repo-summary: re-implemented summary view as pyramid.
- changed exception handler, to now work in pure pyramid mode - changed missing requirements logic on repo based views that require vcs-connection
This commit is contained in:
parent
3d2de9920e
commit
53b4ac98f8
51 changed files with 415 additions and 410 deletions
|
|
@ -105,9 +105,14 @@ class BaseAppView(object):
|
|||
raise HTTPFound(
|
||||
self.request.route_path('my_account_password'))
|
||||
|
||||
def _get_local_tmpl_context(self):
|
||||
def _get_local_tmpl_context(self, include_app_defaults=False):
|
||||
c = TemplateArgs()
|
||||
c.auth_user = self.request.user
|
||||
if include_app_defaults:
|
||||
# NOTE(marcink): after full pyramid migration include_app_defaults
|
||||
# should be turned on by default
|
||||
from rhodecode.lib.base import attach_context_attributes
|
||||
attach_context_attributes(c, self.request, self.request.user.user_id)
|
||||
return c
|
||||
|
||||
def _register_global_c(self, tmpl_args):
|
||||
|
|
@ -154,8 +159,10 @@ class RepoAppView(BaseAppView):
|
|||
'Requirements are missing for repository %s: %s',
|
||||
self.db_repo_name, error.message)
|
||||
|
||||
def _get_local_tmpl_context(self):
|
||||
c = super(RepoAppView, self)._get_local_tmpl_context()
|
||||
def _get_local_tmpl_context(self, include_app_defaults=False):
|
||||
c = super(RepoAppView, self)._get_local_tmpl_context(
|
||||
include_app_defaults=include_app_defaults)
|
||||
|
||||
# register common vars for this type of view
|
||||
c.rhodecode_db_repo = self.db_repo
|
||||
c.repo_name = self.db_repo_name
|
||||
|
|
@ -309,7 +316,7 @@ class RepoTypeRoutePredicate(object):
|
|||
# _('Action not supported for %s.' % rhodecode_repo.alias)),
|
||||
# category='warning')
|
||||
# return redirect(
|
||||
# url('summary_home', repo_name=cls.rhodecode_db_repo.repo_name))
|
||||
# route_path('repo_summary', repo_name=cls.rhodecode_db_repo.repo_name))
|
||||
|
||||
return False
|
||||
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ class HomeView(BaseAppView):
|
|||
'text': obj['name'],
|
||||
'type': 'repo',
|
||||
'obj': obj['dbrepo'],
|
||||
'url': h.url('summary_home', repo_name=obj['name'])
|
||||
'url': h.route_path('repo_summary', repo_name=obj['name'])
|
||||
}
|
||||
for obj in repo_iter]
|
||||
|
||||
|
|
|
|||
|
|
@ -17,18 +17,33 @@
|
|||
# This program is dual-licensed. If you wish to learn more about the
|
||||
# RhodeCode Enterprise Edition, including its added features, Support services,
|
||||
# and proprietary license terms, please see https://rhodecode.com/licenses/
|
||||
from rhodecode.apps._base import add_route_with_slash
|
||||
|
||||
|
||||
def includeme(config):
|
||||
|
||||
# Summary
|
||||
config.add_route(
|
||||
name='repo_summary',
|
||||
pattern='/{repo_name:.*?[^/]}', repo_route=True)
|
||||
|
||||
# NOTE(marcink): one additional route is defined in very bottom, catch
|
||||
# all pattern
|
||||
config.add_route(
|
||||
name='repo_summary_explicit',
|
||||
pattern='/{repo_name:.*?[^/]}/summary', repo_route=True)
|
||||
config.add_route(
|
||||
name='repo_summary_commits',
|
||||
pattern='/{repo_name:.*?[^/]}/summary-commits', repo_route=True)
|
||||
|
||||
# refs data
|
||||
config.add_route(
|
||||
name='repo_refs_data',
|
||||
pattern='/{repo_name:.*?[^/]}/refs-data', repo_route=True)
|
||||
|
||||
config.add_route(
|
||||
name='repo_refs_changelog_data',
|
||||
pattern='/{repo_name:.*?[^/]}/refs-data-changelog', repo_route=True)
|
||||
|
||||
config.add_route(
|
||||
name='repo_stats',
|
||||
pattern='/{repo_name:.*?[^/]}/repo_stats/{commit_id}', repo_route=True)
|
||||
|
||||
# Tags
|
||||
config.add_route(
|
||||
|
|
@ -40,7 +55,6 @@ def includeme(config):
|
|||
name='branches_home',
|
||||
pattern='/{repo_name:.*?[^/]}/branches', repo_route=True)
|
||||
|
||||
# Bookmarks
|
||||
config.add_route(
|
||||
name='bookmarks_home',
|
||||
pattern='/{repo_name:.*?[^/]}/bookmarks', repo_route=True)
|
||||
|
|
@ -125,9 +139,10 @@ def includeme(config):
|
|||
pattern='/{repo_name:.*?[^/]}/settings/strip_execute', repo_route=True)
|
||||
|
||||
# NOTE(marcink): needs to be at the end for catch-all
|
||||
# config.add_route(
|
||||
# name='repo_summary',
|
||||
# pattern='/{repo_name:.*?[^/]}', repo_route=True)
|
||||
add_route_with_slash(
|
||||
config,
|
||||
name='repo_summary',
|
||||
pattern='/{repo_name:.*?[^/]}', repo_route=True)
|
||||
|
||||
# Scan module for configuration decorators.
|
||||
config.scan()
|
||||
|
|
|
|||
|
|
@ -23,16 +23,16 @@ import re
|
|||
import mock
|
||||
import pytest
|
||||
|
||||
from rhodecode.controllers import summary
|
||||
from rhodecode.apps.repository.views.repo_summary import RepoSummaryView
|
||||
from rhodecode.lib import helpers as h
|
||||
from rhodecode.lib.compat import OrderedDict
|
||||
from rhodecode.lib.utils2 import AttributeDict
|
||||
from rhodecode.lib.vcs.exceptions import RepositoryRequirementError
|
||||
from rhodecode.model.db import Repository
|
||||
from rhodecode.model.meta import Session
|
||||
from rhodecode.model.repo import RepoModel
|
||||
from rhodecode.model.scm import ScmModel
|
||||
from rhodecode.tests import (
|
||||
TestController, url, HG_REPO, assert_session_flash)
|
||||
from rhodecode.tests import assert_session_flash
|
||||
from rhodecode.tests.fixture import Fixture
|
||||
from rhodecode.tests.utils import AssertResponse, repo_on_filesystem
|
||||
|
||||
|
|
@ -40,14 +40,31 @@ from rhodecode.tests.utils import AssertResponse, repo_on_filesystem
|
|||
fixture = Fixture()
|
||||
|
||||
|
||||
class TestSummaryController(TestController):
|
||||
def test_index(self, backend, http_host_only_stub):
|
||||
self.log_user()
|
||||
def route_path(name, params=None, **kwargs):
|
||||
import urllib
|
||||
|
||||
base_url = {
|
||||
'repo_summary': '/{repo_name}',
|
||||
'repo_stats': '/{repo_name}/repo_stats/{commit_id}',
|
||||
'repo_refs_data': '/{repo_name}/refs-data',
|
||||
'repo_refs_changelog_data': '/{repo_name}/refs-data-changelog'
|
||||
|
||||
}[name].format(**kwargs)
|
||||
|
||||
if params:
|
||||
base_url = '{}?{}'.format(base_url, urllib.urlencode(params))
|
||||
return base_url
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('app')
|
||||
class TestSummaryView(object):
|
||||
def test_index(self, autologin_user, backend, http_host_only_stub):
|
||||
repo_id = backend.repo.repo_id
|
||||
repo_name = backend.repo_name
|
||||
with mock.patch('rhodecode.lib.helpers.is_svn_without_proxy',
|
||||
return_value=False):
|
||||
response = self.app.get(url('summary_home', repo_name=repo_name))
|
||||
response = self.app.get(
|
||||
route_path('repo_summary', repo_name=repo_name))
|
||||
|
||||
# repo type
|
||||
response.mustcontain(
|
||||
|
|
@ -66,11 +83,11 @@ class TestSummaryController(TestController):
|
|||
'id="clone_url_id" readonly="readonly"'
|
||||
' value="http://test_admin@%s/_%s"' % (http_host_only_stub, repo_id, ))
|
||||
|
||||
def test_index_svn_without_proxy(self, backend_svn, http_host_only_stub):
|
||||
self.log_user()
|
||||
def test_index_svn_without_proxy(
|
||||
self, autologin_user, backend_svn, http_host_only_stub):
|
||||
repo_id = backend_svn.repo.repo_id
|
||||
repo_name = backend_svn.repo_name
|
||||
response = self.app.get(url('summary_home', repo_name=repo_name))
|
||||
response = self.app.get(route_path('repo_summary', repo_name=repo_name))
|
||||
# clone url...
|
||||
response.mustcontain(
|
||||
'id="clone_url" disabled'
|
||||
|
|
@ -79,14 +96,15 @@ class TestSummaryController(TestController):
|
|||
'id="clone_url_id" disabled'
|
||||
' value="http://test_admin@%s/_%s"' % (http_host_only_stub, repo_id, ))
|
||||
|
||||
def test_index_with_trailing_slash(self, autologin_user, backend,
|
||||
http_host_only_stub):
|
||||
def test_index_with_trailing_slash(
|
||||
self, autologin_user, backend, http_host_only_stub):
|
||||
|
||||
repo_id = backend.repo.repo_id
|
||||
repo_name = backend.repo_name
|
||||
with mock.patch('rhodecode.lib.helpers.is_svn_without_proxy',
|
||||
return_value=False):
|
||||
response = self.app.get(
|
||||
url('summary_home', repo_name=repo_name) + '/',
|
||||
route_path('repo_summary', repo_name=repo_name) + '/',
|
||||
status=200)
|
||||
|
||||
# clone url...
|
||||
|
|
@ -97,11 +115,10 @@ class TestSummaryController(TestController):
|
|||
'id="clone_url_id" readonly="readonly"'
|
||||
' value="http://test_admin@%s/_%s"' % (http_host_only_stub, repo_id, ))
|
||||
|
||||
def test_index_by_id(self, backend):
|
||||
self.log_user()
|
||||
def test_index_by_id(self, autologin_user, backend):
|
||||
repo_id = backend.repo.repo_id
|
||||
response = self.app.get(url(
|
||||
'summary_home', repo_name='_%s' % (repo_id,)))
|
||||
response = self.app.get(
|
||||
route_path('repo_summary', repo_name='_%s' % (repo_id,)))
|
||||
|
||||
# repo type
|
||||
response.mustcontain(
|
||||
|
|
@ -112,10 +129,9 @@ class TestSummaryController(TestController):
|
|||
"""<i class="icon-unlock-alt">"""
|
||||
)
|
||||
|
||||
def test_index_by_repo_having_id_path_in_name_hg(self):
|
||||
self.log_user()
|
||||
def test_index_by_repo_having_id_path_in_name_hg(self, autologin_user):
|
||||
fixture.create_repo(name='repo_1')
|
||||
response = self.app.get(url('summary_home', repo_name='repo_1'))
|
||||
response = self.app.get(route_path('repo_summary', repo_name='repo_1'))
|
||||
|
||||
try:
|
||||
response.mustcontain("repo_1")
|
||||
|
|
@ -123,11 +139,11 @@ class TestSummaryController(TestController):
|
|||
RepoModel().delete(Repository.get_by_repo_name('repo_1'))
|
||||
Session().commit()
|
||||
|
||||
def test_index_with_anonymous_access_disabled(self):
|
||||
with fixture.anon_access(False):
|
||||
response = self.app.get(url('summary_home', repo_name=HG_REPO),
|
||||
status=302)
|
||||
assert 'login' in response.location
|
||||
def test_index_with_anonymous_access_disabled(
|
||||
self, backend, disable_anonymous_user):
|
||||
response = self.app.get(
|
||||
route_path('repo_summary', repo_name=backend.repo_name), status=302)
|
||||
assert 'login' in response.location
|
||||
|
||||
def _enable_stats(self, repo):
|
||||
r = Repository.get_by_repo_name(repo)
|
||||
|
|
@ -174,17 +190,15 @@ class TestSummaryController(TestController):
|
|||
},
|
||||
}
|
||||
|
||||
def test_repo_stats(self, backend, xhr_header):
|
||||
self.log_user()
|
||||
def test_repo_stats(self, autologin_user, backend, xhr_header):
|
||||
response = self.app.get(
|
||||
url('repo_stats',
|
||||
repo_name=backend.repo_name, commit_id='tip'),
|
||||
route_path(
|
||||
'repo_stats', repo_name=backend.repo_name, commit_id='tip'),
|
||||
extra_environ=xhr_header,
|
||||
status=200)
|
||||
assert re.match(r'6[\d\.]+ KiB', response.json['size'])
|
||||
|
||||
def test_repo_stats_code_stats_enabled(self, backend, xhr_header):
|
||||
self.log_user()
|
||||
def test_repo_stats_code_stats_enabled(self, autologin_user, backend, xhr_header):
|
||||
repo_name = backend.repo_name
|
||||
|
||||
# codes stats
|
||||
|
|
@ -192,8 +206,8 @@ class TestSummaryController(TestController):
|
|||
ScmModel().mark_for_invalidation(repo_name)
|
||||
|
||||
response = self.app.get(
|
||||
url('repo_stats',
|
||||
repo_name=backend.repo_name, commit_id='tip'),
|
||||
route_path(
|
||||
'repo_stats', repo_name=backend.repo_name, commit_id='tip'),
|
||||
extra_environ=xhr_header,
|
||||
status=200)
|
||||
|
||||
|
|
@ -204,7 +218,7 @@ class TestSummaryController(TestController):
|
|||
|
||||
def test_repo_refs_data(self, backend):
|
||||
response = self.app.get(
|
||||
url('repo_refs_data', repo_name=backend.repo_name),
|
||||
route_path('repo_refs_data', repo_name=backend.repo_name),
|
||||
status=200)
|
||||
|
||||
# Ensure that there is the correct amount of items in the result
|
||||
|
|
@ -221,72 +235,68 @@ class TestSummaryController(TestController):
|
|||
Repository, 'scm_instance', side_effect=RepositoryRequirementError)
|
||||
|
||||
with scm_patcher:
|
||||
response = self.app.get(url('summary_home', repo_name=repo_name))
|
||||
response = self.app.get(route_path('repo_summary', repo_name=repo_name))
|
||||
assert_response = AssertResponse(response)
|
||||
assert_response.element_contains(
|
||||
'.main .alert-warning strong', 'Missing requirements')
|
||||
assert_response.element_contains(
|
||||
'.main .alert-warning',
|
||||
'These commits cannot be displayed, because this repository'
|
||||
' uses the Mercurial largefiles extension, which was not enabled.')
|
||||
'Commits cannot be displayed, because this repository '
|
||||
'uses one or more extensions, which was not enabled.')
|
||||
|
||||
def test_missing_requirements_page_does_not_contains_switch_to(
|
||||
self, backend):
|
||||
self.log_user()
|
||||
self, autologin_user, backend):
|
||||
repo_name = backend.repo_name
|
||||
scm_patcher = mock.patch.object(
|
||||
Repository, 'scm_instance', side_effect=RepositoryRequirementError)
|
||||
|
||||
with scm_patcher:
|
||||
response = self.app.get(url('summary_home', repo_name=repo_name))
|
||||
response = self.app.get(route_path('repo_summary', repo_name=repo_name))
|
||||
response.mustcontain(no='Switch To')
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('pylonsapp')
|
||||
class TestSwitcherReferenceData:
|
||||
@pytest.mark.usefixtures('app')
|
||||
class TestRepoLocation(object):
|
||||
|
||||
def test_creates_reference_urls_based_on_name(self):
|
||||
references = {
|
||||
'name': 'commit_id',
|
||||
}
|
||||
controller = summary.SummaryController()
|
||||
is_svn = False
|
||||
result = controller._switcher_reference_data(
|
||||
'repo_name', references, is_svn)
|
||||
expected_url = h.url(
|
||||
'files_home', repo_name='repo_name', revision='name',
|
||||
at='name')
|
||||
assert result[0]['files_url'] == expected_url
|
||||
@pytest.mark.parametrize("suffix", [u'', u'ąęł'], ids=['', 'non-ascii'])
|
||||
def test_manual_delete(self, autologin_user, backend, suffix, csrf_token):
|
||||
repo = backend.create_repo(name_suffix=suffix)
|
||||
repo_name = repo.repo_name
|
||||
|
||||
def test_urls_contain_commit_id_if_slash_in_name(self):
|
||||
references = {
|
||||
'name/with/slash': 'commit_id',
|
||||
}
|
||||
controller = summary.SummaryController()
|
||||
is_svn = False
|
||||
result = controller._switcher_reference_data(
|
||||
'repo_name', references, is_svn)
|
||||
expected_url = h.url(
|
||||
'files_home', repo_name='repo_name', revision='commit_id',
|
||||
at='name/with/slash')
|
||||
assert result[0]['files_url'] == expected_url
|
||||
# delete from file system
|
||||
RepoModel()._delete_filesystem_repo(repo)
|
||||
|
||||
def test_adds_reference_to_path_for_svn(self):
|
||||
references = {
|
||||
'name/with/slash': 'commit_id',
|
||||
}
|
||||
controller = summary.SummaryController()
|
||||
is_svn = True
|
||||
result = controller._switcher_reference_data(
|
||||
'repo_name', references, is_svn)
|
||||
expected_url = h.url(
|
||||
'files_home', repo_name='repo_name', f_path='name/with/slash',
|
||||
revision='commit_id', at='name/with/slash')
|
||||
assert result[0]['files_url'] == expected_url
|
||||
# test if the repo is still in the database
|
||||
new_repo = RepoModel().get_by_repo_name(repo_name)
|
||||
assert new_repo.repo_name == repo_name
|
||||
|
||||
# check if repo is not in the filesystem
|
||||
assert not repo_on_filesystem(repo_name)
|
||||
self.assert_repo_not_found_redirect(repo_name)
|
||||
|
||||
def assert_repo_not_found_redirect(self, repo_name):
|
||||
# run the check page that triggers the other flash message
|
||||
response = self.app.get(h.url('repo_check_home', repo_name=repo_name))
|
||||
assert_session_flash(
|
||||
response, 'The repository at %s cannot be located.' % repo_name)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('pylonsapp')
|
||||
class TestCreateReferenceData:
|
||||
@pytest.fixture()
|
||||
def summary_view(context_stub, request_stub, user_util):
|
||||
"""
|
||||
Bootstrap view to test the view functions
|
||||
"""
|
||||
request_stub.matched_route = AttributeDict(name='test_view')
|
||||
|
||||
request_stub.user = user_util.create_user().AuthUser
|
||||
request_stub.db_repo = user_util.create_repo()
|
||||
|
||||
view = RepoSummaryView(context=context_stub, request=request_stub)
|
||||
return view
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('app')
|
||||
class TestCreateReferenceData(object):
|
||||
|
||||
@pytest.fixture
|
||||
def example_refs(self):
|
||||
|
|
@ -297,14 +307,13 @@ class TestCreateReferenceData:
|
|||
]
|
||||
return example_refs
|
||||
|
||||
def test_generates_refs_based_on_commit_ids(self, example_refs):
|
||||
def test_generates_refs_based_on_commit_ids(self, example_refs, summary_view):
|
||||
repo = mock.Mock()
|
||||
repo.name = 'test-repo'
|
||||
repo.alias = 'git'
|
||||
full_repo_name = 'pytest-repo-group/' + repo.name
|
||||
controller = summary.SummaryController()
|
||||
|
||||
result = controller._create_reference_data(
|
||||
result = summary_view._create_reference_data(
|
||||
repo, full_repo_name, example_refs)
|
||||
|
||||
expected_files_url = '/{}/files/'.format(full_repo_name)
|
||||
|
|
@ -333,13 +342,13 @@ class TestCreateReferenceData:
|
|||
}]
|
||||
assert result == expected_result
|
||||
|
||||
def test_generates_refs_with_path_for_svn(self, example_refs):
|
||||
def test_generates_refs_with_path_for_svn(self, example_refs, summary_view):
|
||||
repo = mock.Mock()
|
||||
repo.name = 'test-repo'
|
||||
repo.alias = 'svn'
|
||||
full_repo_name = 'pytest-repo-group/' + repo.name
|
||||
controller = summary.SummaryController()
|
||||
result = controller._create_reference_data(
|
||||
|
||||
result = summary_view._create_reference_data(
|
||||
repo, full_repo_name, example_refs)
|
||||
|
||||
expected_files_url = '/{}/files/'.format(full_repo_name)
|
||||
|
|
@ -373,35 +382,9 @@ class TestCreateReferenceData:
|
|||
assert result == expected_result
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("app")
|
||||
class TestRepoLocation:
|
||||
|
||||
@pytest.mark.parametrize("suffix", [u'', u'ąęł'], ids=['', 'non-ascii'])
|
||||
def test_manual_delete(self, autologin_user, backend, suffix, csrf_token):
|
||||
repo = backend.create_repo(name_suffix=suffix)
|
||||
repo_name = repo.repo_name
|
||||
|
||||
# delete from file system
|
||||
RepoModel()._delete_filesystem_repo(repo)
|
||||
|
||||
# test if the repo is still in the database
|
||||
new_repo = RepoModel().get_by_repo_name(repo_name)
|
||||
assert new_repo.repo_name == repo_name
|
||||
|
||||
# check if repo is not in the filesystem
|
||||
assert not repo_on_filesystem(repo_name)
|
||||
self.assert_repo_not_found_redirect(repo_name)
|
||||
|
||||
def assert_repo_not_found_redirect(self, repo_name):
|
||||
# run the check page that triggers the other flash message
|
||||
response = self.app.get(url('repo_check_home', repo_name=repo_name))
|
||||
assert_session_flash(
|
||||
response, 'The repository at %s cannot be located.' % repo_name)
|
||||
|
||||
|
||||
class TestCreateFilesUrl(object):
|
||||
def test_creates_non_svn_url(self):
|
||||
controller = summary.SummaryController()
|
||||
|
||||
def test_creates_non_svn_url(self, summary_view):
|
||||
repo = mock.Mock()
|
||||
repo.name = 'abcde'
|
||||
full_repo_name = 'test-repo-group/' + repo.name
|
||||
|
|
@ -409,16 +392,15 @@ class TestCreateFilesUrl(object):
|
|||
raw_id = 'deadbeef0123456789'
|
||||
is_svn = False
|
||||
|
||||
with mock.patch.object(summary.h, 'url') as url_mock:
|
||||
result = controller._create_files_url(
|
||||
with mock.patch('rhodecode.lib.helpers.url') as url_mock:
|
||||
result = summary_view._create_files_url(
|
||||
repo, full_repo_name, ref_name, raw_id, is_svn)
|
||||
url_mock.assert_called_once_with(
|
||||
'files_home', repo_name=full_repo_name, f_path='',
|
||||
revision=ref_name, at=ref_name)
|
||||
assert result == url_mock.return_value
|
||||
|
||||
def test_creates_svn_url(self):
|
||||
controller = summary.SummaryController()
|
||||
def test_creates_svn_url(self, summary_view):
|
||||
repo = mock.Mock()
|
||||
repo.name = 'abcde'
|
||||
full_repo_name = 'test-repo-group/' + repo.name
|
||||
|
|
@ -426,16 +408,15 @@ class TestCreateFilesUrl(object):
|
|||
raw_id = 'deadbeef0123456789'
|
||||
is_svn = True
|
||||
|
||||
with mock.patch.object(summary.h, 'url') as url_mock:
|
||||
result = controller._create_files_url(
|
||||
with mock.patch('rhodecode.lib.helpers.url') as url_mock:
|
||||
result = summary_view._create_files_url(
|
||||
repo, full_repo_name, ref_name, raw_id, is_svn)
|
||||
url_mock.assert_called_once_with(
|
||||
'files_home', repo_name=full_repo_name, f_path=ref_name,
|
||||
revision=raw_id, at=ref_name)
|
||||
assert result == url_mock.return_value
|
||||
|
||||
def test_name_has_slashes(self):
|
||||
controller = summary.SummaryController()
|
||||
def test_name_has_slashes(self, summary_view):
|
||||
repo = mock.Mock()
|
||||
repo.name = 'abcde'
|
||||
full_repo_name = 'test-repo-group/' + repo.name
|
||||
|
|
@ -443,8 +424,8 @@ class TestCreateFilesUrl(object):
|
|||
raw_id = 'deadbeef0123456789'
|
||||
is_svn = False
|
||||
|
||||
with mock.patch.object(summary.h, 'url') as url_mock:
|
||||
result = controller._create_files_url(
|
||||
with mock.patch('rhodecode.lib.helpers.url') as url_mock:
|
||||
result = summary_view._create_files_url(
|
||||
repo, full_repo_name, ref_name, raw_id, is_svn)
|
||||
url_mock.assert_called_once_with(
|
||||
'files_home', repo_name=full_repo_name, f_path='', revision=raw_id,
|
||||
|
|
@ -463,42 +444,39 @@ class TestReferenceItems(object):
|
|||
def _format_function(name, id_):
|
||||
return 'format_function_{}_{}'.format(name, id_)
|
||||
|
||||
def test_creates_required_amount_of_items(self):
|
||||
def test_creates_required_amount_of_items(self, summary_view):
|
||||
amount = 100
|
||||
refs = {
|
||||
'ref{}'.format(i): '{0:040d}'.format(i)
|
||||
for i in range(amount)
|
||||
}
|
||||
|
||||
controller = summary.SummaryController()
|
||||
|
||||
url_patcher = mock.patch.object(
|
||||
controller, '_create_files_url')
|
||||
svn_patcher = mock.patch.object(
|
||||
summary.h, 'is_svn', return_value=False)
|
||||
url_patcher = mock.patch.object(summary_view, '_create_files_url')
|
||||
svn_patcher = mock.patch('rhodecode.lib.helpers.is_svn',
|
||||
return_value=False)
|
||||
|
||||
with url_patcher as url_mock, svn_patcher:
|
||||
result = controller._create_reference_items(
|
||||
result = summary_view._create_reference_items(
|
||||
self.repo, self.repo_full_name, refs, self.ref_type,
|
||||
self._format_function)
|
||||
assert len(result) == amount
|
||||
assert url_mock.call_count == amount
|
||||
|
||||
def test_single_item_details(self):
|
||||
def test_single_item_details(self, summary_view):
|
||||
ref_name = 'ref1'
|
||||
ref_id = 'deadbeef'
|
||||
refs = {
|
||||
ref_name: ref_id
|
||||
}
|
||||
|
||||
controller = summary.SummaryController()
|
||||
svn_patcher = mock.patch('rhodecode.lib.helpers.is_svn',
|
||||
return_value=False)
|
||||
|
||||
url_patcher = mock.patch.object(
|
||||
controller, '_create_files_url', return_value=self.fake_url)
|
||||
svn_patcher = mock.patch.object(
|
||||
summary.h, 'is_svn', return_value=False)
|
||||
summary_view, '_create_files_url', return_value=self.fake_url)
|
||||
|
||||
with url_patcher as url_mock, svn_patcher:
|
||||
result = controller._create_reference_items(
|
||||
result = summary_view._create_reference_items(
|
||||
self.repo, self.repo_full_name, refs, self.ref_type,
|
||||
self._format_function)
|
||||
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (C) 2010-2017 RhodeCode GmbH
|
||||
# Copyright (C) 2011-2017 RhodeCode GmbH
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License, version 3
|
||||
|
|
@ -18,46 +18,51 @@
|
|||
# RhodeCode Enterprise Edition, including its added features, Support services,
|
||||
# and proprietary license terms, please see https://rhodecode.com/licenses/
|
||||
|
||||
"""
|
||||
Summary controller for RhodeCode Enterprise
|
||||
"""
|
||||
|
||||
import logging
|
||||
from string import lower
|
||||
import string
|
||||
|
||||
from pyramid.view import view_config
|
||||
|
||||
from pylons import tmpl_context as c, request
|
||||
from pylons.i18n.translation import _
|
||||
from beaker.cache import cache_region
|
||||
|
||||
from rhodecode.config.conf import (LANGUAGES_EXTENSIONS_MAP)
|
||||
|
||||
from rhodecode.controllers import utils
|
||||
from rhodecode.controllers.changelog import _load_changelog_summary
|
||||
|
||||
from rhodecode.apps._base import RepoAppView
|
||||
from rhodecode.config.conf import (LANGUAGES_EXTENSIONS_MAP)
|
||||
from rhodecode.lib import caches, helpers as h
|
||||
from rhodecode.lib.utils import jsonify
|
||||
from rhodecode.lib.utils2 import safe_str
|
||||
from rhodecode.lib.auth import (
|
||||
LoginRequired, HasRepoPermissionAnyDecorator, XHRRequired)
|
||||
from rhodecode.lib.base import BaseRepoController, render
|
||||
from rhodecode.lib.helpers import RepoPage
|
||||
from rhodecode.lib.utils2 import safe_str, safe_int
|
||||
from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
|
||||
from rhodecode.lib.markup_renderer import MarkupRenderer, relative_links
|
||||
from rhodecode.lib.ext_json import json
|
||||
from rhodecode.lib.vcs.backends.base import EmptyCommit
|
||||
from rhodecode.lib.vcs.exceptions import CommitError, EmptyRepositoryError
|
||||
from rhodecode.model.db import Statistics, CacheKey, User
|
||||
from rhodecode.model.meta import Session
|
||||
from rhodecode.model.repo import ReadmeFinder
|
||||
|
||||
from rhodecode.model.scm import ScmModel
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SummaryController(BaseRepoController):
|
||||
class RepoSummaryView(RepoAppView):
|
||||
|
||||
def __before__(self):
|
||||
super(SummaryController, self).__before__()
|
||||
def load_default_context(self):
|
||||
c = self._get_local_tmpl_context(include_app_defaults=True)
|
||||
|
||||
def __get_readme_data(self, db_repo):
|
||||
# TODO(marcink): remove repo_info and use c.rhodecode_db_repo instead
|
||||
c.repo_info = self.db_repo
|
||||
c.rhodecode_repo = None
|
||||
if not c.repository_requirements_missing:
|
||||
c.rhodecode_repo = self.rhodecode_vcs_repo
|
||||
|
||||
self._register_global_c(c)
|
||||
return c
|
||||
|
||||
def _get_readme_data(self, db_repo, default_renderer):
|
||||
repo_name = db_repo.repo_name
|
||||
log.debug('Looking for README file')
|
||||
default_renderer = c.visual.default_renderer
|
||||
|
||||
@cache_region('long_term')
|
||||
def _generate_readme(cache_key):
|
||||
|
|
@ -113,16 +118,58 @@ class SummaryController(BaseRepoController):
|
|||
log.exception(
|
||||
"Exception while trying to render the README")
|
||||
|
||||
def _load_commits_context(self, c):
|
||||
p = safe_int(self.request.GET.get('page'), 1)
|
||||
size = safe_int(self.request.GET.get('size'), 10)
|
||||
|
||||
def url_generator(**kw):
|
||||
query_params = {
|
||||
'size': size
|
||||
}
|
||||
query_params.update(kw)
|
||||
return h.route_path(
|
||||
'repo_summary_commits',
|
||||
repo_name=c.rhodecode_db_repo.repo_name, _query=query_params)
|
||||
|
||||
pre_load = ['author', 'branch', 'date', 'message']
|
||||
try:
|
||||
collection = self.rhodecode_vcs_repo.get_commits(pre_load=pre_load)
|
||||
except EmptyRepositoryError:
|
||||
collection = self.rhodecode_vcs_repo
|
||||
|
||||
c.repo_commits = RepoPage(
|
||||
collection, page=p, items_per_page=size, url=url_generator)
|
||||
page_ids = [x.raw_id for x in c.repo_commits]
|
||||
c.comments = self.db_repo.get_comments(page_ids)
|
||||
c.statuses = self.db_repo.statuses(page_ids)
|
||||
|
||||
@LoginRequired()
|
||||
@HasRepoPermissionAnyDecorator(
|
||||
'repository.read', 'repository.write', 'repository.admin')
|
||||
def index(self, repo_name):
|
||||
@view_config(
|
||||
route_name='repo_summary_commits', request_method='GET',
|
||||
renderer='rhodecode:templates/summary/summary_commits.mako')
|
||||
def summary_commits(self):
|
||||
c = self.load_default_context()
|
||||
self._load_commits_context(c)
|
||||
return self._get_template_context(c)
|
||||
|
||||
@LoginRequired()
|
||||
@HasRepoPermissionAnyDecorator(
|
||||
'repository.read', 'repository.write', 'repository.admin')
|
||||
@view_config(
|
||||
route_name='repo_summary', request_method='GET',
|
||||
renderer='rhodecode:templates/summary/summary.mako')
|
||||
@view_config(
|
||||
route_name='repo_summary_slash', request_method='GET',
|
||||
renderer='rhodecode:templates/summary/summary.mako')
|
||||
def summary(self):
|
||||
c = self.load_default_context()
|
||||
|
||||
# Prepare the clone URL
|
||||
|
||||
username = ''
|
||||
if c.rhodecode_user.username != User.DEFAULT_USER:
|
||||
username = safe_str(c.rhodecode_user.username)
|
||||
if self._rhodecode_user.username != User.DEFAULT_USER:
|
||||
username = safe_str(self._rhodecode_user.username)
|
||||
|
||||
_def_clone_uri = _def_clone_uri_by_id = c.clone_uri_tmpl
|
||||
if '{repo}' in _def_clone_uri:
|
||||
|
|
@ -132,23 +179,23 @@ class SummaryController(BaseRepoController):
|
|||
_def_clone_uri_by_id = _def_clone_uri.replace(
|
||||
'_{repoid}', '{repo}')
|
||||
|
||||
c.clone_repo_url = c.rhodecode_db_repo.clone_url(
|
||||
c.clone_repo_url = self.db_repo.clone_url(
|
||||
user=username, uri_tmpl=_def_clone_uri)
|
||||
c.clone_repo_url_id = c.rhodecode_db_repo.clone_url(
|
||||
c.clone_repo_url_id = self.db_repo.clone_url(
|
||||
user=username, uri_tmpl=_def_clone_uri_by_id)
|
||||
|
||||
# If enabled, get statistics data
|
||||
|
||||
c.show_stats = bool(c.rhodecode_db_repo.enable_statistics)
|
||||
c.show_stats = bool(self.db_repo.enable_statistics)
|
||||
|
||||
stats = self.sa.query(Statistics)\
|
||||
.filter(Statistics.repository == c.rhodecode_db_repo)\
|
||||
stats = Session().query(Statistics) \
|
||||
.filter(Statistics.repository == self.db_repo) \
|
||||
.scalar()
|
||||
|
||||
c.stats_percentage = 0
|
||||
|
||||
if stats and stats.languages:
|
||||
c.no_data = False is c.rhodecode_db_repo.enable_statistics
|
||||
c.no_data = False is self.db_repo.enable_statistics
|
||||
lang_stats_d = json.loads(stats.languages)
|
||||
|
||||
# Sort first by decreasing count and second by the file extension,
|
||||
|
|
@ -164,51 +211,59 @@ class SummaryController(BaseRepoController):
|
|||
c.no_data = True
|
||||
c.trending_languages = json.dumps({})
|
||||
|
||||
c.enable_downloads = c.rhodecode_db_repo.enable_downloads
|
||||
c.repository_followers = self.scm_model.get_followers(
|
||||
c.rhodecode_db_repo)
|
||||
c.repository_forks = self.scm_model.get_forks(c.rhodecode_db_repo)
|
||||
c.repository_is_user_following = self.scm_model.is_following_repo(
|
||||
c.repo_name, c.rhodecode_user.user_id)
|
||||
scm_model = ScmModel()
|
||||
c.enable_downloads = self.db_repo.enable_downloads
|
||||
c.repository_followers = scm_model.get_followers(self.db_repo)
|
||||
c.repository_forks = scm_model.get_forks(self.db_repo)
|
||||
c.repository_is_user_following = scm_model.is_following_repo(
|
||||
self.db_repo_name, self._rhodecode_user.user_id)
|
||||
|
||||
# first interaction with the VCS instance after here...
|
||||
if c.repository_requirements_missing:
|
||||
return render('summary/missing_requirements.mako')
|
||||
self.request.override_renderer = \
|
||||
'rhodecode:templates/summary/missing_requirements.mako'
|
||||
return self._get_template_context(c)
|
||||
|
||||
c.readme_data, c.readme_file = \
|
||||
self.__get_readme_data(c.rhodecode_db_repo)
|
||||
self._get_readme_data(self.db_repo, c.visual.default_renderer)
|
||||
|
||||
_load_changelog_summary()
|
||||
# loads the summary commits template context
|
||||
self._load_commits_context(c)
|
||||
|
||||
if request.is_xhr:
|
||||
return render('changelog/changelog_summary_data.mako')
|
||||
return self._get_template_context(c)
|
||||
|
||||
return render('summary/summary.mako')
|
||||
def get_request_commit_id(self):
|
||||
return self.request.matchdict['commit_id']
|
||||
|
||||
@LoginRequired()
|
||||
@XHRRequired()
|
||||
@HasRepoPermissionAnyDecorator(
|
||||
'repository.read', 'repository.write', 'repository.admin')
|
||||
@jsonify
|
||||
def repo_stats(self, repo_name, commit_id):
|
||||
@view_config(
|
||||
route_name='repo_stats', request_method='GET',
|
||||
renderer='json_ext')
|
||||
def repo_stats(self):
|
||||
commit_id = self.get_request_commit_id()
|
||||
|
||||
_namespace = caches.get_repo_namespace_key(
|
||||
caches.SUMMARY_STATS, repo_name)
|
||||
show_stats = bool(c.rhodecode_db_repo.enable_statistics)
|
||||
cache_manager = caches.get_cache_manager('repo_cache_long', _namespace)
|
||||
caches.SUMMARY_STATS, self.db_repo_name)
|
||||
show_stats = bool(self.db_repo.enable_statistics)
|
||||
cache_manager = caches.get_cache_manager(
|
||||
'repo_cache_long', _namespace)
|
||||
_cache_key = caches.compute_key_from_params(
|
||||
repo_name, commit_id, show_stats)
|
||||
self.db_repo_name, commit_id, show_stats)
|
||||
|
||||
def compute_stats():
|
||||
code_stats = {}
|
||||
size = 0
|
||||
try:
|
||||
scm_instance = c.rhodecode_db_repo.scm_instance()
|
||||
scm_instance = self.db_repo.scm_instance()
|
||||
commit = scm_instance.get_commit(commit_id)
|
||||
|
||||
for node in commit.get_filenodes_generator():
|
||||
size += node.size
|
||||
if not show_stats:
|
||||
continue
|
||||
ext = lower(node.extension)
|
||||
ext = string.lower(node.extension)
|
||||
ext_info = LANGUAGES_EXTENSIONS_MAP.get(ext)
|
||||
if ext_info:
|
||||
if ext in code_stats:
|
||||
|
|
@ -223,44 +278,41 @@ class SummaryController(BaseRepoController):
|
|||
stats = cache_manager.get(_cache_key, createfunc=compute_stats)
|
||||
return stats
|
||||
|
||||
def _switcher_reference_data(self, repo_name, references, is_svn):
|
||||
"""Prepare reference data for given `references`"""
|
||||
items = []
|
||||
for name, commit_id in references.items():
|
||||
use_commit_id = '/' in name or is_svn
|
||||
items.append({
|
||||
'name': name,
|
||||
'commit_id': commit_id,
|
||||
'files_url': h.url(
|
||||
'files_home',
|
||||
repo_name=repo_name,
|
||||
f_path=name if is_svn else '',
|
||||
revision=commit_id if use_commit_id else name,
|
||||
at=name)
|
||||
})
|
||||
return items
|
||||
|
||||
@LoginRequired()
|
||||
@HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
|
||||
'repository.admin')
|
||||
@jsonify
|
||||
def repo_refs_data(self, repo_name):
|
||||
repo = c.rhodecode_repo
|
||||
@HasRepoPermissionAnyDecorator(
|
||||
'repository.read', 'repository.write', 'repository.admin')
|
||||
@view_config(
|
||||
route_name='repo_refs_data', request_method='GET',
|
||||
renderer='json_ext')
|
||||
def repo_refs_data(self):
|
||||
_ = self.request.translate
|
||||
self.load_default_context()
|
||||
|
||||
repo = self.rhodecode_vcs_repo
|
||||
refs_to_create = [
|
||||
(_("Branch"), repo.branches, 'branch'),
|
||||
(_("Tag"), repo.tags, 'tag'),
|
||||
(_("Bookmark"), repo.bookmarks, 'book'),
|
||||
]
|
||||
res = self._create_reference_data(repo, repo_name, refs_to_create)
|
||||
res = self._create_reference_data(
|
||||
repo, self.db_repo_name, refs_to_create)
|
||||
data = {
|
||||
'more': False,
|
||||
'results': res
|
||||
}
|
||||
return data
|
||||
|
||||
@jsonify
|
||||
def repo_refs_changelog_data(self, repo_name):
|
||||
repo = c.rhodecode_repo
|
||||
@LoginRequired()
|
||||
@HasRepoPermissionAnyDecorator(
|
||||
'repository.read', 'repository.write', 'repository.admin')
|
||||
@view_config(
|
||||
route_name='repo_refs_changelog_data', request_method='GET',
|
||||
renderer='json_ext')
|
||||
def repo_refs_changelog_data(self):
|
||||
_ = self.request.translate
|
||||
self.load_default_context()
|
||||
|
||||
repo = self.rhodecode_vcs_repo
|
||||
|
||||
refs_to_create = [
|
||||
(_("Branches"), repo.branches, 'branch'),
|
||||
|
|
@ -268,7 +320,8 @@ class SummaryController(BaseRepoController):
|
|||
# TODO: enable when vcs can handle bookmarks filters
|
||||
# (_("Bookmarks"), repo.bookmarks, "book"),
|
||||
]
|
||||
res = self._create_reference_data(repo, repo_name, refs_to_create)
|
||||
res = self._create_reference_data(
|
||||
repo, self.db_repo_name, refs_to_create)
|
||||
data = {
|
||||
'more': False,
|
||||
'results': res
|
||||
|
|
@ -284,7 +337,8 @@ class SummaryController(BaseRepoController):
|
|||
result.append({
|
||||
'text': title,
|
||||
'children': self._create_reference_items(
|
||||
repo, full_repo_name, refs, ref_type, format_ref_id),
|
||||
repo, full_repo_name, refs, ref_type,
|
||||
format_ref_id),
|
||||
})
|
||||
return result
|
||||
|
||||
|
|
@ -304,8 +358,7 @@ class SummaryController(BaseRepoController):
|
|||
})
|
||||
return result
|
||||
|
||||
def _create_files_url(self, repo, full_repo_name, ref_name, raw_id,
|
||||
is_svn):
|
||||
def _create_files_url(self, repo, full_repo_name, ref_name, raw_id, is_svn):
|
||||
use_commit_id = '/' in ref_name or is_svn
|
||||
return h.url(
|
||||
'files_home',
|
||||
|
|
@ -39,11 +39,15 @@ from routes.middleware import RoutesMiddleware
|
|||
import routes.util
|
||||
|
||||
import rhodecode
|
||||
|
||||
from rhodecode.model import meta
|
||||
from rhodecode.config import patches
|
||||
from rhodecode.config.routing import STATIC_FILE_PREFIX
|
||||
from rhodecode.config.environment import (
|
||||
load_environment, load_pyramid_environment)
|
||||
|
||||
from rhodecode.lib.vcs import VCSCommunicationError
|
||||
from rhodecode.lib.exceptions import VCSServerUnavailable
|
||||
from rhodecode.lib.middleware import csrf
|
||||
from rhodecode.lib.middleware.appenlight import wrap_in_appenlight_if_enabled
|
||||
from rhodecode.lib.middleware.error_handling import (
|
||||
|
|
@ -51,7 +55,7 @@ from rhodecode.lib.middleware.error_handling import (
|
|||
from rhodecode.lib.middleware.https_fixup import HttpsFixup
|
||||
from rhodecode.lib.middleware.vcs import VCSMiddleware
|
||||
from rhodecode.lib.plugins.utils import register_rhodecode_plugin
|
||||
from rhodecode.lib.utils2 import aslist as rhodecode_aslist
|
||||
from rhodecode.lib.utils2 import aslist as rhodecode_aslist, AttributeDict
|
||||
from rhodecode.subscribers import (
|
||||
scan_repositories_if_enabled, write_js_routes_if_enabled,
|
||||
write_metadata_if_needed)
|
||||
|
|
@ -221,7 +225,6 @@ def add_pylons_compat_data(registry, global_config, settings):
|
|||
|
||||
def error_handler(exception, request):
|
||||
import rhodecode
|
||||
from rhodecode.lib.utils2 import AttributeDict
|
||||
from rhodecode.lib import helpers
|
||||
|
||||
rhodecode_title = rhodecode.CONFIG.get('rhodecode_title') or 'RhodeCode'
|
||||
|
|
@ -230,6 +233,8 @@ def error_handler(exception, request):
|
|||
# prefer original exception for the response since it may have headers set
|
||||
if isinstance(exception, HTTPException):
|
||||
base_response = exception
|
||||
elif isinstance(exception, VCSCommunicationError):
|
||||
base_response = VCSServerUnavailable()
|
||||
|
||||
def is_http_error(response):
|
||||
# error which should have traceback
|
||||
|
|
@ -257,6 +262,7 @@ def error_handler(exception, request):
|
|||
if hasattr(base_response, 'causes'):
|
||||
c.causes = base_response.causes
|
||||
c.messages = helpers.flash.pop_messages()
|
||||
|
||||
response = render_to_response(
|
||||
'/errors/error_document.mako', {'c': c, 'h': helpers}, request=request,
|
||||
response=base_response)
|
||||
|
|
@ -404,7 +410,6 @@ def wrap_app_in_wsgi_middlewares(pyramid_app, config):
|
|||
pool = meta.Base.metadata.bind.engine.pool
|
||||
log.debug('sa pool status: %s', pool.status())
|
||||
|
||||
|
||||
return pyramid_app_with_cleanup
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -117,8 +117,9 @@ class JSRoutesMapper(Mapper):
|
|||
|
||||
def make_map(config):
|
||||
"""Create, configure and return the routes Mapper"""
|
||||
rmap = JSRoutesMapper(directory=config['pylons.paths']['controllers'],
|
||||
always_scan=config['debug'])
|
||||
rmap = JSRoutesMapper(
|
||||
directory=config['pylons.paths']['controllers'],
|
||||
always_scan=config['debug'])
|
||||
rmap.minimization = False
|
||||
rmap.explicit = False
|
||||
|
||||
|
|
@ -609,18 +610,6 @@ def make_map(config):
|
|||
controller='admin/repos', action='repo_check',
|
||||
requirements=URL_NAME_REQUIREMENTS)
|
||||
|
||||
rmap.connect('repo_stats', '/{repo_name}/repo_stats/{commit_id}',
|
||||
controller='summary', action='repo_stats',
|
||||
conditions={'function': check_repo},
|
||||
requirements=URL_NAME_REQUIREMENTS, jsroute=True)
|
||||
|
||||
rmap.connect('repo_refs_data', '/{repo_name}/refs-data',
|
||||
controller='summary', action='repo_refs_data',
|
||||
requirements=URL_NAME_REQUIREMENTS, jsroute=True)
|
||||
rmap.connect('repo_refs_changelog_data', '/{repo_name}/refs-data-changelog',
|
||||
controller='summary', action='repo_refs_changelog_data',
|
||||
requirements=URL_NAME_REQUIREMENTS, jsroute=True)
|
||||
|
||||
rmap.connect('changeset_home', '/{repo_name}/changeset/{revision}',
|
||||
controller='changeset', revision='tip',
|
||||
conditions={'function': check_repo},
|
||||
|
|
@ -834,19 +823,10 @@ def make_map(config):
|
|||
conditions={'function': check_repo, 'method': ['DELETE']},
|
||||
requirements=URL_NAME_REQUIREMENTS, jsroute=True)
|
||||
|
||||
rmap.connect('summary_home_explicit', '/{repo_name}/summary',
|
||||
controller='summary', conditions={'function': check_repo},
|
||||
requirements=URL_NAME_REQUIREMENTS)
|
||||
|
||||
rmap.connect('changelog_home', '/{repo_name}/changelog', jsroute=True,
|
||||
controller='changelog', conditions={'function': check_repo},
|
||||
requirements=URL_NAME_REQUIREMENTS)
|
||||
|
||||
rmap.connect('changelog_summary_home', '/{repo_name}/changelog_summary',
|
||||
controller='changelog', action='changelog_summary',
|
||||
conditions={'function': check_repo},
|
||||
requirements=URL_NAME_REQUIREMENTS)
|
||||
|
||||
rmap.connect('changelog_file_home',
|
||||
'/{repo_name}/changelog/{revision}/{f_path}',
|
||||
controller='changelog', f_path=None,
|
||||
|
|
@ -999,19 +979,4 @@ def make_map(config):
|
|||
conditions={'function': check_repo},
|
||||
requirements=URL_NAME_REQUIREMENTS)
|
||||
|
||||
# catch all, at the end
|
||||
_connect_with_slash(
|
||||
rmap, 'summary_home', '/{repo_name}', jsroute=True,
|
||||
controller='summary', action='index',
|
||||
conditions={'function': check_repo},
|
||||
requirements=URL_NAME_REQUIREMENTS)
|
||||
|
||||
return rmap
|
||||
|
||||
|
||||
def _connect_with_slash(mapper, name, path, *args, **kwargs):
|
||||
"""
|
||||
Connect a route with an optional trailing slash in `path`.
|
||||
"""
|
||||
mapper.connect(name + '_slash', path + '/', *args, **kwargs)
|
||||
mapper.connect(name, path, *args, **kwargs)
|
||||
|
|
|
|||
|
|
@ -274,9 +274,9 @@ class ReposController(BaseRepoController):
|
|||
h.flash(_('Created repository %s from %s')
|
||||
% (repo.repo_name, clone_uri), category='success')
|
||||
else:
|
||||
repo_url = h.link_to(repo.repo_name,
|
||||
h.url('summary_home',
|
||||
repo_name=repo.repo_name))
|
||||
repo_url = h.link_to(
|
||||
repo.repo_name,
|
||||
h.route_path('repo_summary',repo_name=repo.repo_name))
|
||||
fork = repo.fork
|
||||
if fork:
|
||||
fork_name = fork.repo_name
|
||||
|
|
@ -366,7 +366,7 @@ class ReposController(BaseRepoController):
|
|||
log.exception("Exception during unlocking")
|
||||
h.flash(_('An error occurred during unlocking'),
|
||||
category='error')
|
||||
return redirect(url('summary_home', repo_name=repo_name))
|
||||
return redirect(h.route_path('repo_summary', repo_name=repo_name))
|
||||
|
||||
@HasRepoPermissionAllDecorator('repository.admin')
|
||||
@auth.CSRFRequired()
|
||||
|
|
|
|||
|
|
@ -46,27 +46,6 @@ log = logging.getLogger(__name__)
|
|||
DEFAULT_CHANGELOG_SIZE = 20
|
||||
|
||||
|
||||
def _load_changelog_summary():
|
||||
p = safe_int(request.GET.get('page'), 1)
|
||||
size = safe_int(request.GET.get('size'), 10)
|
||||
|
||||
def url_generator(**kw):
|
||||
return url('summary_home',
|
||||
repo_name=c.rhodecode_db_repo.repo_name, size=size, **kw)
|
||||
|
||||
pre_load = ['author', 'branch', 'date', 'message']
|
||||
try:
|
||||
collection = c.rhodecode_repo.get_commits(pre_load=pre_load)
|
||||
except EmptyRepositoryError:
|
||||
collection = c.rhodecode_repo
|
||||
|
||||
c.repo_commits = RepoPage(
|
||||
collection, page=p, items_per_page=size, url=url_generator)
|
||||
page_ids = [x.raw_id for x in c.repo_commits]
|
||||
c.comments = c.rhodecode_db_repo.get_comments(page_ids)
|
||||
c.statuses = c.rhodecode_db_repo.statuses(page_ids)
|
||||
|
||||
|
||||
class ChangelogController(BaseRepoController):
|
||||
|
||||
def __before__(self):
|
||||
|
|
@ -211,7 +190,7 @@ class ChangelogController(BaseRepoController):
|
|||
|
||||
except EmptyRepositoryError as e:
|
||||
h.flash(safe_str(e), category='warning')
|
||||
return redirect(url('summary_home', repo_name=repo_name))
|
||||
return redirect(h.route_path('repo_summary', repo_name=repo_name))
|
||||
except (RepositoryError, CommitDoesNotExistError, Exception) as e:
|
||||
msg = safe_str(e)
|
||||
log.exception(msg)
|
||||
|
|
@ -279,12 +258,3 @@ class ChangelogController(BaseRepoController):
|
|||
c.rhodecode_repo, c.pagination,
|
||||
prev_data=prev_data, next_data=next_data)
|
||||
return render('changelog/changelog_elements.mako')
|
||||
|
||||
@LoginRequired()
|
||||
@HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
|
||||
'repository.admin')
|
||||
def changelog_summary(self, repo_name):
|
||||
if request.environ.get('HTTP_X_PJAX'):
|
||||
_load_changelog_summary()
|
||||
return render('changelog/changelog_summary_data.mako')
|
||||
raise HTTPNotFound()
|
||||
|
|
|
|||
|
|
@ -63,14 +63,14 @@ class CompareController(BaseRepoController):
|
|||
return repo.scm_instance().EMPTY_COMMIT
|
||||
h.flash(h.literal(_('There are no commits yet')),
|
||||
category='warning')
|
||||
redirect(url('summary_home', repo_name=repo.repo_name))
|
||||
redirect(h.route_path('repo_summary', repo_name=repo.repo_name))
|
||||
|
||||
except RepositoryError as e:
|
||||
msg = safe_str(e)
|
||||
log.exception(msg)
|
||||
h.flash(msg, category='warning')
|
||||
if not partial:
|
||||
redirect(h.url('summary_home', repo_name=repo.repo_name))
|
||||
redirect(h.route_path('repo_summary', repo_name=repo.repo_name))
|
||||
raise HTTPBadRequest()
|
||||
|
||||
@LoginRequired()
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ class FeedController(BaseRepoController):
|
|||
def _generate_feed(cache_key):
|
||||
feed = Atom1Feed(
|
||||
title=self.title % repo_name,
|
||||
link=url('summary_home', repo_name=repo_name, qualified=True),
|
||||
link=h.route_url('repo_summary', repo_name=repo_name),
|
||||
description=self.description % repo_name,
|
||||
language=self.language,
|
||||
ttl=self.ttl
|
||||
|
|
@ -150,8 +150,7 @@ class FeedController(BaseRepoController):
|
|||
def _generate_feed(cache_key):
|
||||
feed = Rss201rev2Feed(
|
||||
title=self.title % repo_name,
|
||||
link=url('summary_home', repo_name=repo_name,
|
||||
qualified=True),
|
||||
link=h.route_url('repo_summary', repo_name=repo_name),
|
||||
description=self.description % repo_name,
|
||||
language=self.language,
|
||||
ttl=self.ttl
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ class FilesController(BaseRepoController):
|
|||
add_new = ""
|
||||
h.flash(h.literal(
|
||||
_('There are no files yet. %s') % add_new), category='warning')
|
||||
redirect(h.url('summary_home', repo_name=repo_name))
|
||||
redirect(h.route_path('repo_summary', repo_name=repo_name))
|
||||
except (CommitDoesNotExistError, LookupError):
|
||||
msg = _('No such commit exists for this repository')
|
||||
h.flash(msg, category='error')
|
||||
|
|
@ -669,14 +669,14 @@ class FilesController(BaseRepoController):
|
|||
|
||||
# If there's no commit, redirect to repo summary
|
||||
if type(c.commit) is EmptyCommit:
|
||||
redirect_url = "summary_home"
|
||||
redirect_url = h.route_path('repo_summary', repo_name=c.repo_name)
|
||||
else:
|
||||
redirect_url = "changeset_home"
|
||||
redirect_url = url("changeset_home", repo_name=c.repo_name,
|
||||
revision='tip')
|
||||
|
||||
if not filename:
|
||||
h.flash(_('No filename'), category='warning')
|
||||
return redirect(url(redirect_url, repo_name=c.repo_name,
|
||||
revision='tip'))
|
||||
return redirect(redirect_url)
|
||||
|
||||
# extract the location from filename,
|
||||
# allows using foo/bar.txt syntax to create subdirectories
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ class PullrequestsController(BaseRepoController):
|
|||
except EmptyRepositoryError:
|
||||
h.flash(h.literal(_('There are no commits yet')),
|
||||
category='warning')
|
||||
redirect(url('summary_home', repo_name=source_repo.repo_name))
|
||||
redirect(h.route_path('repo_summary', repo_name=source_repo.repo_name))
|
||||
|
||||
commit_id = request.GET.get('commit')
|
||||
branch_ref = request.GET.get('branch')
|
||||
|
|
|
|||
|
|
@ -161,8 +161,9 @@ class ActionParser(object):
|
|||
return action_map
|
||||
|
||||
def get_fork_name(self):
|
||||
from rhodecode.lib import helpers as h
|
||||
repo_name = self.action_params
|
||||
_url = url('summary_home', repo_name=repo_name)
|
||||
_url = h.route_path('repo_summary', repo_name=repo_name)
|
||||
return _('fork name %s') % link_to(self.action_params, _url)
|
||||
|
||||
def get_user_name(self):
|
||||
|
|
|
|||
|
|
@ -1342,7 +1342,7 @@ class HasAcceptedRepoType(object):
|
|||
_('Action not supported for %s.' % rhodecode_repo.alias)),
|
||||
category='warning')
|
||||
return redirect(
|
||||
url('summary_home', repo_name=cls.rhodecode_db_repo.repo_name))
|
||||
h.route_path('repo_summary', repo_name=cls.rhodecode_db_repo.repo_name))
|
||||
|
||||
|
||||
class PermsDecorator(object):
|
||||
|
|
|
|||
|
|
@ -580,7 +580,7 @@ class BaseRepoController(BaseController):
|
|||
'Requirements are missing for repository %s: %s',
|
||||
c.repo_name, error.message)
|
||||
|
||||
summary_url = url('summary_home', repo_name=c.repo_name)
|
||||
summary_url = h.route_path('repo_summary', repo_name=c.repo_name)
|
||||
statistics_url = url('edit_repo_statistics', repo_name=c.repo_name)
|
||||
settings_update_url = url('repo', repo_name=c.repo_name)
|
||||
path = request.path
|
||||
|
|
|
|||
|
|
@ -1538,7 +1538,7 @@ def breadcrumb_repo_link(repo):
|
|||
link_to(group.name, route_path('repo_group_home', repo_group_name=group.group_name))
|
||||
for group in repo.groups_with_parents
|
||||
] + [
|
||||
link_to(repo.just_name, url('summary_home', repo_name=repo.repo_name))
|
||||
link_to(repo.just_name, route_path('repo_summary', repo_name=repo.repo_name))
|
||||
]
|
||||
|
||||
return literal(' » '.join(path))
|
||||
|
|
|
|||
|
|
@ -268,8 +268,7 @@ class CommentsModel(BaseModel):
|
|||
|
||||
target_repo_url = h.link_to(
|
||||
repo.repo_name,
|
||||
h.url('summary_home',
|
||||
repo_name=repo.repo_name, qualified=True))
|
||||
h.route_url('repo_summary', repo_name=repo.repo_name))
|
||||
|
||||
# commit specifics
|
||||
kwargs.update({
|
||||
|
|
@ -300,13 +299,11 @@ class CommentsModel(BaseModel):
|
|||
qualified=True,)
|
||||
|
||||
# set some variables for email notification
|
||||
pr_target_repo_url = h.url(
|
||||
'summary_home', repo_name=pr_target_repo.repo_name,
|
||||
qualified=True)
|
||||
pr_target_repo_url = h.route_url(
|
||||
'repo_summary', repo_name=pr_target_repo.repo_name)
|
||||
|
||||
pr_source_repo_url = h.url(
|
||||
'summary_home', repo_name=pr_source_repo.repo_name,
|
||||
qualified=True)
|
||||
pr_source_repo_url = h.route_url(
|
||||
'repo_summary', repo_name=pr_source_repo.repo_name)
|
||||
|
||||
# pull request specifics
|
||||
kwargs.update({
|
||||
|
|
|
|||
|
|
@ -1765,6 +1765,7 @@ class Repository(Base, BaseModel):
|
|||
# TODO: mikhail: Here there is an anti-pattern, we probably need to
|
||||
# move this methods on models level.
|
||||
from rhodecode.model.settings import SettingsModel
|
||||
from rhodecode.model.repo import RepoModel
|
||||
|
||||
repo = self
|
||||
_user_id, _time, _reason = self.locked
|
||||
|
|
@ -1774,7 +1775,7 @@ class Repository(Base, BaseModel):
|
|||
'repo_name': repo.repo_name,
|
||||
'repo_type': repo.repo_type,
|
||||
'clone_uri': repo.clone_uri or '',
|
||||
'url': repo.home_url(),
|
||||
'url': RepoModel().get_url(self),
|
||||
'private': repo.private,
|
||||
'created_on': repo.created_on,
|
||||
'description': repo.description,
|
||||
|
|
@ -1935,10 +1936,6 @@ class Repository(Base, BaseModel):
|
|||
repo_name=self.repo_name,
|
||||
repo_id=self.repo_id, **override)
|
||||
|
||||
def home_url(self):
|
||||
request = get_current_request()
|
||||
return request.route_url('repo_summary', repo_name=self.repo_name)
|
||||
|
||||
def set_state(self, state):
|
||||
self.repo_state = state
|
||||
Session().add(self)
|
||||
|
|
|
|||
|
|
@ -999,15 +999,11 @@ class PullRequestModel(BaseModel):
|
|||
qualified=True,)
|
||||
|
||||
# set some variables for email notification
|
||||
pr_target_repo_url = h.url(
|
||||
'summary_home',
|
||||
repo_name=pr_target_repo.repo_name,
|
||||
qualified=True)
|
||||
pr_target_repo_url = h.route_url(
|
||||
'repo_summary', repo_name=pr_target_repo.repo_name)
|
||||
|
||||
pr_source_repo_url = h.url(
|
||||
'summary_home',
|
||||
repo_name=pr_source_repo.repo_name,
|
||||
qualified=True)
|
||||
pr_source_repo_url = h.route_url(
|
||||
'repo_summary', repo_name=pr_source_repo.repo_name)
|
||||
|
||||
# pull request specifics
|
||||
pull_request_commits = [
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import time
|
|||
import traceback
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from pyramid.threadlocal import get_current_request
|
||||
from zope.cachedescriptors.property import Lazy as LazyProperty
|
||||
|
||||
from rhodecode import events
|
||||
|
|
@ -154,9 +155,10 @@ class RepoModel(BaseModel):
|
|||
repos = Repository.query().filter(Repository.group == root).all()
|
||||
return repos
|
||||
|
||||
def get_url(self, repo):
|
||||
return h.url('summary_home', repo_name=safe_str(repo.repo_name),
|
||||
qualified=True)
|
||||
def get_url(self, repo, request=None):
|
||||
if not request:
|
||||
request = get_current_request()
|
||||
return request.route_url('repo_summary', repo_name=safe_str(repo.repo_name))
|
||||
|
||||
@classmethod
|
||||
def update_repoinfo(cls, repositories=None):
|
||||
|
|
|
|||
|
|
@ -215,6 +215,7 @@
|
|||
float: left;
|
||||
display: block;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
|
||||
// adds some space to make copy and paste easier
|
||||
.left-label,
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ function setRCMouseBindings(repoName, repoLandingRev) {
|
|||
// nav in repo context
|
||||
Mousetrap.bind(['g s'], function(e) {
|
||||
window.location = pyroutes.url(
|
||||
'summary_home', {'repo_name': repoName});
|
||||
'repo_summary', {'repo_name': repoName});
|
||||
});
|
||||
Mousetrap.bind(['g c'], function(e) {
|
||||
window.location = pyroutes.url(
|
||||
|
|
|
|||
|
|
@ -18,9 +18,6 @@ function registerRCRoutes() {
|
|||
pyroutes.register('gists', '/_admin/gists', []);
|
||||
pyroutes.register('new_gist', '/_admin/gists/new', []);
|
||||
pyroutes.register('toggle_following', '/_admin/toggle_following', []);
|
||||
pyroutes.register('repo_stats', '/%(repo_name)s/repo_stats/%(commit_id)s', ['repo_name', 'commit_id']);
|
||||
pyroutes.register('repo_refs_data', '/%(repo_name)s/refs-data', ['repo_name']);
|
||||
pyroutes.register('repo_refs_changelog_data', '/%(repo_name)s/refs-data-changelog', ['repo_name']);
|
||||
pyroutes.register('changeset_home', '/%(repo_name)s/changeset/%(revision)s', ['repo_name', 'revision']);
|
||||
pyroutes.register('changeset_comment', '/%(repo_name)s/changeset/%(revision)s/comment', ['repo_name', 'revision']);
|
||||
pyroutes.register('changeset_comment_preview', '/%(repo_name)s/changeset/comment/preview', ['repo_name']);
|
||||
|
|
@ -46,8 +43,6 @@ function registerRCRoutes() {
|
|||
pyroutes.register('files_archive_home', '/%(repo_name)s/archive/%(fname)s', ['repo_name', 'fname']);
|
||||
pyroutes.register('files_nodelist_home', '/%(repo_name)s/nodelist/%(revision)s/%(f_path)s', ['repo_name', 'revision', 'f_path']);
|
||||
pyroutes.register('files_nodetree_full', '/%(repo_name)s/nodetree_full/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
|
||||
pyroutes.register('summary_home_slash', '/%(repo_name)s/', ['repo_name']);
|
||||
pyroutes.register('summary_home', '/%(repo_name)s', ['repo_name']);
|
||||
pyroutes.register('favicon', '/favicon.ico', []);
|
||||
pyroutes.register('robots', '/robots.txt', []);
|
||||
pyroutes.register('auth_home', '/_admin/auth*traverse', []);
|
||||
|
|
@ -99,8 +94,11 @@ function registerRCRoutes() {
|
|||
pyroutes.register('user_group_autocomplete_data', '/_user_groups', []);
|
||||
pyroutes.register('repo_list_data', '/_repos', []);
|
||||
pyroutes.register('goto_switcher_data', '/_goto_data', []);
|
||||
pyroutes.register('repo_summary', '/%(repo_name)s', ['repo_name']);
|
||||
pyroutes.register('repo_summary_explicit', '/%(repo_name)s/summary', ['repo_name']);
|
||||
pyroutes.register('repo_summary_commits', '/%(repo_name)s/summary-commits', ['repo_name']);
|
||||
pyroutes.register('repo_refs_data', '/%(repo_name)s/refs-data', ['repo_name']);
|
||||
pyroutes.register('repo_refs_changelog_data', '/%(repo_name)s/refs-data-changelog', ['repo_name']);
|
||||
pyroutes.register('repo_stats', '/%(repo_name)s/repo_stats/%(commit_id)s', ['repo_name', 'commit_id']);
|
||||
pyroutes.register('tags_home', '/%(repo_name)s/tags', ['repo_name']);
|
||||
pyroutes.register('branches_home', '/%(repo_name)s/branches', ['repo_name']);
|
||||
pyroutes.register('bookmarks_home', '/%(repo_name)s/bookmarks', ['repo_name']);
|
||||
|
|
@ -122,6 +120,8 @@ function registerRCRoutes() {
|
|||
pyroutes.register('strip', '/%(repo_name)s/settings/strip', ['repo_name']);
|
||||
pyroutes.register('strip_check', '/%(repo_name)s/settings/strip_check', ['repo_name']);
|
||||
pyroutes.register('strip_execute', '/%(repo_name)s/settings/strip_execute', ['repo_name']);
|
||||
pyroutes.register('repo_summary', '/%(repo_name)s', ['repo_name']);
|
||||
pyroutes.register('repo_summary_slash', '/%(repo_name)s/', ['repo_name']);
|
||||
pyroutes.register('repo_group_home', '/%(repo_group_name)s', ['repo_group_name']);
|
||||
pyroutes.register('repo_group_home_slash', '/%(repo_group_name)s/', ['repo_group_name']);
|
||||
pyroutes.register('search', '/_admin/search', []);
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@
|
|||
</td>
|
||||
<td class="td-componentname">
|
||||
%if l.repository is not None:
|
||||
${h.link_to(l.repository.repo_name,h.url('summary_home',repo_name=l.repository.repo_name))}
|
||||
${h.link_to(l.repository.repo_name, h.route_path('repo_summary',repo_name=l.repository.repo_name))}
|
||||
%else:
|
||||
${l.repository_name}
|
||||
%endif
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@
|
|||
</td>
|
||||
<td class="td-scope">
|
||||
%if integration.repo:
|
||||
<a href="${h.url('summary_home', repo_name=integration.repo.repo_name)}">
|
||||
<a href="${h.route_path('repo_summary', repo_name=integration.repo.repo_name)}">
|
||||
${_('repo')}:${integration.repo.repo_name}
|
||||
</a>
|
||||
%elif integration.repo_group:
|
||||
|
|
|
|||
|
|
@ -48,12 +48,12 @@
|
|||
if (jsonResponse === undefined) {
|
||||
setTimeout(function () {
|
||||
// we might have a backend problem, try dashboard again
|
||||
window.location = "${h.url('summary_home', repo_name = c.repo)}";
|
||||
window.location = "${h.route_path('repo_summary', repo_name = c.repo)}";
|
||||
}, 3000);
|
||||
} else {
|
||||
if (skipCheck || jsonResponse.result === true) {
|
||||
// success, means go to dashboard
|
||||
window.location = "${h.url('summary_home', repo_name = c.repo)}";
|
||||
window.location = "${h.route_path('repo_summary', repo_name = c.repo)}";
|
||||
} else {
|
||||
// Schedule the next request when the current one's complete
|
||||
setTimeout(worker, 1000);
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
${h.secure_form(h.route_path('edit_repo_advanced_fork', repo_name=c.repo_info.repo_name), method='POST')}
|
||||
|
||||
% if c.repo_info.fork:
|
||||
<div class="panel-body-title-text">${h.literal(_('This repository is a fork of %(repo_link)s') % {'repo_link': h.link_to_if(c.has_origin_repo_read_perm,c.repo_info.fork.repo_name, h.url('summary_home', repo_name=c.repo_info.fork.repo_name))})}
|
||||
<div class="panel-body-title-text">${h.literal(_('This repository is a fork of %(repo_link)s') % {'repo_link': h.link_to_if(c.has_origin_repo_read_perm,c.repo_info.fork.repo_name, h.route_path('repo_summary', repo_name=c.repo_info.fork.repo_name))})}
|
||||
| <button class="btn btn-link btn-danger" type="submit">Remove fork reference</button></div>
|
||||
% endif
|
||||
|
||||
|
|
|
|||
|
|
@ -52,6 +52,6 @@
|
|||
<script>
|
||||
$('#check_for_update').click(function(e){
|
||||
$('#update_notice').show();
|
||||
$('#update_notice').load("${h.route_path('admin_settings_system_update',version=c.rhodecode_version, platform=c.platform)}");
|
||||
$('#update_notice').load("${h.route_path('admin_settings_system_update')}");
|
||||
})
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@
|
|||
%if repo_instance.fork:
|
||||
<p>
|
||||
<i class="icon-code-fork"></i> ${_('Fork of')}
|
||||
<a href="${h.url('summary_home',repo_name=repo_instance.fork.repo_name)}">${repo_instance.fork.repo_name}</a>
|
||||
<a href="${h.route_path('repo_summary',repo_name=repo_instance.fork.repo_name)}">${repo_instance.fork.repo_name}</a>
|
||||
</p>
|
||||
%endif
|
||||
|
||||
|
|
@ -225,7 +225,7 @@
|
|||
<div id="context-bar">
|
||||
<div class="wrapper">
|
||||
<ul id="context-pages" class="horizontal-list navigation">
|
||||
<li class="${is_active('summary')}"><a class="menulink" href="${h.url('summary_home', repo_name=c.repo_name)}"><div class="menulabel">${_('Summary')}</div></a></li>
|
||||
<li class="${is_active('summary')}"><a class="menulink" href="${h.route_path('repo_summary', repo_name=c.repo_name)}"><div class="menulabel">${_('Summary')}</div></a></li>
|
||||
<li class="${is_active('changelog')}"><a class="menulink" href="${h.url('changelog_home', repo_name=c.repo_name)}"><div class="menulabel">${_('Changelog')}</div></a></li>
|
||||
<li class="${is_active('files')}"><a class="menulink" href="${h.url('files_home', repo_name=c.repo_name, revision=c.rhodecode_db_repo.landing_rev[1])}"><div class="menulabel">${_('Files')}</div></a></li>
|
||||
<li class="${is_active('compare')}">
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@
|
|||
<tr class="perm_row ${'%s_%s' % (section, section_perm.split('.')[-1])}">
|
||||
<td class="td-componentname">
|
||||
%if section == 'repositories':
|
||||
<a href="${h.url('summary_home',repo_name=k)}">${k}</a>
|
||||
<a href="${h.route_path('repo_summary',repo_name=k)}">${k}</a>
|
||||
%elif section == 'repositories_groups':
|
||||
<a href="${h.route_path('repo_group_home', repo_group_name=k)}">${k}</a>
|
||||
%elif section == 'user_groups':
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
<div class="menu_items_container hidden">
|
||||
<ul class="menu_items">
|
||||
<li>
|
||||
<a title="${_('Summary')}" href="${h.url('summary_home',repo_name=repo_name)}">
|
||||
<a title="${_('Summary')}" href="${h.route_path('repo_summary',repo_name=repo_name)}">
|
||||
<span>${_('Summary')}</span>
|
||||
</a>
|
||||
</li>
|
||||
|
|
@ -42,7 +42,7 @@
|
|||
%>
|
||||
<div class="${'repo_state_pending' if rstate == 'repo_state_pending' else ''} truncate">
|
||||
##NAME
|
||||
<a href="${h.route_path('edit_repo',repo_name=name) if admin else h.url('summary_home',repo_name=name)}">
|
||||
<a href="${h.route_path('edit_repo',repo_name=name) if admin else h.route_path('repo_summary',repo_name=name)}">
|
||||
|
||||
##TYPE OF REPO
|
||||
%if h.is_hg(rtype):
|
||||
|
|
@ -64,7 +64,7 @@
|
|||
${get_name(name)}
|
||||
</a>
|
||||
%if fork_of:
|
||||
<a href="${h.url('summary_home',repo_name=fork_of.repo_name)}"><i class="icon-code-fork"></i></a>
|
||||
<a href="${h.route_path('repo_summary',repo_name=fork_of.repo_name)}"><i class="icon-code-fork"></i></a>
|
||||
%endif
|
||||
%if rstate == 'repo_state_pending':
|
||||
<i class="icon-cogs" title="${_('Repository creating in progress...')}"></i>
|
||||
|
|
@ -282,7 +282,7 @@
|
|||
|
||||
<%def name="pullrequest_target_repo(repo_name)">
|
||||
<div class="truncate">
|
||||
${h.link_to(repo_name,h.url('summary_home',repo_name=repo_name))}
|
||||
${h.link_to(repo_name,h.route_path('repo_summary',repo_name=repo_name))}
|
||||
</div>
|
||||
</%def>
|
||||
<%def name="pullrequest_status(status)">
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
${base.gravatar_with_user(f.user.email, 16)}
|
||||
</td>
|
||||
<td class="td-componentname">
|
||||
${h.link_to(f.repo_name,h.url('summary_home',repo_name=f.repo_name))}
|
||||
${h.link_to(f.repo_name,h.route_path('repo_summary',repo_name=f.repo_name))}
|
||||
</td>
|
||||
<td class="td-description">
|
||||
<div class="truncate">${f.description}</div>
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
<span class="journal_repo_name">
|
||||
%if entry.repository is not None:
|
||||
${h.link_to(entry.repository.repo_name,
|
||||
h.url('summary_home',repo_name=entry.repository.repo_name))}
|
||||
h.route_path('repo_summary',repo_name=entry.repository.repo_name))}
|
||||
%else:
|
||||
${entry.repository_name}
|
||||
%endif
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@
|
|||
%endif
|
||||
</span>
|
||||
<span class="clone-url">
|
||||
<a href="${h.url('summary_home', repo_name=c.pull_request.source_repo.repo_name)}">${c.pull_request.source_repo.clone_url()}</a>
|
||||
<a href="${h.route_path('repo_summary', repo_name=c.pull_request.source_repo.repo_name)}">${c.pull_request.source_repo.clone_url()}</a>
|
||||
</span>
|
||||
<br/>
|
||||
% if c.ancestor_commit:
|
||||
|
|
@ -113,7 +113,7 @@
|
|||
%endif
|
||||
</span>
|
||||
<span class="clone-url">
|
||||
<a href="${h.url('summary_home', repo_name=c.pull_request.target_repo.repo_name)}">${c.pull_request.target_repo.clone_url()}</a>
|
||||
<a href="${h.route_path('repo_summary', repo_name=c.pull_request.target_repo.repo_name)}">${c.pull_request.target_repo.clone_url()}</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
%elif h.get_repo_type_by_name(entry.get('repository')) == 'svn':
|
||||
<i class="icon-svn"></i>
|
||||
%endif
|
||||
${h.link_to(entry['repository'], h.url('summary_home',repo_name=entry['repository']))}
|
||||
${h.link_to(entry['repository'], h.route_path('repo_summary',repo_name=entry['repository']))}
|
||||
</td>
|
||||
<td class="td-commit">
|
||||
${h.link_to(h._shorten_commit_id(entry['commit_id']),
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ ${h.code_highlight(
|
|||
%elif h.get_repo_type_by_name(entry.get('repository')) == 'svn':
|
||||
<i class="icon-svn"></i>
|
||||
%endif
|
||||
${h.link_to(entry['repository'], h.url('summary_home',repo_name=entry['repository']))}
|
||||
${h.link_to(entry['repository'], h.route_path('repo_summary',repo_name=entry['repository']))}
|
||||
</h2>
|
||||
<div class="stats">
|
||||
${h.link_to(h.literal(entry['f_path']), h.url('files_home',repo_name=entry['repository'],revision=entry.get('commit_id', 'tip'),f_path=entry['f_path']))}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
%elif h.get_repo_type_by_name(entry.get('repository')) == 'svn':
|
||||
<i class="icon-svn"></i>
|
||||
%endif
|
||||
${h.link_to(entry['repository'], h.url('summary_home',repo_name=entry['repository']))}
|
||||
${h.link_to(entry['repository'], h.route_path('repo_summary',repo_name=entry['repository']))}
|
||||
</td>
|
||||
<td class="td-componentname">
|
||||
${h.link_to(h.literal(entry['f_path']),
|
||||
|
|
|
|||
|
|
@ -1,28 +1,28 @@
|
|||
<%def name="refs_counters(branches, closed_branches, tags, bookmarks)">
|
||||
<span class="branchtag tag">
|
||||
<a href="${h.route_path('branches_home',repo_name=c.repo_name)}" class="childs">
|
||||
<i class="icon-branch"></i>${ungettext(
|
||||
<i class="icon-branch"></i>${_ungettext(
|
||||
'%(num)s Branch','%(num)s Branches', len(branches)) % {'num': len(branches)}}</a>
|
||||
</span>
|
||||
|
||||
%if closed_branches:
|
||||
<span class="branchtag tag">
|
||||
<a href="${h.route_path('branches_home',repo_name=c.repo_name)}" class="childs">
|
||||
<i class="icon-branch"></i>${ungettext(
|
||||
<i class="icon-branch"></i>${_ungettext(
|
||||
'%(num)s Closed Branch', '%(num)s Closed Branches', len(closed_branches)) % {'num': len(closed_branches)}}</a>
|
||||
</span>
|
||||
%endif
|
||||
|
||||
<span class="tagtag tag">
|
||||
<a href="${h.route_path('tags_home',repo_name=c.repo_name)}" class="childs">
|
||||
<i class="icon-tag"></i>${ungettext(
|
||||
<i class="icon-tag"></i>${_ungettext(
|
||||
'%(num)s Tag', '%(num)s Tags', len(tags)) % {'num': len(tags)}}</a>
|
||||
</span>
|
||||
|
||||
%if bookmarks:
|
||||
<span class="booktag tag">
|
||||
<a href="${h.route_path('bookmarks_home',repo_name=c.repo_name)}" class="childs">
|
||||
<i class="icon-bookmark"></i>${ungettext(
|
||||
<i class="icon-bookmark"></i>${_ungettext(
|
||||
'%(num)s Bookmark', '%(num)s Bookmarks', len(bookmarks)) % {'num': len(bookmarks)}}</a>
|
||||
</span>
|
||||
%endif
|
||||
|
|
@ -92,15 +92,15 @@
|
|||
|
||||
## commits
|
||||
% if commit_rev == -1:
|
||||
${ungettext('%(num)s Commit', '%(num)s Commits', 0) % {'num': 0}},
|
||||
${_ungettext('%(num)s Commit', '%(num)s Commits', 0) % {'num': 0}},
|
||||
% else:
|
||||
<a href="${h.url('changelog_home', repo_name=c.repo_name)}">
|
||||
${ungettext('%(num)s Commit', '%(num)s Commits', commit_rev) % {'num': commit_rev}}</a>,
|
||||
${_ungettext('%(num)s Commit', '%(num)s Commits', commit_rev) % {'num': commit_rev}}</a>,
|
||||
% endif
|
||||
|
||||
## forks
|
||||
<a title="${_('Number of Repository Forks')}" href="${h.url('repo_forks_home', repo_name=c.repo_name)}">
|
||||
${c.repository_forks} ${ungettext('Fork', 'Forks', c.repository_forks)}</a>,
|
||||
${c.repository_forks} ${_ungettext('Fork', 'Forks', c.repository_forks)}</a>,
|
||||
|
||||
## repo size
|
||||
% if commit_rev == -1:
|
||||
|
|
|
|||
|
|
@ -14,8 +14,14 @@
|
|||
|
||||
<div class="alert alert-dismissable alert-warning">
|
||||
<strong>Missing requirements</strong>
|
||||
These commits cannot be displayed, because this repository uses the Mercurial largefiles extension, which was not enabled.
|
||||
Please <a href="${h.url('repo_vcs_settings', repo_name=c.repo_name)}">enable this extension in settings</a>, or contact the repository owner for help.
|
||||
Commits cannot be displayed, because this repository uses one or more extensions, which was not enabled. <br/>
|
||||
Please <a href="${h.url('repo_vcs_settings', repo_name=c.repo_name)}">enable extension in settings</a>, or contact the repository owner for help.
|
||||
Missing extensions could be:
|
||||
<pre>
|
||||
|
||||
- Mercurial largefiles
|
||||
- Git LFS
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
</%def>
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
%endif
|
||||
<div class="table">
|
||||
<div id="shortlog_data">
|
||||
<%include file='../changelog/changelog_summary_data.mako'/>
|
||||
<%include file='summary_commits.mako'/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -110,8 +110,7 @@ $(document).ready(function(){
|
|||
|
||||
var callback = function (data) {
|
||||
% if c.show_stats:
|
||||
showRepoStats(
|
||||
'lang_stats', data);
|
||||
showRepoStats('lang_stats', data);
|
||||
% endif
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ def scm_extras(user_regular, repo_stub):
|
|||
RepoPreCreateEvent, RepoCreateEvent,
|
||||
RepoPreDeleteEvent, RepoDeleteEvent,
|
||||
])
|
||||
def test_repo_events_serialized(repo_stub, EventClass):
|
||||
def test_repo_events_serialized(config_stub, repo_stub, EventClass):
|
||||
event = EventClass(repo_stub)
|
||||
data = event.as_dict()
|
||||
assert data['name'] == EventClass.name
|
||||
|
|
@ -67,7 +67,7 @@ def test_repo_events_serialized(repo_stub, EventClass):
|
|||
@pytest.mark.parametrize('EventClass', [
|
||||
RepoPrePullEvent, RepoPullEvent, RepoPrePushEvent
|
||||
])
|
||||
def test_vcs_repo_events_serialize(repo_stub, scm_extras, EventClass):
|
||||
def test_vcs_repo_events_serialize(config_stub, repo_stub, scm_extras, EventClass):
|
||||
event = EventClass(repo_name=repo_stub.repo_name, extras=scm_extras)
|
||||
data = event.as_dict()
|
||||
assert data['name'] == EventClass.name
|
||||
|
|
@ -76,7 +76,7 @@ def test_vcs_repo_events_serialize(repo_stub, scm_extras, EventClass):
|
|||
|
||||
|
||||
@pytest.mark.parametrize('EventClass', [RepoPushEvent])
|
||||
def test_vcs_repo_push_event_serialize(repo_stub, scm_extras, EventClass):
|
||||
def test_vcs_repo_push_event_serialize(config_stub, repo_stub, scm_extras, EventClass):
|
||||
event = EventClass(repo_name=repo_stub.repo_name,
|
||||
pushed_commit_ids=scm_extras['commit_ids'],
|
||||
extras=scm_extras)
|
||||
|
|
|
|||
|
|
@ -24,10 +24,10 @@ import mock
|
|||
import pytest
|
||||
|
||||
from rhodecode.lib import auth
|
||||
from rhodecode.lib.utils2 import safe_str, str2bool, safe_unicode
|
||||
from rhodecode.lib.vcs.exceptions import RepositoryRequirementError
|
||||
from rhodecode.model.db import Repository, RepoGroup, UserRepoToPerm, User,\
|
||||
Permission
|
||||
from rhodecode.lib.utils2 import safe_str, str2bool
|
||||
from rhodecode.lib import helpers as h
|
||||
from rhodecode.model.db import (
|
||||
Repository, RepoGroup, UserRepoToPerm, User, Permission)
|
||||
from rhodecode.model.meta import Session
|
||||
from rhodecode.model.repo import RepoModel
|
||||
from rhodecode.model.repo_group import RepoGroupModel
|
||||
|
|
@ -475,7 +475,7 @@ class TestAdminRepos(object):
|
|||
assert new_repo.description == description
|
||||
|
||||
# test if the repository is visible in the list ?
|
||||
response = self.app.get(url('summary_home', repo_name=repo_name))
|
||||
response = self.app.get(h.route_path('repo_summary', repo_name=repo_name))
|
||||
response.mustcontain(repo_name)
|
||||
response.mustcontain(backend.alias)
|
||||
|
||||
|
|
|
|||
|
|
@ -796,11 +796,12 @@ class TestChangingFiles:
|
|||
|
||||
# Not allowed, redirect to the summary
|
||||
redirected = response.follow()
|
||||
summary_url = url('summary_home', repo_name=repo.repo_name)
|
||||
summary_url = h.route_path('repo_summary', repo_name=repo.repo_name)
|
||||
|
||||
# As there are no commits, displays the summary page with the error of
|
||||
# creating a file with no filename
|
||||
assert redirected.req.path == summary_url
|
||||
|
||||
assert redirected.request.path == summary_url
|
||||
|
||||
@pytest.mark.parametrize("location, filename", [
|
||||
('/abs', 'foo'),
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import pytest
|
|||
|
||||
from rhodecode.tests import *
|
||||
from rhodecode.tests.fixture import Fixture
|
||||
from rhodecode.lib import helpers as h
|
||||
|
||||
from rhodecode.model.db import Repository
|
||||
from rhodecode.model.repo import RepoModel
|
||||
|
|
@ -147,7 +148,7 @@ class _BaseTest(TestController):
|
|||
assert fork_repo.fork.repo_name == repo_name
|
||||
|
||||
# test if the repository is visible in the list ?
|
||||
response = self.app.get(url('summary_home', repo_name=fork_name_full))
|
||||
response = self.app.get(h.route_path('repo_summary', repo_name=fork_name_full))
|
||||
response.mustcontain(fork_name_full)
|
||||
response.mustcontain(self.REPO_TYPE)
|
||||
|
||||
|
|
@ -193,7 +194,7 @@ class _BaseTest(TestController):
|
|||
assert fork_repo.fork.repo_name == repo_name
|
||||
|
||||
# test if the repository is visible in the list ?
|
||||
response = self.app.get(url('summary_home', repo_name=fork_name))
|
||||
response = self.app.get(h.route_path('repo_summary', repo_name=fork_name))
|
||||
response.mustcontain(fork_name)
|
||||
response.mustcontain(self.REPO_TYPE)
|
||||
response.mustcontain('Fork of')
|
||||
|
|
@ -254,7 +255,7 @@ class TestHG(_BaseTest):
|
|||
|
||||
@pytest.mark.usefixtures('app', 'autologin_user')
|
||||
@pytest.mark.skip_backends('git','hg')
|
||||
class TestSVNFork:
|
||||
class TestSVNFork(object):
|
||||
|
||||
def test_fork_redirects(self, backend):
|
||||
denied_actions = ['fork','fork_create']
|
||||
|
|
@ -266,7 +267,7 @@ class TestSVNFork:
|
|||
|
||||
# Not allowed, redirect to the summary
|
||||
redirected = response.follow()
|
||||
summary_url = url('summary_home', repo_name=backend.repo_name)
|
||||
summary_url = h.route_path('repo_summary', repo_name=backend.repo_name)
|
||||
|
||||
# URL adds leading slash and path doesn't have it
|
||||
assert redirected.req.path == summary_url
|
||||
assert redirected.request.path == summary_url
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ from rhodecode.tests import (
|
|||
no_newline_id_generator)
|
||||
from rhodecode.tests.fixture import Fixture
|
||||
from rhodecode.lib.auth import check_password
|
||||
from rhodecode.lib import helpers as h
|
||||
from rhodecode.model.auth_token import AuthTokenModel
|
||||
from rhodecode.model import validators
|
||||
from rhodecode.model.db import User, Notification, UserApiKeys
|
||||
|
|
@ -105,8 +106,9 @@ class TestLoginController(object):
|
|||
with fixture.anon_access(False):
|
||||
kwargs = {'branch': 'stable'}
|
||||
response = self.app.get(
|
||||
url('summary_home', repo_name=HG_REPO, **kwargs))
|
||||
h.route_path('repo_summary', repo_name=HG_REPO, _query=kwargs))
|
||||
assert response.status == '302 Found'
|
||||
|
||||
response_query = urlparse.parse_qsl(response.location)
|
||||
assert 'branch=stable' in response_query[0][1]
|
||||
|
||||
|
|
|
|||
|
|
@ -24,13 +24,13 @@ from webob.exc import HTTPNotFound
|
|||
|
||||
import rhodecode
|
||||
from rhodecode.lib.vcs.nodes import FileNode
|
||||
from rhodecode.lib import helpers as h
|
||||
from rhodecode.model.changeset_status import ChangesetStatusModel
|
||||
from rhodecode.model.db import (
|
||||
PullRequest, ChangesetStatus, UserLog, Notification)
|
||||
from rhodecode.model.meta import Session
|
||||
from rhodecode.model.pull_request import PullRequestModel
|
||||
from rhodecode.model.user import UserModel
|
||||
from rhodecode.model.repo import RepoModel
|
||||
from rhodecode.tests import (
|
||||
assert_session_flash, url, TEST_USER_ADMIN_LOGIN, TEST_USER_REGULAR_LOGIN)
|
||||
from rhodecode.tests.utils import AssertResponse
|
||||
|
|
@ -38,7 +38,7 @@ from rhodecode.tests.utils import AssertResponse
|
|||
|
||||
@pytest.mark.usefixtures('app', 'autologin_user')
|
||||
@pytest.mark.backends("git", "hg")
|
||||
class TestPullrequestsController:
|
||||
class TestPullrequestsController(object):
|
||||
|
||||
def test_index(self, backend):
|
||||
self.app.get(url(
|
||||
|
|
@ -47,7 +47,7 @@ class TestPullrequestsController:
|
|||
|
||||
def test_option_menu_create_pull_request_exists(self, backend):
|
||||
repo_name = backend.repo_name
|
||||
response = self.app.get(url('summary_home', repo_name=repo_name))
|
||||
response = self.app.get(h.route_path('repo_summary', repo_name=repo_name))
|
||||
|
||||
create_pr_link = '<a href="%s">Create Pull Request</a>' % url(
|
||||
'pullrequest', repo_name=repo_name)
|
||||
|
|
@ -1074,10 +1074,10 @@ def test_redirects_to_repo_summary_for_svn_repositories(backend_svn, app, action
|
|||
|
||||
# Not allowed, redirect to the summary
|
||||
redirected = response.follow()
|
||||
summary_url = url('summary_home', repo_name=backend_svn.repo_name)
|
||||
summary_url = h.route_path('repo_summary', repo_name=backend_svn.repo_name)
|
||||
|
||||
# URL adds leading slash and path doesn't have it
|
||||
assert redirected.req.path == summary_url
|
||||
assert redirected.request.path == summary_url
|
||||
|
||||
|
||||
def test_delete_comment_returns_404_if_comment_does_not_exist(pylonsapp):
|
||||
|
|
|
|||
|
|
@ -20,10 +20,10 @@
|
|||
|
||||
import pytest
|
||||
from mock import Mock, patch
|
||||
from pylons import url
|
||||
|
||||
from rhodecode.lib import base
|
||||
from rhodecode.lib.vcs.exceptions import RepositoryRequirementError
|
||||
from rhodecode.lib import helpers as h
|
||||
from rhodecode.model import db
|
||||
|
||||
|
||||
|
|
@ -165,7 +165,7 @@ class TestBaseRepoControllerHandleMissingRequirements(object):
|
|||
context_mock.repo_name = repo_name
|
||||
controller._handle_missing_requirements(error)
|
||||
|
||||
expected_url = url('summary_home', repo_name=repo_name)
|
||||
expected_url = h.route_path('repo_summary', repo_name=repo_name)
|
||||
if should_redirect:
|
||||
redirect_mock.assert_called_once_with(expected_url)
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -1682,6 +1682,15 @@ def request_stub():
|
|||
return request
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def context_stub():
|
||||
"""
|
||||
Stub context object.
|
||||
"""
|
||||
context = pyramid.testing.DummyResource()
|
||||
return context
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def config_stub(request, request_stub):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -123,6 +123,7 @@ def set_anonymous_access(enabled):
|
|||
user.active = enabled
|
||||
Session().add(user)
|
||||
Session().commit()
|
||||
time.sleep(1.5) # must sleep for cache (1s to expire)
|
||||
log.info('anonymous access is now: %s', enabled)
|
||||
assert enabled == User.get_default_user().active, (
|
||||
'Cannot set anonymous access')
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue