diff --git a/rhodecode/apps/admin/__init__.py b/rhodecode/apps/admin/__init__.py
--- a/rhodecode/apps/admin/__init__.py
+++ b/rhodecode/apps/admin/__init__.py
@@ -20,7 +20,6 @@
from rhodecode.apps._base import ADMIN_PREFIX
-from rhodecode.lib.utils2 import str2bool
def admin_routes(config):
@@ -82,6 +81,88 @@ def admin_routes(config):
name='admin_defaults_repositories_update',
pattern='/defaults/repositories/update')
+ # admin settings
+
+ config.add_route(
+ name='admin_settings',
+ pattern='/settings')
+ config.add_route(
+ name='admin_settings_update',
+ pattern='/settings/update')
+
+ config.add_route(
+ name='admin_settings_global',
+ pattern='/settings/global')
+ config.add_route(
+ name='admin_settings_global_update',
+ pattern='/settings/global/update')
+
+ config.add_route(
+ name='admin_settings_vcs',
+ pattern='/settings/vcs')
+ config.add_route(
+ name='admin_settings_vcs_update',
+ pattern='/settings/vcs/update')
+ config.add_route(
+ name='admin_settings_vcs_svn_pattern_delete',
+ pattern='/settings/vcs/svn_pattern_delete')
+
+ config.add_route(
+ name='admin_settings_mapping',
+ pattern='/settings/mapping')
+ config.add_route(
+ name='admin_settings_mapping_update',
+ pattern='/settings/mapping/update')
+
+ config.add_route(
+ name='admin_settings_visual',
+ pattern='/settings/visual')
+ config.add_route(
+ name='admin_settings_visual_update',
+ pattern='/settings/visual/update')
+
+
+ config.add_route(
+ name='admin_settings_issuetracker',
+ pattern='/settings/issue-tracker')
+ config.add_route(
+ name='admin_settings_issuetracker_update',
+ pattern='/settings/issue-tracker/update')
+ config.add_route(
+ name='admin_settings_issuetracker_test',
+ pattern='/settings/issue-tracker/test')
+ config.add_route(
+ name='admin_settings_issuetracker_delete',
+ pattern='/settings/issue-tracker/delete')
+
+ config.add_route(
+ name='admin_settings_email',
+ pattern='/settings/email')
+ config.add_route(
+ name='admin_settings_email_update',
+ pattern='/settings/email/update')
+
+ config.add_route(
+ name='admin_settings_hooks',
+ pattern='/settings/hooks')
+ config.add_route(
+ name='admin_settings_hooks_update',
+ pattern='/settings/hooks/update')
+ config.add_route(
+ name='admin_settings_hooks_delete',
+ pattern='/settings/hooks/delete')
+
+ config.add_route(
+ name='admin_settings_search',
+ pattern='/settings/search')
+
+ config.add_route(
+ name='admin_settings_labs',
+ pattern='/settings/labs')
+ config.add_route(
+ name='admin_settings_labs_update',
+ pattern='/settings/labs/update')
+
# global permissions
config.add_route(
@@ -236,7 +317,7 @@ def admin_routes(config):
config.add_route(
name='edit_user_ips_delete',
pattern='/users/{user_id:\d+}/edit/ips/delete',
- user_route_with_default=True) # enabled for default user too
+ user_route_with_default=True) # enabled for default user too
# user perms
config.add_route(
diff --git a/rhodecode/apps/admin/navigation.py b/rhodecode/apps/admin/navigation.py
--- a/rhodecode/apps/admin/navigation.py
+++ b/rhodecode/apps/admin/navigation.py
@@ -46,65 +46,53 @@ class NavEntry(object):
be removed as soon as we are fully migrated to pyramid.
"""
- def __init__(self, key, name, view_name, pyramid=False):
+ def __init__(self, key, name, view_name):
self.key = key
self.name = name
self.view_name = view_name
- self.pyramid = pyramid
def generate_url(self, request):
- if self.pyramid:
- if hasattr(request, 'route_path'):
- return request.route_path(self.view_name)
- else:
- # TODO: johbo: Remove this after migrating to pyramid.
- # We need the pyramid request here to generate URLs to pyramid
- # views from within pylons views.
- from pyramid.threadlocal import get_current_request
- pyramid_request = get_current_request()
- return pyramid_request.route_path(self.view_name)
- else:
- from pylons import url
- return url(self.view_name)
+ return request.route_path(self.view_name)
def get_localized_name(self, request):
- if hasattr(request, 'translate'):
- return request.translate(self.name)
- else:
- # TODO(marcink): Remove this after migrating to pyramid
- from pyramid.threadlocal import get_current_request
- pyramid_request = get_current_request()
- return pyramid_request.translate(self.name)
+ return request.translate(self.name)
@implementer(IAdminNavigationRegistry)
class NavigationRegistry(object):
_base_entries = [
- NavEntry('global', _('Global'), 'admin_settings_global'),
- NavEntry('vcs', _('VCS'), 'admin_settings_vcs'),
- NavEntry('visual', _('Visual'), 'admin_settings_visual'),
- NavEntry('mapping', _('Remap and Rescan'), 'admin_settings_mapping'),
+ NavEntry('global', _('Global'),
+ 'admin_settings_global'),
+ NavEntry('vcs', _('VCS'),
+ 'admin_settings_vcs'),
+ NavEntry('visual', _('Visual'),
+ 'admin_settings_visual'),
+ NavEntry('mapping', _('Remap and Rescan'),
+ 'admin_settings_mapping'),
NavEntry('issuetracker', _('Issue Tracker'),
'admin_settings_issuetracker'),
- NavEntry('email', _('Email'), 'admin_settings_email'),
- NavEntry('hooks', _('Hooks'), 'admin_settings_hooks'),
- NavEntry('search', _('Full Text Search'), 'admin_settings_search'),
-
+ NavEntry('email', _('Email'),
+ 'admin_settings_email'),
+ NavEntry('hooks', _('Hooks'),
+ 'admin_settings_hooks'),
+ NavEntry('search', _('Full Text Search'),
+ 'admin_settings_search'),
NavEntry('integrations', _('Integrations'),
- 'global_integrations_home', pyramid=True),
+ 'global_integrations_home'),
NavEntry('system', _('System Info'),
- 'admin_settings_system', pyramid=True),
+ 'admin_settings_system'),
NavEntry('process_management', _('Processes'),
- 'admin_settings_process_management', pyramid=True),
+ 'admin_settings_process_management'),
NavEntry('sessions', _('User Sessions'),
- 'admin_settings_sessions', pyramid=True),
+ 'admin_settings_sessions'),
NavEntry('open_source', _('Open Source Licenses'),
- 'admin_settings_open_source', pyramid=True),
+ 'admin_settings_open_source'),
]
- _labs_entry = NavEntry('labs', _('Labs'), 'admin_settings_labs')
+ _labs_entry = NavEntry('labs', _('Labs'),
+ 'admin_settings_labs')
def __init__(self, labs_active=False):
self._registered_entries = collections.OrderedDict()
diff --git a/rhodecode/tests/functional/test_admin_settings.py b/rhodecode/apps/admin/tests/test_admin_settings.py
rename from rhodecode/tests/functional/test_admin_settings.py
rename to rhodecode/apps/admin/tests/test_admin_settings.py
--- a/rhodecode/tests/functional/test_admin_settings.py
+++ b/rhodecode/apps/admin/tests/test_admin_settings.py
@@ -27,7 +27,7 @@ from rhodecode.lib.utils2 import md5
from rhodecode.model.db import RhodeCodeUi
from rhodecode.model.meta import Session
from rhodecode.model.settings import SettingsModel, IssueTrackerSettingsModel
-from rhodecode.tests import url, assert_session_flash
+from rhodecode.tests import assert_session_flash
from rhodecode.tests.utils import AssertResponse
@@ -35,6 +35,78 @@ UPDATE_DATA_QUALNAME = (
'rhodecode.apps.admin.views.system_info.AdminSystemInfoSettingsView.get_update_data')
+def route_path(name, params=None, **kwargs):
+ import urllib
+ from rhodecode.apps._base import ADMIN_PREFIX
+
+ base_url = {
+
+ 'admin_settings':
+ ADMIN_PREFIX +'/settings',
+ 'admin_settings_update':
+ ADMIN_PREFIX + '/settings/update',
+ 'admin_settings_global':
+ ADMIN_PREFIX + '/settings/global',
+ 'admin_settings_global_update':
+ ADMIN_PREFIX + '/settings/global/update',
+ 'admin_settings_vcs':
+ ADMIN_PREFIX + '/settings/vcs',
+ 'admin_settings_vcs_update':
+ ADMIN_PREFIX + '/settings/vcs/update',
+ 'admin_settings_vcs_svn_pattern_delete':
+ ADMIN_PREFIX + '/settings/vcs/svn_pattern_delete',
+ 'admin_settings_mapping':
+ ADMIN_PREFIX + '/settings/mapping',
+ 'admin_settings_mapping_update':
+ ADMIN_PREFIX + '/settings/mapping/update',
+ 'admin_settings_visual':
+ ADMIN_PREFIX + '/settings/visual',
+ 'admin_settings_visual_update':
+ ADMIN_PREFIX + '/settings/visual/update',
+ 'admin_settings_issuetracker':
+ ADMIN_PREFIX + '/settings/issue-tracker',
+ 'admin_settings_issuetracker_update':
+ ADMIN_PREFIX + '/settings/issue-tracker/update',
+ 'admin_settings_issuetracker_test':
+ ADMIN_PREFIX + '/settings/issue-tracker/test',
+ 'admin_settings_issuetracker_delete':
+ ADMIN_PREFIX + '/settings/issue-tracker/delete',
+ 'admin_settings_email':
+ ADMIN_PREFIX + '/settings/email',
+ 'admin_settings_email_update':
+ ADMIN_PREFIX + '/settings/email/update',
+ 'admin_settings_hooks':
+ ADMIN_PREFIX + '/settings/hooks',
+ 'admin_settings_hooks_update':
+ ADMIN_PREFIX + '/settings/hooks/update',
+ 'admin_settings_hooks_delete':
+ ADMIN_PREFIX + '/settings/hooks/delete',
+ 'admin_settings_search':
+ ADMIN_PREFIX + '/settings/search',
+ 'admin_settings_labs':
+ ADMIN_PREFIX + '/settings/labs',
+ 'admin_settings_labs_update':
+ ADMIN_PREFIX + '/settings/labs/update',
+
+ 'admin_settings_sessions':
+ ADMIN_PREFIX + '/settings/sessions',
+ 'admin_settings_sessions_cleanup':
+ ADMIN_PREFIX + '/settings/sessions/cleanup',
+ 'admin_settings_system':
+ ADMIN_PREFIX + '/settings/system',
+ 'admin_settings_system_update':
+ ADMIN_PREFIX + '/settings/system/updates',
+ 'admin_settings_open_source':
+ ADMIN_PREFIX + '/settings/open_source',
+
+
+ }[name].format(**kwargs)
+
+ if params:
+ base_url = '{}?{}'.format(base_url, urllib.urlencode(params))
+ return base_url
+
+
@pytest.mark.usefixtures('autologin_user', 'app')
class TestAdminSettingsController(object):
@@ -47,12 +119,12 @@ class TestAdminSettingsController(object
'admin_settings_hooks',
'admin_settings_search',
])
- def test_simple_get(self, urlname, app):
- app.get(url(urlname))
+ def test_simple_get(self, urlname):
+ self.app.get(route_path(urlname))
def test_create_custom_hook(self, csrf_token):
response = self.app.post(
- url('admin_settings_hooks'),
+ route_path('admin_settings_hooks_update'),
params={
'new_hook_ui_key': 'test_hooks_1',
'new_hook_ui_value': 'cd /tmp',
@@ -64,7 +136,7 @@ class TestAdminSettingsController(object
def test_create_custom_hook_delete(self, csrf_token):
response = self.app.post(
- url('admin_settings_hooks'),
+ route_path('admin_settings_hooks_update'),
params={
'new_hook_ui_key': 'test_hooks_2',
'new_hook_ui_value': 'cd /tmp2',
@@ -78,9 +150,9 @@ class TestAdminSettingsController(object
# delete
self.app.post(
- url('admin_settings_hooks'),
+ route_path('admin_settings_hooks_delete'),
params={'hook_id': hook_id, 'csrf_token': csrf_token})
- response = self.app.get(url('admin_settings_hooks'))
+ response = self.app.get(route_path('admin_settings_hooks'))
response.mustcontain(no=['test_hooks_2'])
response.mustcontain(no=['cd /tmp2'])
@@ -135,7 +207,6 @@ class TestAdminSettingsGlobal(object):
def test_title_change(self, csrf_token):
old_title = 'RhodeCode'
- new_title = old_title + '_changed'
for new_title in ['Changed', 'Żółwik', old_title]:
response = self.post_and_verify_settings({
@@ -161,7 +232,8 @@ class TestAdminSettingsGlobal(object):
'rhodecode_personal_repo_group_pattern': '${username}',
}
params.update(settings)
- response = self.app.post(url('admin_settings_global'), params=params)
+ response = self.app.post(
+ route_path('admin_settings_global_update'), params=params)
assert_session_flash(response, 'Updated application settings')
app_settings = SettingsModel().get_all_settings()
@@ -175,8 +247,8 @@ class TestAdminSettingsGlobal(object):
@pytest.mark.usefixtures('autologin_user', 'app')
class TestAdminSettingsVcs(object):
- def test_contains_svn_default_patterns(self, app):
- response = app.get(url('admin_settings_vcs'))
+ def test_contains_svn_default_patterns(self):
+ response = self.app.get(route_path('admin_settings_vcs'))
expected_patterns = [
'/trunk',
'/branches/*',
@@ -186,7 +258,7 @@ class TestAdminSettingsVcs(object):
response.mustcontain(pattern)
def test_add_new_svn_branch_and_tag_pattern(
- self, app, backend_svn, form_defaults, disable_sql_cache,
+ self, backend_svn, form_defaults, disable_sql_cache,
csrf_token):
form_defaults.update({
'new_svn_branch': '/exp/branches/*',
@@ -194,8 +266,9 @@ class TestAdminSettingsVcs(object):
'csrf_token': csrf_token,
})
- response = app.post(
- url('admin_settings_vcs'), params=form_defaults, status=302)
+ response = self.app.post(
+ route_path('admin_settings_vcs_update'),
+ params=form_defaults, status=302)
response = response.follow()
# Expect to find the new values on the page
@@ -208,12 +281,12 @@ class TestAdminSettingsVcs(object):
assert 'important_tags/v0.5' in repo.tags
def test_add_same_svn_value_twice_shows_an_error_message(
- self, app, form_defaults, csrf_token, settings_util):
+ self, form_defaults, csrf_token, settings_util):
settings_util.create_rhodecode_ui('vcs_svn_branch', '/test')
settings_util.create_rhodecode_ui('vcs_svn_tag', '/test')
- response = app.post(
- url('admin_settings_vcs'),
+ response = self.app.post(
+ route_path('admin_settings_vcs_update'),
params={
'paths_root_path': form_defaults['paths_root_path'],
'new_svn_branch': '/test',
@@ -230,14 +303,13 @@ class TestAdminSettingsVcs(object):
'vcs_svn_tag',
])
def test_delete_svn_patterns(
- self, section, app, csrf_token, settings_util):
+ self, section, csrf_token, settings_util):
setting = settings_util.create_rhodecode_ui(
section, '/test_delete', cleanup=False)
- app.post(
- url('admin_settings_vcs'),
+ self.app.post(
+ route_path('admin_settings_vcs_svn_pattern_delete'),
params={
- '_method': 'delete',
'delete_svn_pattern': setting.ui_id,
'csrf_token': csrf_token},
headers={'X-REQUESTED-WITH': 'XMLHttpRequest'})
@@ -246,25 +318,24 @@ class TestAdminSettingsVcs(object):
'vcs_svn_branch',
'vcs_svn_tag',
])
- def test_delete_svn_patterns_raises_400_when_no_xhr(
- self, section, app, csrf_token, settings_util):
+ def test_delete_svn_patterns_raises_404_when_no_xhr(
+ self, section, csrf_token, settings_util):
setting = settings_util.create_rhodecode_ui(section, '/test_delete')
- app.post(
- url('admin_settings_vcs'),
+ self.app.post(
+ route_path('admin_settings_vcs_svn_pattern_delete'),
params={
- '_method': 'delete',
'delete_svn_pattern': setting.ui_id,
'csrf_token': csrf_token},
- status=400)
+ status=404)
- def test_extensions_hgsubversion(self, app, form_defaults, csrf_token):
+ def test_extensions_hgsubversion(self, form_defaults, csrf_token):
form_defaults.update({
'csrf_token': csrf_token,
'extensions_hgsubversion': 'True',
})
- response = app.post(
- url('admin_settings_vcs'),
+ response = self.app.post(
+ route_path('admin_settings_vcs_update'),
params=form_defaults,
status=302)
@@ -275,13 +346,13 @@ class TestAdminSettingsVcs(object):
'value="True" checked="checked" />')
response.mustcontain(extensions_input)
- def test_extensions_hgevolve(self, app, form_defaults, csrf_token):
+ def test_extensions_hgevolve(self, form_defaults, csrf_token):
form_defaults.update({
'csrf_token': csrf_token,
'extensions_evolve': 'True',
})
- response = app.post(
- url('admin_settings_vcs'),
+ response = self.app.post(
+ route_path('admin_settings_vcs_update'),
params=form_defaults,
status=302)
@@ -292,20 +363,19 @@ class TestAdminSettingsVcs(object):
'value="True" checked="checked" />')
response.mustcontain(extensions_input)
- def test_has_a_section_for_pull_request_settings(self, app):
- response = app.get(url('admin_settings_vcs'))
+ def test_has_a_section_for_pull_request_settings(self):
+ response = self.app.get(route_path('admin_settings_vcs'))
response.mustcontain('Pull Request Settings')
- def test_has_an_input_for_invalidation_of_inline_comments(
- self, app):
- response = app.get(url('admin_settings_vcs'))
+ def test_has_an_input_for_invalidation_of_inline_comments(self):
+ response = self.app.get(route_path('admin_settings_vcs'))
assert_response = AssertResponse(response)
assert_response.one_element_exists(
'[name=rhodecode_use_outdated_comments]')
@pytest.mark.parametrize('new_value', [True, False])
def test_allows_to_change_invalidation_of_inline_comments(
- self, app, form_defaults, csrf_token, new_value):
+ self, form_defaults, csrf_token, new_value):
setting_key = 'use_outdated_comments'
setting = SettingsModel().create_or_update_setting(
setting_key, not new_value, 'bool')
@@ -316,8 +386,8 @@ class TestAdminSettingsVcs(object):
'csrf_token': csrf_token,
'rhodecode_use_outdated_comments': str(new_value),
})
- response = app.post(
- url('admin_settings_vcs'),
+ response = self.app.post(
+ route_path('admin_settings_vcs_update'),
params=form_defaults,
status=302)
response = response.follow()
@@ -326,7 +396,7 @@ class TestAdminSettingsVcs(object):
@pytest.mark.parametrize('new_value', [True, False])
def test_allows_to_change_hg_rebase_merge_strategy(
- self, app, form_defaults, csrf_token, new_value):
+ self, form_defaults, csrf_token, new_value):
setting_key = 'hg_use_rebase_for_merging'
form_defaults.update({
@@ -336,8 +406,8 @@ class TestAdminSettingsVcs(object):
with mock.patch.dict(
rhodecode.CONFIG, {'labs_settings_active': 'true'}):
- app.post(
- url('admin_settings_vcs'),
+ self.app.post(
+ route_path('admin_settings_vcs_update'),
params=form_defaults,
status=302)
@@ -353,9 +423,8 @@ class TestAdminSettingsVcs(object):
@pytest.fixture
def form_defaults(self):
- from rhodecode.controllers.admin.settings import SettingsController
- controller = SettingsController()
- return controller._form_defaults()
+ from rhodecode.apps.admin.views.settings import AdminSettingsView
+ return AdminSettingsView._form_defaults()
# TODO: johbo: What we really want is to checkpoint before a test run and
# reset the session afterwards.
@@ -374,14 +443,16 @@ class TestAdminSettingsVcs(object):
@pytest.mark.usefixtures('autologin_user', 'app')
class TestLabsSettings(object):
def test_get_settings_page_disabled(self):
- with mock.patch.dict(rhodecode.CONFIG,
- {'labs_settings_active': 'false'}):
- response = self.app.get(url('admin_settings_labs'), status=302)
+ with mock.patch.dict(
+ rhodecode.CONFIG, {'labs_settings_active': 'false'}):
- assert response.location.endswith(url('admin_settings'))
+ response = self.app.get(
+ route_path('admin_settings_labs'), status=302)
+
+ assert response.location.endswith(route_path('admin_settings'))
def test_get_settings_page_enabled(self):
- from rhodecode.controllers.admin import settings
+ from rhodecode.apps.admin.views import settings
lab_settings = [
settings.LabSetting(
key='rhodecode_bool',
@@ -401,7 +472,7 @@ class TestLabsSettings(object):
with mock.patch.dict(rhodecode.CONFIG,
{'labs_settings_active': 'true'}):
with mock.patch.object(settings, '_LAB_SETTINGS', lab_settings):
- response = self.app.get(url('admin_settings_labs'))
+ response = self.app.get(route_path('admin_settings_labs'))
assert '' in response
assert '' in response
@@ -417,9 +488,6 @@ class TestLabsSettings(object):
@pytest.mark.usefixtures('app')
class TestOpenSourceLicenses(object):
- def _get_url(self):
- return ADMIN_PREFIX + '/settings/open_source'
-
def test_records_are_displayed(self, autologin_user):
sample_licenses = {
"python2.7-pytest-2.7.1": {
@@ -433,7 +501,8 @@ class TestOpenSourceLicenses(object):
'rhodecode.apps.admin.views.open_source_licenses.read_opensource_licenses',
return_value=sample_licenses)
with read_licenses_patch:
- response = self.app.get(self._get_url(), status=200)
+ response = self.app.get(
+ route_path('admin_settings_open_source'), status=200)
assert_response = AssertResponse(response)
assert_response.element_contains(
@@ -444,29 +513,25 @@ class TestOpenSourceLicenses(object):
assert_response.element_contains('.panel-body', license)
def test_records_can_be_read(self, autologin_user):
- response = self.app.get(self._get_url(), status=200)
+ response = self.app.get(
+ route_path('admin_settings_open_source'), status=200)
assert_response = AssertResponse(response)
assert_response.element_contains(
'.panel-heading', 'Licenses of Third Party Packages')
def test_forbidden_when_normal_user(self, autologin_regular_user):
- self.app.get(self._get_url(), status=404)
+ self.app.get(
+ route_path('admin_settings_open_source'), status=404)
@pytest.mark.usefixtures('app')
class TestUserSessions(object):
- def _get_url(self, name='admin_settings_sessions'):
- return {
- 'admin_settings_sessions': ADMIN_PREFIX + '/settings/sessions',
- 'admin_settings_sessions_cleanup': ADMIN_PREFIX + '/settings/sessions/cleanup'
- }[name]
-
def test_forbidden_when_normal_user(self, autologin_regular_user):
- self.app.get(self._get_url(), status=404)
+ self.app.get(route_path('admin_settings_sessions'), status=404)
def test_show_sessions_page(self, autologin_user):
- response = self.app.get(self._get_url(), status=200)
+ response = self.app.get(route_path('admin_settings_sessions'), status=200)
response.mustcontain('file')
def test_cleanup_old_sessions(self, autologin_user, csrf_token):
@@ -476,24 +541,19 @@ class TestUserSessions(object):
'expire_days': '60'
}
response = self.app.post(
- self._get_url('admin_settings_sessions_cleanup'), params=post_data,
+ route_path('admin_settings_sessions_cleanup'), params=post_data,
status=302)
assert_session_flash(response, 'Cleaned up old sessions')
@pytest.mark.usefixtures('app')
class TestAdminSystemInfo(object):
- def _get_url(self, name='admin_settings_system'):
- return {
- 'admin_settings_system': ADMIN_PREFIX + '/settings/system',
- 'admin_settings_system_update': ADMIN_PREFIX + '/settings/system/updates',
- }[name]
def test_forbidden_when_normal_user(self, autologin_regular_user):
- self.app.get(self._get_url(), status=404)
+ self.app.get(route_path('admin_settings_system'), status=404)
def test_system_info_page(self, autologin_user):
- response = self.app.get(self._get_url())
+ response = self.app.get(route_path('admin_settings_system'))
response.mustcontain('RhodeCode Community Edition, version {}'.format(
rhodecode.__version__))
@@ -511,7 +571,7 @@ class TestAdminSystemInfo(object):
]
}
with mock.patch(UPDATE_DATA_QUALNAME, return_value=update_data):
- response = self.app.get(self._get_url('admin_settings_system_update'))
+ response = self.app.get(route_path('admin_settings_system_update'))
response.mustcontain('A new version is available')
def test_system_update_nothing_new(self, autologin_user):
@@ -524,13 +584,13 @@ class TestAdminSystemInfo(object):
]
}
with mock.patch(UPDATE_DATA_QUALNAME, return_value=update_data):
- response = self.app.get(self._get_url('admin_settings_system_update'))
+ response = self.app.get(route_path('admin_settings_system_update'))
response.mustcontain(
'You already have the latest stable version.')
def test_system_update_bad_response(self, autologin_user):
with mock.patch(UPDATE_DATA_QUALNAME, side_effect=ValueError('foo')):
- response = self.app.get(self._get_url('admin_settings_system_update'))
+ response = self.app.get(route_path('admin_settings_system_update'))
response.mustcontain(
'Bad data sent from update server')
@@ -542,12 +602,12 @@ class TestAdminSettingsIssueTracker(obje
PATTERN_KEY = RC_PREFIX + SHORT_PATTERN_KEY
def test_issuetracker_index(self, autologin_user):
- response = self.app.get(url('admin_settings_issuetracker'))
+ response = self.app.get(route_path('admin_settings_issuetracker'))
assert response.status_code == 200
def test_add_empty_issuetracker_pattern(
self, request, autologin_user, csrf_token):
- post_url = url('admin_settings_issuetracker_save')
+ post_url = route_path('admin_settings_issuetracker_update')
post_data = {
'csrf_token': csrf_token
}
@@ -557,7 +617,7 @@ class TestAdminSettingsIssueTracker(obje
self, request, autologin_user, csrf_token):
pattern = 'issuetracker_pat'
another_pattern = pattern+'1'
- post_url = url('admin_settings_issuetracker_save')
+ post_url = route_path('admin_settings_issuetracker_update')
post_data = {
'new_pattern_pattern_0': pattern,
'new_pattern_url_0': 'url',
@@ -600,7 +660,7 @@ class TestAdminSettingsIssueTracker(obje
SettingsModel().create_or_update_setting(
self.SHORT_PATTERN_KEY+old_uid, old_pattern, 'unicode')
- post_url = url('admin_settings_issuetracker_save')
+ post_url = route_path('admin_settings_issuetracker_update')
post_data = {
'new_pattern_pattern_0': pattern,
'new_pattern_url_0': 'url',
@@ -634,7 +694,7 @@ class TestAdminSettingsIssueTracker(obje
settings_util.create_rhodecode_setting(
desc_key, 'old description', 'unicode', cleanup=False)
- post_url = url('admin_settings_issuetracker_save')
+ post_url = route_path('admin_settings_issuetracker_update')
post_data = {
'new_pattern_pattern_0': pattern,
'new_pattern_url_0': 'url',
@@ -659,7 +719,7 @@ class TestAdminSettingsIssueTracker(obje
settings_util.create_rhodecode_setting(
self.SHORT_PATTERN_KEY+uid, pattern, 'unicode', cleanup=False)
- post_url = url('admin_issuetracker_delete')
+ post_url = route_path('admin_settings_issuetracker_delete')
post_data = {
'_method': 'delete',
'uid': uid,
diff --git a/rhodecode/apps/admin/views/settings.py b/rhodecode/apps/admin/views/settings.py
new file mode 100644
--- /dev/null
+++ b/rhodecode/apps/admin/views/settings.py
@@ -0,0 +1,754 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (C) 2010-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
+# (only), as published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+# 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/
+
+
+import logging
+import collections
+
+import datetime
+import formencode
+import formencode.htmlfill
+
+import rhodecode
+from pyramid.view import view_config
+from pyramid.httpexceptions import HTTPFound, HTTPNotFound
+from pyramid.renderers import render
+from pyramid.response import Response
+
+from rhodecode.apps._base import BaseAppView
+from rhodecode.apps.admin.navigation import navigation_list
+from rhodecode.apps.svn_support.config_keys import generate_config
+from rhodecode.lib import helpers as h
+from rhodecode.lib.auth import (
+ LoginRequired, HasPermissionAllDecorator, CSRFRequired)
+from rhodecode.lib.celerylib import tasks, run_task
+from rhodecode.lib.utils import repo2db_mapper
+from rhodecode.lib.utils2 import str2bool, safe_unicode, AttributeDict
+from rhodecode.lib.index import searcher_from_config
+
+from rhodecode.model.db import RhodeCodeUi, Repository
+from rhodecode.model.forms import (ApplicationSettingsForm,
+ ApplicationUiSettingsForm, ApplicationVisualisationForm,
+ LabsSettingsForm, IssueTrackerPatternsForm)
+from rhodecode.model.repo_group import RepoGroupModel
+
+from rhodecode.model.scm import ScmModel
+from rhodecode.model.notification import EmailNotificationModel
+from rhodecode.model.meta import Session
+from rhodecode.model.settings import (
+ IssueTrackerSettingsModel, VcsSettingsModel, SettingNotFound,
+ SettingsModel)
+
+
+log = logging.getLogger(__name__)
+
+
+class AdminSettingsView(BaseAppView):
+
+ def load_default_context(self):
+ c = self._get_local_tmpl_context()
+ c.labs_active = str2bool(
+ rhodecode.CONFIG.get('labs_settings_active', 'true'))
+ c.navlist = navigation_list(self.request)
+ self._register_global_c(c)
+ return c
+
+ @classmethod
+ def _get_ui_settings(cls):
+ ret = RhodeCodeUi.query().all()
+
+ if not ret:
+ raise Exception('Could not get application ui settings !')
+ settings = {}
+ for each in ret:
+ k = each.ui_key
+ v = each.ui_value
+ if k == '/':
+ k = 'root_path'
+
+ if k in ['push_ssl', 'publish', 'enabled']:
+ v = str2bool(v)
+
+ if k.find('.') != -1:
+ k = k.replace('.', '_')
+
+ if each.ui_section in ['hooks', 'extensions']:
+ v = each.ui_active
+
+ settings[each.ui_section + '_' + k] = v
+ return settings
+
+ @classmethod
+ def _form_defaults(cls):
+ defaults = SettingsModel().get_all_settings()
+ defaults.update(cls._get_ui_settings())
+
+ defaults.update({
+ 'new_svn_branch': '',
+ 'new_svn_tag': '',
+ })
+ return defaults
+
+ @LoginRequired()
+ @HasPermissionAllDecorator('hg.admin')
+ @view_config(
+ route_name='admin_settings_vcs', request_method='GET',
+ renderer='rhodecode:templates/admin/settings/settings.mako')
+ def settings_vcs(self):
+ c = self.load_default_context()
+ c.active = 'vcs'
+ model = VcsSettingsModel()
+ c.svn_branch_patterns = model.get_global_svn_branch_patterns()
+ c.svn_tag_patterns = model.get_global_svn_tag_patterns()
+
+ settings = self.request.registry.settings
+ c.svn_proxy_generate_config = settings[generate_config]
+
+ defaults = self._form_defaults()
+
+ model.create_largeobjects_dirs_if_needed(defaults['paths_root_path'])
+
+ data = render('rhodecode:templates/admin/settings/settings.mako',
+ self._get_template_context(c), self.request)
+ html = formencode.htmlfill.render(
+ data,
+ defaults=defaults,
+ encoding="UTF-8",
+ force_defaults=False
+ )
+ return Response(html)
+
+ @LoginRequired()
+ @HasPermissionAllDecorator('hg.admin')
+ @CSRFRequired()
+ @view_config(
+ route_name='admin_settings_vcs_update', request_method='POST',
+ renderer='rhodecode:templates/admin/settings/settings.mako')
+ def settings_vcs_update(self):
+ _ = self.request.translate
+ c = self.load_default_context()
+ c.active = 'vcs'
+
+ model = VcsSettingsModel()
+ c.svn_branch_patterns = model.get_global_svn_branch_patterns()
+ c.svn_tag_patterns = model.get_global_svn_tag_patterns()
+
+ settings = self.request.registry.settings
+ c.svn_proxy_generate_config = settings[generate_config]
+
+ application_form = ApplicationUiSettingsForm()()
+
+ try:
+ form_result = application_form.to_python(dict(self.request.POST))
+ except formencode.Invalid as errors:
+ h.flash(
+ _("Some form inputs contain invalid data."),
+ category='error')
+ data = render('rhodecode:templates/admin/settings/settings.mako',
+ self._get_template_context(c), self.request)
+ html = formencode.htmlfill.render(
+ data,
+ defaults=errors.value,
+ errors=errors.error_dict or {},
+ prefix_error=False,
+ encoding="UTF-8",
+ force_defaults=False
+ )
+ return Response(html)
+
+ try:
+ if c.visual.allow_repo_location_change:
+ model.update_global_path_setting(
+ form_result['paths_root_path'])
+
+ model.update_global_ssl_setting(form_result['web_push_ssl'])
+ model.update_global_hook_settings(form_result)
+
+ model.create_or_update_global_svn_settings(form_result)
+ model.create_or_update_global_hg_settings(form_result)
+ model.create_or_update_global_git_settings(form_result)
+ model.create_or_update_global_pr_settings(form_result)
+ except Exception:
+ log.exception("Exception while updating settings")
+ h.flash(_('Error occurred during updating '
+ 'application settings'), category='error')
+ else:
+ Session().commit()
+ h.flash(_('Updated VCS settings'), category='success')
+ raise HTTPFound(h.route_path('admin_settings_vcs'))
+
+ data = render('rhodecode:templates/admin/settings/settings.mako',
+ self._get_template_context(c), self.request)
+ html = formencode.htmlfill.render(
+ data,
+ defaults=self._form_defaults(),
+ encoding="UTF-8",
+ force_defaults=False
+ )
+ return Response(html)
+
+ @LoginRequired()
+ @HasPermissionAllDecorator('hg.admin')
+ @CSRFRequired()
+ @view_config(
+ route_name='admin_settings_vcs_svn_pattern_delete', request_method='POST',
+ renderer='json_ext', xhr=True)
+ def settings_vcs_delete_svn_pattern(self):
+ delete_pattern_id = self.request.POST.get('delete_svn_pattern')
+ model = VcsSettingsModel()
+ try:
+ model.delete_global_svn_pattern(delete_pattern_id)
+ except SettingNotFound:
+ log.exception(
+ 'Failed to delete svn_pattern with id %s', delete_pattern_id)
+ raise HTTPNotFound()
+
+ Session().commit()
+ return True
+
+ @LoginRequired()
+ @HasPermissionAllDecorator('hg.admin')
+ @view_config(
+ route_name='admin_settings_mapping', request_method='GET',
+ renderer='rhodecode:templates/admin/settings/settings.mako')
+ def settings_mapping(self):
+ c = self.load_default_context()
+ c.active = 'mapping'
+
+ data = render('rhodecode:templates/admin/settings/settings.mako',
+ self._get_template_context(c), self.request)
+ html = formencode.htmlfill.render(
+ data,
+ defaults=self._form_defaults(),
+ encoding="UTF-8",
+ force_defaults=False
+ )
+ return Response(html)
+
+ @LoginRequired()
+ @HasPermissionAllDecorator('hg.admin')
+ @CSRFRequired()
+ @view_config(
+ route_name='admin_settings_mapping_update', request_method='POST',
+ renderer='rhodecode:templates/admin/settings/settings.mako')
+ def settings_mapping_update(self):
+ _ = self.request.translate
+ c = self.load_default_context()
+ c.active = 'mapping'
+ rm_obsolete = self.request.POST.get('destroy', False)
+ invalidate_cache = self.request.POST.get('invalidate', False)
+ log.debug(
+ 'rescanning repo location with destroy obsolete=%s', rm_obsolete)
+
+ if invalidate_cache:
+ log.debug('invalidating all repositories cache')
+ for repo in Repository.get_all():
+ ScmModel().mark_for_invalidation(repo.repo_name, delete=True)
+
+ filesystem_repos = ScmModel().repo_scan()
+ added, removed = repo2db_mapper(filesystem_repos, rm_obsolete)
+ _repr = lambda l: ', '.join(map(safe_unicode, l)) or '-'
+ h.flash(_('Repositories successfully '
+ 'rescanned added: %s ; removed: %s') %
+ (_repr(added), _repr(removed)),
+ category='success')
+ raise HTTPFound(h.route_path('admin_settings_mapping'))
+
+ @LoginRequired()
+ @HasPermissionAllDecorator('hg.admin')
+ @view_config(
+ route_name='admin_settings', request_method='GET',
+ renderer='rhodecode:templates/admin/settings/settings.mako')
+ @view_config(
+ route_name='admin_settings_global', request_method='GET',
+ renderer='rhodecode:templates/admin/settings/settings.mako')
+ def settings_global(self):
+ c = self.load_default_context()
+ c.active = 'global'
+ c.personal_repo_group_default_pattern = RepoGroupModel()\
+ .get_personal_group_name_pattern()
+
+ data = render('rhodecode:templates/admin/settings/settings.mako',
+ self._get_template_context(c), self.request)
+ html = formencode.htmlfill.render(
+ data,
+ defaults=self._form_defaults(),
+ encoding="UTF-8",
+ force_defaults=False
+ )
+ return Response(html)
+
+ @LoginRequired()
+ @HasPermissionAllDecorator('hg.admin')
+ @CSRFRequired()
+ @view_config(
+ route_name='admin_settings_update', request_method='POST',
+ renderer='rhodecode:templates/admin/settings/settings.mako')
+ @view_config(
+ route_name='admin_settings_global_update', request_method='POST',
+ renderer='rhodecode:templates/admin/settings/settings.mako')
+ def settings_global_update(self):
+ _ = self.request.translate
+ c = self.load_default_context()
+ c.active = 'global'
+ c.personal_repo_group_default_pattern = RepoGroupModel()\
+ .get_personal_group_name_pattern()
+ application_form = ApplicationSettingsForm()()
+ try:
+ form_result = application_form.to_python(dict(self.request.POST))
+ except formencode.Invalid as errors:
+ data = render('rhodecode:templates/admin/settings/settings.mako',
+ self._get_template_context(c), self.request)
+ html = formencode.htmlfill.render(
+ data,
+ defaults=errors.value,
+ errors=errors.error_dict or {},
+ prefix_error=False,
+ encoding="UTF-8",
+ force_defaults=False
+ )
+ return Response(html)
+
+ settings = [
+ ('title', 'rhodecode_title', 'unicode'),
+ ('realm', 'rhodecode_realm', 'unicode'),
+ ('pre_code', 'rhodecode_pre_code', 'unicode'),
+ ('post_code', 'rhodecode_post_code', 'unicode'),
+ ('captcha_public_key', 'rhodecode_captcha_public_key', 'unicode'),
+ ('captcha_private_key', 'rhodecode_captcha_private_key', 'unicode'),
+ ('create_personal_repo_group', 'rhodecode_create_personal_repo_group', 'bool'),
+ ('personal_repo_group_pattern', 'rhodecode_personal_repo_group_pattern', 'unicode'),
+ ]
+ try:
+ for setting, form_key, type_ in settings:
+ sett = SettingsModel().create_or_update_setting(
+ setting, form_result[form_key], type_)
+ Session().add(sett)
+
+ Session().commit()
+ SettingsModel().invalidate_settings_cache()
+ h.flash(_('Updated application settings'), category='success')
+ except Exception:
+ log.exception("Exception while updating application settings")
+ h.flash(
+ _('Error occurred during updating application settings'),
+ category='error')
+
+ raise HTTPFound(h.route_path('admin_settings_global'))
+
+ @LoginRequired()
+ @HasPermissionAllDecorator('hg.admin')
+ @view_config(
+ route_name='admin_settings_visual', request_method='GET',
+ renderer='rhodecode:templates/admin/settings/settings.mako')
+ def settings_visual(self):
+ c = self.load_default_context()
+ c.active = 'visual'
+
+ data = render('rhodecode:templates/admin/settings/settings.mako',
+ self._get_template_context(c), self.request)
+ html = formencode.htmlfill.render(
+ data,
+ defaults=self._form_defaults(),
+ encoding="UTF-8",
+ force_defaults=False
+ )
+ return Response(html)
+
+ @LoginRequired()
+ @HasPermissionAllDecorator('hg.admin')
+ @CSRFRequired()
+ @view_config(
+ route_name='admin_settings_visual_update', request_method='POST',
+ renderer='rhodecode:templates/admin/settings/settings.mako')
+ def settings_visual_update(self):
+ _ = self.request.translate
+ c = self.load_default_context()
+ c.active = 'visual'
+ application_form = ApplicationVisualisationForm()()
+ try:
+ form_result = application_form.to_python(dict(self.request.POST))
+ except formencode.Invalid as errors:
+ data = render('rhodecode:templates/admin/settings/settings.mako',
+ self._get_template_context(c), self.request)
+ html = formencode.htmlfill.render(
+ data,
+ defaults=errors.value,
+ errors=errors.error_dict or {},
+ prefix_error=False,
+ encoding="UTF-8",
+ force_defaults=False
+ )
+ return Response(html)
+
+ try:
+ settings = [
+ ('show_public_icon', 'rhodecode_show_public_icon', 'bool'),
+ ('show_private_icon', 'rhodecode_show_private_icon', 'bool'),
+ ('stylify_metatags', 'rhodecode_stylify_metatags', 'bool'),
+ ('repository_fields', 'rhodecode_repository_fields', 'bool'),
+ ('dashboard_items', 'rhodecode_dashboard_items', 'int'),
+ ('admin_grid_items', 'rhodecode_admin_grid_items', 'int'),
+ ('show_version', 'rhodecode_show_version', 'bool'),
+ ('use_gravatar', 'rhodecode_use_gravatar', 'bool'),
+ ('markup_renderer', 'rhodecode_markup_renderer', 'unicode'),
+ ('gravatar_url', 'rhodecode_gravatar_url', 'unicode'),
+ ('clone_uri_tmpl', 'rhodecode_clone_uri_tmpl', 'unicode'),
+ ('support_url', 'rhodecode_support_url', 'unicode'),
+ ('show_revision_number', 'rhodecode_show_revision_number', 'bool'),
+ ('show_sha_length', 'rhodecode_show_sha_length', 'int'),
+ ]
+ for setting, form_key, type_ in settings:
+ sett = SettingsModel().create_or_update_setting(
+ setting, form_result[form_key], type_)
+ Session().add(sett)
+
+ Session().commit()
+ SettingsModel().invalidate_settings_cache()
+ h.flash(_('Updated visualisation settings'), category='success')
+ except Exception:
+ log.exception("Exception updating visualization settings")
+ h.flash(_('Error occurred during updating '
+ 'visualisation settings'),
+ category='error')
+
+ raise HTTPFound(h.route_path('admin_settings_visual'))
+
+ @LoginRequired()
+ @HasPermissionAllDecorator('hg.admin')
+ @view_config(
+ route_name='admin_settings_issuetracker', request_method='GET',
+ renderer='rhodecode:templates/admin/settings/settings.mako')
+ def settings_issuetracker(self):
+ c = self.load_default_context()
+ c.active = 'issuetracker'
+ defaults = SettingsModel().get_all_settings()
+
+ entry_key = 'rhodecode_issuetracker_pat_'
+
+ c.issuetracker_entries = {}
+ for k, v in defaults.items():
+ if k.startswith(entry_key):
+ uid = k[len(entry_key):]
+ c.issuetracker_entries[uid] = None
+
+ for uid in c.issuetracker_entries:
+ c.issuetracker_entries[uid] = AttributeDict({
+ 'pat': defaults.get('rhodecode_issuetracker_pat_' + uid),
+ 'url': defaults.get('rhodecode_issuetracker_url_' + uid),
+ 'pref': defaults.get('rhodecode_issuetracker_pref_' + uid),
+ 'desc': defaults.get('rhodecode_issuetracker_desc_' + uid),
+ })
+
+ return self._get_template_context(c)
+
+ @LoginRequired()
+ @HasPermissionAllDecorator('hg.admin')
+ @CSRFRequired()
+ @view_config(
+ route_name='admin_settings_issuetracker_test', request_method='POST',
+ renderer='string', xhr=True)
+ def settings_issuetracker_test(self):
+ return h.urlify_commit_message(
+ self.request.POST.get('test_text', ''),
+ 'repo_group/test_repo1')
+
+ @LoginRequired()
+ @HasPermissionAllDecorator('hg.admin')
+ @CSRFRequired()
+ @view_config(
+ route_name='admin_settings_issuetracker_update', request_method='POST',
+ renderer='rhodecode:templates/admin/settings/settings.mako')
+ def settings_issuetracker_update(self):
+ _ = self.request.translate
+ self.load_default_context()
+ settings_model = IssueTrackerSettingsModel()
+
+ form = IssueTrackerPatternsForm()().to_python(self.request.POST)
+ if form:
+ for uid in form.get('delete_patterns', []):
+ settings_model.delete_entries(uid)
+
+ for pattern in form.get('patterns', []):
+ for setting, value, type_ in pattern:
+ sett = settings_model.create_or_update_setting(
+ setting, value, type_)
+ Session().add(sett)
+
+ Session().commit()
+
+ SettingsModel().invalidate_settings_cache()
+ h.flash(_('Updated issue tracker entries'), category='success')
+ raise HTTPFound(h.route_path('admin_settings_issuetracker'))
+
+ @LoginRequired()
+ @HasPermissionAllDecorator('hg.admin')
+ @CSRFRequired()
+ @view_config(
+ route_name='admin_settings_issuetracker_delete', request_method='POST',
+ renderer='rhodecode:templates/admin/settings/settings.mako')
+ def settings_issuetracker_delete(self):
+ _ = self.request.translate
+ self.load_default_context()
+ uid = self.request.POST.get('uid')
+ try:
+ IssueTrackerSettingsModel().delete_entries(uid)
+ except Exception:
+ log.exception('Failed to delete issue tracker setting %s', uid)
+ raise HTTPNotFound()
+ h.flash(_('Removed issue tracker entry'), category='success')
+ raise HTTPFound(h.route_path('admin_settings_issuetracker'))
+
+ @LoginRequired()
+ @HasPermissionAllDecorator('hg.admin')
+ @view_config(
+ route_name='admin_settings_email', request_method='GET',
+ renderer='rhodecode:templates/admin/settings/settings.mako')
+ def settings_email(self):
+ c = self.load_default_context()
+ c.active = 'email'
+ c.rhodecode_ini = rhodecode.CONFIG
+
+ data = render('rhodecode:templates/admin/settings/settings.mako',
+ self._get_template_context(c), self.request)
+ html = formencode.htmlfill.render(
+ data,
+ defaults=self._form_defaults(),
+ encoding="UTF-8",
+ force_defaults=False
+ )
+ return Response(html)
+
+ @LoginRequired()
+ @HasPermissionAllDecorator('hg.admin')
+ @CSRFRequired()
+ @view_config(
+ route_name='admin_settings_email_update', request_method='POST',
+ renderer='rhodecode:templates/admin/settings/settings.mako')
+ def settings_email_update(self):
+ _ = self.request.translate
+ c = self.load_default_context()
+ c.active = 'email'
+
+ test_email = self.request.POST.get('test_email')
+
+ if not test_email:
+ h.flash(_('Please enter email address'), category='error')
+ raise HTTPFound(h.route_path('admin_settings_email'))
+
+ email_kwargs = {
+ 'date': datetime.datetime.now(),
+ 'user': c.rhodecode_user,
+ 'rhodecode_version': c.rhodecode_version
+ }
+
+ (subject, headers, email_body,
+ email_body_plaintext) = EmailNotificationModel().render_email(
+ EmailNotificationModel.TYPE_EMAIL_TEST, **email_kwargs)
+
+ recipients = [test_email] if test_email else None
+
+ run_task(tasks.send_email, recipients, subject,
+ email_body_plaintext, email_body)
+
+ h.flash(_('Send email task created'), category='success')
+ raise HTTPFound(h.route_path('admin_settings_email'))
+
+ @LoginRequired()
+ @HasPermissionAllDecorator('hg.admin')
+ @view_config(
+ route_name='admin_settings_hooks', request_method='GET',
+ renderer='rhodecode:templates/admin/settings/settings.mako')
+ def settings_hooks(self):
+ c = self.load_default_context()
+ c.active = 'hooks'
+
+ model = SettingsModel()
+ c.hooks = model.get_builtin_hooks()
+ c.custom_hooks = model.get_custom_hooks()
+
+ data = render('rhodecode:templates/admin/settings/settings.mako',
+ self._get_template_context(c), self.request)
+ html = formencode.htmlfill.render(
+ data,
+ defaults=self._form_defaults(),
+ encoding="UTF-8",
+ force_defaults=False
+ )
+ return Response(html)
+
+ @LoginRequired()
+ @HasPermissionAllDecorator('hg.admin')
+ @CSRFRequired()
+ @view_config(
+ route_name='admin_settings_hooks_update', request_method='POST',
+ renderer='rhodecode:templates/admin/settings/settings.mako')
+ @view_config(
+ route_name='admin_settings_hooks_delete', request_method='POST',
+ renderer='rhodecode:templates/admin/settings/settings.mako')
+ def settings_hooks_update(self):
+ _ = self.request.translate
+ c = self.load_default_context()
+ c.active = 'hooks'
+ if c.visual.allow_custom_hooks_settings:
+ ui_key = self.request.POST.get('new_hook_ui_key')
+ ui_value = self.request.POST.get('new_hook_ui_value')
+
+ hook_id = self.request.POST.get('hook_id')
+ new_hook = False
+
+ model = SettingsModel()
+ try:
+ if ui_value and ui_key:
+ model.create_or_update_hook(ui_key, ui_value)
+ h.flash(_('Added new hook'), category='success')
+ new_hook = True
+ elif hook_id:
+ RhodeCodeUi.delete(hook_id)
+ Session().commit()
+
+ # check for edits
+ update = False
+ _d = self.request.POST.dict_of_lists()
+ for k, v in zip(_d.get('hook_ui_key', []),
+ _d.get('hook_ui_value_new', [])):
+ model.create_or_update_hook(k, v)
+ update = True
+
+ if update and not new_hook:
+ h.flash(_('Updated hooks'), category='success')
+ Session().commit()
+ except Exception:
+ log.exception("Exception during hook creation")
+ h.flash(_('Error occurred during hook creation'),
+ category='error')
+
+ raise HTTPFound(h.route_path('admin_settings_hooks'))
+
+ @LoginRequired()
+ @HasPermissionAllDecorator('hg.admin')
+ @view_config(
+ route_name='admin_settings_search', request_method='GET',
+ renderer='rhodecode:templates/admin/settings/settings.mako')
+ def settings_search(self):
+ c = self.load_default_context()
+ c.active = 'search'
+
+ searcher = searcher_from_config(self.request.registry.settings)
+ c.statistics = searcher.statistics()
+
+ return self._get_template_context(c)
+
+ @LoginRequired()
+ @HasPermissionAllDecorator('hg.admin')
+ @view_config(
+ route_name='admin_settings_labs', request_method='GET',
+ renderer='rhodecode:templates/admin/settings/settings.mako')
+ def settings_labs(self):
+ c = self.load_default_context()
+ if not c.labs_active:
+ raise HTTPFound(h.route_path('admin_settings'))
+
+ c.active = 'labs'
+ c.lab_settings = _LAB_SETTINGS
+
+ data = render('rhodecode:templates/admin/settings/settings.mako',
+ self._get_template_context(c), self.request)
+ html = formencode.htmlfill.render(
+ data,
+ defaults=self._form_defaults(),
+ encoding="UTF-8",
+ force_defaults=False
+ )
+ return Response(html)
+
+ @LoginRequired()
+ @HasPermissionAllDecorator('hg.admin')
+ @CSRFRequired()
+ @view_config(
+ route_name='admin_settings_labs_update', request_method='POST',
+ renderer='rhodecode:templates/admin/settings/settings.mako')
+ def settings_labs_update(self):
+ _ = self.request.translate
+ c = self.load_default_context()
+ c.active = 'labs'
+
+ application_form = LabsSettingsForm()()
+ try:
+ form_result = application_form.to_python(dict(self.request.POST))
+ except formencode.Invalid as errors:
+ h.flash(
+ _('Some form inputs contain invalid data.'),
+ category='error')
+ data = render('rhodecode:templates/admin/settings/settings.mako',
+ self._get_template_context(c), self.request)
+ html = formencode.htmlfill.render(
+ data,
+ defaults=errors.value,
+ errors=errors.error_dict or {},
+ prefix_error=False,
+ encoding="UTF-8",
+ force_defaults=False
+ )
+ return Response(html)
+
+ try:
+ session = Session()
+ for setting in _LAB_SETTINGS:
+ setting_name = setting.key[len('rhodecode_'):]
+ sett = SettingsModel().create_or_update_setting(
+ setting_name, form_result[setting.key], setting.type)
+ session.add(sett)
+
+ except Exception:
+ log.exception('Exception while updating lab settings')
+ h.flash(_('Error occurred during updating labs settings'),
+ category='error')
+ else:
+ Session().commit()
+ SettingsModel().invalidate_settings_cache()
+ h.flash(_('Updated Labs settings'), category='success')
+ raise HTTPFound(h.route_path('admin_settings_labs'))
+
+ data = render('rhodecode:templates/admin/settings/settings.mako',
+ self._get_template_context(c), self.request)
+ html = formencode.htmlfill.render(
+ data,
+ defaults=self._form_defaults(),
+ encoding="UTF-8",
+ force_defaults=False
+ )
+ return Response(html)
+
+
+# :param key: name of the setting including the 'rhodecode_' prefix
+# :param type: the RhodeCodeSetting type to use.
+# :param group: the i18ned group in which we should dispaly this setting
+# :param label: the i18ned label we should display for this setting
+# :param help: the i18ned help we should dispaly for this setting
+LabSetting = collections.namedtuple(
+ 'LabSetting', ('key', 'type', 'group', 'label', 'help'))
+
+
+# This list has to be kept in sync with the form
+# rhodecode.model.forms.LabsSettingsForm.
+_LAB_SETTINGS = [
+
+]
diff --git a/rhodecode/config/routing.py b/rhodecode/config/routing.py
--- a/rhodecode/config/routing.py
+++ b/rhodecode/config/routing.py
@@ -172,81 +172,6 @@ def make_map(config):
# CUSTOM ROUTES HERE
#==========================================================================
- # ADMIN SETTINGS ROUTES
- with rmap.submapper(path_prefix=ADMIN_PREFIX,
- controller='admin/settings') as m:
-
- # default
- m.connect('admin_settings', '/settings',
- action='settings_global_update',
- conditions={'method': ['POST']})
- m.connect('admin_settings', '/settings',
- action='settings_global', conditions={'method': ['GET']})
-
- m.connect('admin_settings_vcs', '/settings/vcs',
- action='settings_vcs_update',
- conditions={'method': ['POST']})
- m.connect('admin_settings_vcs', '/settings/vcs',
- action='settings_vcs',
- conditions={'method': ['GET']})
- m.connect('admin_settings_vcs', '/settings/vcs',
- action='delete_svn_pattern',
- conditions={'method': ['DELETE']})
-
- m.connect('admin_settings_mapping', '/settings/mapping',
- action='settings_mapping_update',
- conditions={'method': ['POST']})
- m.connect('admin_settings_mapping', '/settings/mapping',
- action='settings_mapping', conditions={'method': ['GET']})
-
- m.connect('admin_settings_global', '/settings/global',
- action='settings_global_update',
- conditions={'method': ['POST']})
- m.connect('admin_settings_global', '/settings/global',
- action='settings_global', conditions={'method': ['GET']})
-
- m.connect('admin_settings_visual', '/settings/visual',
- action='settings_visual_update',
- conditions={'method': ['POST']})
- m.connect('admin_settings_visual', '/settings/visual',
- action='settings_visual', conditions={'method': ['GET']})
-
- m.connect('admin_settings_issuetracker',
- '/settings/issue-tracker', action='settings_issuetracker',
- conditions={'method': ['GET']})
- m.connect('admin_settings_issuetracker_save',
- '/settings/issue-tracker/save',
- action='settings_issuetracker_save',
- conditions={'method': ['POST']})
- m.connect('admin_issuetracker_test', '/settings/issue-tracker/test',
- action='settings_issuetracker_test',
- conditions={'method': ['POST']})
- m.connect('admin_issuetracker_delete',
- '/settings/issue-tracker/delete',
- action='settings_issuetracker_delete',
- conditions={'method': ['DELETE']})
-
- m.connect('admin_settings_email', '/settings/email',
- action='settings_email_update',
- conditions={'method': ['POST']})
- m.connect('admin_settings_email', '/settings/email',
- action='settings_email', conditions={'method': ['GET']})
-
- m.connect('admin_settings_hooks', '/settings/hooks',
- action='settings_hooks_update',
- conditions={'method': ['POST', 'DELETE']})
- m.connect('admin_settings_hooks', '/settings/hooks',
- action='settings_hooks', conditions={'method': ['GET']})
-
- m.connect('admin_settings_search', '/settings/search',
- action='settings_search', conditions={'method': ['GET']})
-
- m.connect('admin_settings_labs', '/settings/labs',
- action='settings_labs_update',
- conditions={'method': ['POST']})
- m.connect('admin_settings_labs', '/settings/labs',
- action='settings_labs', conditions={'method': ['GET']})
-
# ADMIN MY ACCOUNT
with rmap.submapper(path_prefix=ADMIN_PREFIX,
controller='admin/my_account') as m:
diff --git a/rhodecode/controllers/admin/__init__.py b/rhodecode/controllers/admin/__init__.py
deleted file mode 100644
--- a/rhodecode/controllers/admin/__init__.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (C) 2010-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
-# (only), as published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see .
-#
-# 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/
diff --git a/rhodecode/controllers/admin/settings.py b/rhodecode/controllers/admin/settings.py
deleted file mode 100644
--- a/rhodecode/controllers/admin/settings.py
+++ /dev/null
@@ -1,631 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (C) 2010-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
-# (only), as published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see .
-#
-# 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/
-
-
-"""
-settings controller for rhodecode admin
-"""
-
-import collections
-import logging
-
-import datetime
-import formencode
-from formencode import htmlfill
-from pylons import request, tmpl_context as c, url, config
-from pylons.controllers.util import redirect
-from pylons.i18n.translation import _
-from pylons.decorators import jsonify
-from pyramid.threadlocal import get_current_registry
-from webob.exc import HTTPBadRequest
-
-import rhodecode
-from rhodecode.apps.admin.navigation import navigation_list
-from rhodecode.apps.svn_support.config_keys import generate_config
-from rhodecode.lib import auth
-from rhodecode.lib import helpers as h
-from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator
-from rhodecode.lib.base import BaseController, render
-from rhodecode.lib.celerylib import tasks, run_task
-from rhodecode.lib.utils import repo2db_mapper
-from rhodecode.lib.utils2 import (
- str2bool, safe_unicode, AttributeDict, safe_int)
-
-from rhodecode.model.db import RhodeCodeUi, Repository
-from rhodecode.model.forms import ApplicationSettingsForm, \
- ApplicationUiSettingsForm, ApplicationVisualisationForm, \
- LabsSettingsForm, IssueTrackerPatternsForm
-from rhodecode.model.repo_group import RepoGroupModel
-
-from rhodecode.model.scm import ScmModel
-from rhodecode.model.notification import EmailNotificationModel
-from rhodecode.model.meta import Session
-from rhodecode.model.settings import (
- IssueTrackerSettingsModel, VcsSettingsModel, SettingNotFound,
- SettingsModel)
-
-
-log = logging.getLogger(__name__)
-
-
-class SettingsController(BaseController):
- """REST Controller styled on the Atom Publishing Protocol"""
- # To properly map this controller, ensure your config/routing.py
- # file has a resource setup:
- # map.resource('setting', 'settings', controller='admin/settings',
- # path_prefix='/admin', name_prefix='admin_')
-
- @LoginRequired()
- def __before__(self):
- super(SettingsController, self).__before__()
- c.labs_active = str2bool(
- rhodecode.CONFIG.get('labs_settings_active', 'true'))
- c.navlist = navigation_list(request)
-
- def _get_ui_settings(self):
- ret = RhodeCodeUi.query().all()
-
- if not ret:
- raise Exception('Could not get application ui settings !')
- settings = {}
- for each in ret:
- k = each.ui_key
- v = each.ui_value
- if k == '/':
- k = 'root_path'
-
- if k in ['push_ssl', 'publish', 'enabled']:
- v = str2bool(v)
-
- if k.find('.') != -1:
- k = k.replace('.', '_')
-
- if each.ui_section in ['hooks', 'extensions']:
- v = each.ui_active
-
- settings[each.ui_section + '_' + k] = v
- return settings
-
- @HasPermissionAllDecorator('hg.admin')
- @auth.CSRFRequired()
- @jsonify
- def delete_svn_pattern(self):
- if not request.is_xhr:
- raise HTTPBadRequest()
-
- delete_pattern_id = request.POST.get('delete_svn_pattern')
- model = VcsSettingsModel()
- try:
- model.delete_global_svn_pattern(delete_pattern_id)
- except SettingNotFound:
- raise HTTPBadRequest()
-
- Session().commit()
- return True
-
- @HasPermissionAllDecorator('hg.admin')
- @auth.CSRFRequired()
- def settings_vcs_update(self):
- """POST /admin/settings: All items in the collection"""
- # url('admin_settings_vcs')
- c.active = 'vcs'
-
- model = VcsSettingsModel()
- c.svn_branch_patterns = model.get_global_svn_branch_patterns()
- c.svn_tag_patterns = model.get_global_svn_tag_patterns()
-
- # TODO: Replace with request.registry after migrating to pyramid.
- pyramid_settings = get_current_registry().settings
- c.svn_proxy_generate_config = pyramid_settings[generate_config]
-
- application_form = ApplicationUiSettingsForm()()
-
- try:
- form_result = application_form.to_python(dict(request.POST))
- except formencode.Invalid as errors:
- h.flash(
- _("Some form inputs contain invalid data."),
- category='error')
- return htmlfill.render(
- render('admin/settings/settings.mako'),
- defaults=errors.value,
- errors=errors.error_dict or {},
- prefix_error=False,
- encoding="UTF-8",
- force_defaults=False
- )
-
- try:
- if c.visual.allow_repo_location_change:
- model.update_global_path_setting(
- form_result['paths_root_path'])
-
- model.update_global_ssl_setting(form_result['web_push_ssl'])
- model.update_global_hook_settings(form_result)
-
- model.create_or_update_global_svn_settings(form_result)
- model.create_or_update_global_hg_settings(form_result)
- model.create_or_update_global_git_settings(form_result)
- model.create_or_update_global_pr_settings(form_result)
- except Exception:
- log.exception("Exception while updating settings")
- h.flash(_('Error occurred during updating '
- 'application settings'), category='error')
- else:
- Session().commit()
- h.flash(_('Updated VCS settings'), category='success')
- return redirect(url('admin_settings_vcs'))
-
- return htmlfill.render(
- render('admin/settings/settings.mako'),
- defaults=self._form_defaults(),
- encoding="UTF-8",
- force_defaults=False)
-
- @HasPermissionAllDecorator('hg.admin')
- def settings_vcs(self):
- """GET /admin/settings: All items in the collection"""
- # url('admin_settings_vcs')
- c.active = 'vcs'
- model = VcsSettingsModel()
- c.svn_branch_patterns = model.get_global_svn_branch_patterns()
- c.svn_tag_patterns = model.get_global_svn_tag_patterns()
-
- # TODO: Replace with request.registry after migrating to pyramid.
- pyramid_settings = get_current_registry().settings
- c.svn_proxy_generate_config = pyramid_settings[generate_config]
-
- defaults = self._form_defaults()
-
- model.create_largeobjects_dirs_if_needed(defaults['paths_root_path'])
- return htmlfill.render(
- render('admin/settings/settings.mako'),
- defaults=defaults,
- encoding="UTF-8",
- force_defaults=False)
-
- @HasPermissionAllDecorator('hg.admin')
- @auth.CSRFRequired()
- def settings_mapping_update(self):
- """POST /admin/settings/mapping: All items in the collection"""
- # url('admin_settings_mapping')
- c.active = 'mapping'
- rm_obsolete = request.POST.get('destroy', False)
- invalidate_cache = request.POST.get('invalidate', False)
- log.debug(
- 'rescanning repo location with destroy obsolete=%s', rm_obsolete)
-
- if invalidate_cache:
- log.debug('invalidating all repositories cache')
- for repo in Repository.get_all():
- ScmModel().mark_for_invalidation(repo.repo_name, delete=True)
-
- filesystem_repos = ScmModel().repo_scan()
- added, removed = repo2db_mapper(filesystem_repos, rm_obsolete)
- _repr = lambda l: ', '.join(map(safe_unicode, l)) or '-'
- h.flash(_('Repositories successfully '
- 'rescanned added: %s ; removed: %s') %
- (_repr(added), _repr(removed)),
- category='success')
- return redirect(url('admin_settings_mapping'))
-
- @HasPermissionAllDecorator('hg.admin')
- def settings_mapping(self):
- """GET /admin/settings/mapping: All items in the collection"""
- # url('admin_settings_mapping')
- c.active = 'mapping'
-
- return htmlfill.render(
- render('admin/settings/settings.mako'),
- defaults=self._form_defaults(),
- encoding="UTF-8",
- force_defaults=False)
-
- @HasPermissionAllDecorator('hg.admin')
- @auth.CSRFRequired()
- def settings_global_update(self):
- """POST /admin/settings/global: All items in the collection"""
- # url('admin_settings_global')
- c.active = 'global'
- c.personal_repo_group_default_pattern = RepoGroupModel()\
- .get_personal_group_name_pattern()
- application_form = ApplicationSettingsForm()()
- try:
- form_result = application_form.to_python(dict(request.POST))
- except formencode.Invalid as errors:
- return htmlfill.render(
- render('admin/settings/settings.mako'),
- defaults=errors.value,
- errors=errors.error_dict or {},
- prefix_error=False,
- encoding="UTF-8",
- force_defaults=False)
-
- try:
- settings = [
- ('title', 'rhodecode_title', 'unicode'),
- ('realm', 'rhodecode_realm', 'unicode'),
- ('pre_code', 'rhodecode_pre_code', 'unicode'),
- ('post_code', 'rhodecode_post_code', 'unicode'),
- ('captcha_public_key', 'rhodecode_captcha_public_key', 'unicode'),
- ('captcha_private_key', 'rhodecode_captcha_private_key', 'unicode'),
- ('create_personal_repo_group', 'rhodecode_create_personal_repo_group', 'bool'),
- ('personal_repo_group_pattern', 'rhodecode_personal_repo_group_pattern', 'unicode'),
- ]
- for setting, form_key, type_ in settings:
- sett = SettingsModel().create_or_update_setting(
- setting, form_result[form_key], type_)
- Session().add(sett)
-
- Session().commit()
- SettingsModel().invalidate_settings_cache()
- h.flash(_('Updated application settings'), category='success')
- except Exception:
- log.exception("Exception while updating application settings")
- h.flash(
- _('Error occurred during updating application settings'),
- category='error')
-
- return redirect(url('admin_settings_global'))
-
- @HasPermissionAllDecorator('hg.admin')
- def settings_global(self):
- """GET /admin/settings/global: All items in the collection"""
- # url('admin_settings_global')
- c.active = 'global'
- c.personal_repo_group_default_pattern = RepoGroupModel()\
- .get_personal_group_name_pattern()
-
- return htmlfill.render(
- render('admin/settings/settings.mako'),
- defaults=self._form_defaults(),
- encoding="UTF-8",
- force_defaults=False)
-
- @HasPermissionAllDecorator('hg.admin')
- @auth.CSRFRequired()
- def settings_visual_update(self):
- """POST /admin/settings/visual: All items in the collection"""
- # url('admin_settings_visual')
- c.active = 'visual'
- application_form = ApplicationVisualisationForm()()
- try:
- form_result = application_form.to_python(dict(request.POST))
- except formencode.Invalid as errors:
- return htmlfill.render(
- render('admin/settings/settings.mako'),
- defaults=errors.value,
- errors=errors.error_dict or {},
- prefix_error=False,
- encoding="UTF-8",
- force_defaults=False
- )
-
- try:
- settings = [
- ('show_public_icon', 'rhodecode_show_public_icon', 'bool'),
- ('show_private_icon', 'rhodecode_show_private_icon', 'bool'),
- ('stylify_metatags', 'rhodecode_stylify_metatags', 'bool'),
- ('repository_fields', 'rhodecode_repository_fields', 'bool'),
- ('dashboard_items', 'rhodecode_dashboard_items', 'int'),
- ('admin_grid_items', 'rhodecode_admin_grid_items', 'int'),
- ('show_version', 'rhodecode_show_version', 'bool'),
- ('use_gravatar', 'rhodecode_use_gravatar', 'bool'),
- ('markup_renderer', 'rhodecode_markup_renderer', 'unicode'),
- ('gravatar_url', 'rhodecode_gravatar_url', 'unicode'),
- ('clone_uri_tmpl', 'rhodecode_clone_uri_tmpl', 'unicode'),
- ('support_url', 'rhodecode_support_url', 'unicode'),
- ('show_revision_number', 'rhodecode_show_revision_number', 'bool'),
- ('show_sha_length', 'rhodecode_show_sha_length', 'int'),
- ]
- for setting, form_key, type_ in settings:
- sett = SettingsModel().create_or_update_setting(
- setting, form_result[form_key], type_)
- Session().add(sett)
-
- Session().commit()
- SettingsModel().invalidate_settings_cache()
- h.flash(_('Updated visualisation settings'), category='success')
- except Exception:
- log.exception("Exception updating visualization settings")
- h.flash(_('Error occurred during updating '
- 'visualisation settings'),
- category='error')
-
- return redirect(url('admin_settings_visual'))
-
- @HasPermissionAllDecorator('hg.admin')
- def settings_visual(self):
- """GET /admin/settings/visual: All items in the collection"""
- # url('admin_settings_visual')
- c.active = 'visual'
-
- return htmlfill.render(
- render('admin/settings/settings.mako'),
- defaults=self._form_defaults(),
- encoding="UTF-8",
- force_defaults=False)
-
- @HasPermissionAllDecorator('hg.admin')
- @auth.CSRFRequired()
- def settings_issuetracker_test(self):
- if request.is_xhr:
- return h.urlify_commit_message(
- request.POST.get('test_text', ''),
- 'repo_group/test_repo1')
- else:
- raise HTTPBadRequest()
-
- @HasPermissionAllDecorator('hg.admin')
- @auth.CSRFRequired()
- def settings_issuetracker_delete(self):
- uid = request.POST.get('uid')
- IssueTrackerSettingsModel().delete_entries(uid)
- h.flash(_('Removed issue tracker entry'), category='success')
- return redirect(url('admin_settings_issuetracker'))
-
- @HasPermissionAllDecorator('hg.admin')
- def settings_issuetracker(self):
- """GET /admin/settings/issue-tracker: All items in the collection"""
- # url('admin_settings_issuetracker')
- c.active = 'issuetracker'
- defaults = SettingsModel().get_all_settings()
-
- entry_key = 'rhodecode_issuetracker_pat_'
-
- c.issuetracker_entries = {}
- for k, v in defaults.items():
- if k.startswith(entry_key):
- uid = k[len(entry_key):]
- c.issuetracker_entries[uid] = None
-
- for uid in c.issuetracker_entries:
- c.issuetracker_entries[uid] = AttributeDict({
- 'pat': defaults.get('rhodecode_issuetracker_pat_' + uid),
- 'url': defaults.get('rhodecode_issuetracker_url_' + uid),
- 'pref': defaults.get('rhodecode_issuetracker_pref_' + uid),
- 'desc': defaults.get('rhodecode_issuetracker_desc_' + uid),
- })
-
- return render('admin/settings/settings.mako')
-
- @HasPermissionAllDecorator('hg.admin')
- @auth.CSRFRequired()
- def settings_issuetracker_save(self):
- settings_model = IssueTrackerSettingsModel()
-
- form = IssueTrackerPatternsForm()().to_python(request.POST)
- if form:
- for uid in form.get('delete_patterns', []):
- settings_model.delete_entries(uid)
-
- for pattern in form.get('patterns', []):
- for setting, value, type_ in pattern:
- sett = settings_model.create_or_update_setting(
- setting, value, type_)
- Session().add(sett)
-
- Session().commit()
-
- SettingsModel().invalidate_settings_cache()
- h.flash(_('Updated issue tracker entries'), category='success')
- return redirect(url('admin_settings_issuetracker'))
-
- @HasPermissionAllDecorator('hg.admin')
- @auth.CSRFRequired()
- def settings_email_update(self):
- """POST /admin/settings/email: All items in the collection"""
- # url('admin_settings_email')
- c.active = 'email'
-
- test_email = request.POST.get('test_email')
-
- if not test_email:
- h.flash(_('Please enter email address'), category='error')
- return redirect(url('admin_settings_email'))
-
- email_kwargs = {
- 'date': datetime.datetime.now(),
- 'user': c.rhodecode_user,
- 'rhodecode_version': c.rhodecode_version
- }
-
- (subject, headers, email_body,
- email_body_plaintext) = EmailNotificationModel().render_email(
- EmailNotificationModel.TYPE_EMAIL_TEST, **email_kwargs)
-
- recipients = [test_email] if test_email else None
-
- run_task(tasks.send_email, recipients, subject,
- email_body_plaintext, email_body)
-
- h.flash(_('Send email task created'), category='success')
- return redirect(url('admin_settings_email'))
-
- @HasPermissionAllDecorator('hg.admin')
- def settings_email(self):
- """GET /admin/settings/email: All items in the collection"""
- # url('admin_settings_email')
- c.active = 'email'
- c.rhodecode_ini = rhodecode.CONFIG
-
- return htmlfill.render(
- render('admin/settings/settings.mako'),
- defaults=self._form_defaults(),
- encoding="UTF-8",
- force_defaults=False)
-
- @HasPermissionAllDecorator('hg.admin')
- @auth.CSRFRequired()
- def settings_hooks_update(self):
- """POST or DELETE /admin/settings/hooks: All items in the collection"""
- # url('admin_settings_hooks')
- c.active = 'hooks'
- if c.visual.allow_custom_hooks_settings:
- ui_key = request.POST.get('new_hook_ui_key')
- ui_value = request.POST.get('new_hook_ui_value')
-
- hook_id = request.POST.get('hook_id')
- new_hook = False
-
- model = SettingsModel()
- try:
- if ui_value and ui_key:
- model.create_or_update_hook(ui_key, ui_value)
- h.flash(_('Added new hook'), category='success')
- new_hook = True
- elif hook_id:
- RhodeCodeUi.delete(hook_id)
- Session().commit()
-
- # check for edits
- update = False
- _d = request.POST.dict_of_lists()
- for k, v in zip(_d.get('hook_ui_key', []),
- _d.get('hook_ui_value_new', [])):
- model.create_or_update_hook(k, v)
- update = True
-
- if update and not new_hook:
- h.flash(_('Updated hooks'), category='success')
- Session().commit()
- except Exception:
- log.exception("Exception during hook creation")
- h.flash(_('Error occurred during hook creation'),
- category='error')
-
- return redirect(url('admin_settings_hooks'))
-
- @HasPermissionAllDecorator('hg.admin')
- def settings_hooks(self):
- """GET /admin/settings/hooks: All items in the collection"""
- # url('admin_settings_hooks')
- c.active = 'hooks'
-
- model = SettingsModel()
- c.hooks = model.get_builtin_hooks()
- c.custom_hooks = model.get_custom_hooks()
-
- return htmlfill.render(
- render('admin/settings/settings.mako'),
- defaults=self._form_defaults(),
- encoding="UTF-8",
- force_defaults=False)
-
- @HasPermissionAllDecorator('hg.admin')
- def settings_search(self):
- """GET /admin/settings/search: All items in the collection"""
- # url('admin_settings_search')
- c.active = 'search'
-
- from rhodecode.lib.index import searcher_from_config
- searcher = searcher_from_config(config)
- c.statistics = searcher.statistics()
-
- return render('admin/settings/settings.mako')
-
- @HasPermissionAllDecorator('hg.admin')
- @auth.CSRFRequired()
- def settings_labs_update(self):
- """POST /admin/settings/labs: All items in the collection"""
- # url('admin_settings/labs', method={'POST'})
- c.active = 'labs'
-
- application_form = LabsSettingsForm()()
- try:
- form_result = application_form.to_python(dict(request.POST))
- except formencode.Invalid as errors:
- h.flash(
- _('Some form inputs contain invalid data.'),
- category='error')
- return htmlfill.render(
- render('admin/settings/settings.mako'),
- defaults=errors.value,
- errors=errors.error_dict or {},
- prefix_error=False,
- encoding='UTF-8',
- force_defaults=False
- )
-
- try:
- session = Session()
- for setting in _LAB_SETTINGS:
- setting_name = setting.key[len('rhodecode_'):]
- sett = SettingsModel().create_or_update_setting(
- setting_name, form_result[setting.key], setting.type)
- session.add(sett)
-
- except Exception:
- log.exception('Exception while updating lab settings')
- h.flash(_('Error occurred during updating labs settings'),
- category='error')
- else:
- Session().commit()
- SettingsModel().invalidate_settings_cache()
- h.flash(_('Updated Labs settings'), category='success')
- return redirect(url('admin_settings_labs'))
-
- return htmlfill.render(
- render('admin/settings/settings.mako'),
- defaults=self._form_defaults(),
- encoding='UTF-8',
- force_defaults=False)
-
- @HasPermissionAllDecorator('hg.admin')
- def settings_labs(self):
- """GET /admin/settings/labs: All items in the collection"""
- # url('admin_settings_labs')
- if not c.labs_active:
- redirect(url('admin_settings'))
-
- c.active = 'labs'
- c.lab_settings = _LAB_SETTINGS
-
- return htmlfill.render(
- render('admin/settings/settings.mako'),
- defaults=self._form_defaults(),
- encoding='UTF-8',
- force_defaults=False)
-
- def _form_defaults(self):
- defaults = SettingsModel().get_all_settings()
- defaults.update(self._get_ui_settings())
-
- defaults.update({
- 'new_svn_branch': '',
- 'new_svn_tag': '',
- })
- return defaults
-
-
-# :param key: name of the setting including the 'rhodecode_' prefix
-# :param type: the RhodeCodeSetting type to use.
-# :param group: the i18ned group in which we should dispaly this setting
-# :param label: the i18ned label we should display for this setting
-# :param help: the i18ned help we should dispaly for this setting
-LabSetting = collections.namedtuple(
- 'LabSetting', ('key', 'type', 'group', 'label', 'help'))
-
-
-# This list has to be kept in sync with the form
-# rhodecode.model.forms.LabsSettingsForm.
-_LAB_SETTINGS = [
-
-]
diff --git a/rhodecode/public/js/rhodecode/routes.js b/rhodecode/public/js/rhodecode/routes.js
--- a/rhodecode/public/js/rhodecode/routes.js
+++ b/rhodecode/public/js/rhodecode/routes.js
@@ -51,6 +51,29 @@ function registerRCRoutes() {
pyroutes.register('admin_settings_process_management_signal', '/_admin/settings/process_management/signal', []);
pyroutes.register('admin_defaults_repositories', '/_admin/defaults/repositories', []);
pyroutes.register('admin_defaults_repositories_update', '/_admin/defaults/repositories/update', []);
+ pyroutes.register('admin_settings', '/_admin/settings', []);
+ pyroutes.register('admin_settings_update', '/_admin/settings/update', []);
+ pyroutes.register('admin_settings_global', '/_admin/settings/global', []);
+ pyroutes.register('admin_settings_global_update', '/_admin/settings/global/update', []);
+ pyroutes.register('admin_settings_vcs', '/_admin/settings/vcs', []);
+ pyroutes.register('admin_settings_vcs_update', '/_admin/settings/vcs/update', []);
+ pyroutes.register('admin_settings_vcs_svn_pattern_delete', '/_admin/settings/vcs/svn_pattern_delete', []);
+ pyroutes.register('admin_settings_mapping', '/_admin/settings/mapping', []);
+ pyroutes.register('admin_settings_mapping_update', '/_admin/settings/mapping/update', []);
+ pyroutes.register('admin_settings_visual', '/_admin/settings/visual', []);
+ pyroutes.register('admin_settings_visual_update', '/_admin/settings/visual/update', []);
+ pyroutes.register('admin_settings_issuetracker', '/_admin/settings/issue-tracker', []);
+ pyroutes.register('admin_settings_issuetracker_update', '/_admin/settings/issue-tracker/update', []);
+ pyroutes.register('admin_settings_issuetracker_test', '/_admin/settings/issue-tracker/test', []);
+ pyroutes.register('admin_settings_issuetracker_delete', '/_admin/settings/issue-tracker/delete', []);
+ pyroutes.register('admin_settings_email', '/_admin/settings/email', []);
+ pyroutes.register('admin_settings_email_update', '/_admin/settings/email/update', []);
+ pyroutes.register('admin_settings_hooks', '/_admin/settings/hooks', []);
+ pyroutes.register('admin_settings_hooks_update', '/_admin/settings/hooks/update', []);
+ pyroutes.register('admin_settings_hooks_delete', '/_admin/settings/hooks/delete', []);
+ pyroutes.register('admin_settings_search', '/_admin/settings/search', []);
+ pyroutes.register('admin_settings_labs', '/_admin/settings/labs', []);
+ pyroutes.register('admin_settings_labs_update', '/_admin/settings/labs/update', []);
pyroutes.register('admin_permissions_application', '/_admin/permissions/application', []);
pyroutes.register('admin_permissions_application_update', '/_admin/permissions/application/update', []);
pyroutes.register('admin_permissions_global', '/_admin/permissions/global', []);
diff --git a/rhodecode/templates/admin/integrations/form.mako b/rhodecode/templates/admin/integrations/form.mako
--- a/rhodecode/templates/admin/integrations/form.mako
+++ b/rhodecode/templates/admin/integrations/form.mako
@@ -27,7 +27,7 @@
%else:
${h.link_to(_('Admin'),h.route_path('admin_home'))}
»
- ${h.link_to(_('Settings'),h.url('admin_settings'))}
+ ${h.link_to(_('Settings'),h.route_path('admin_settings'))}
»
${h.link_to(_('Integrations'),request.route_url(route_name='global_integrations_home'))}
»
diff --git a/rhodecode/templates/admin/integrations/list.mako b/rhodecode/templates/admin/integrations/list.mako
--- a/rhodecode/templates/admin/integrations/list.mako
+++ b/rhodecode/templates/admin/integrations/list.mako
@@ -13,7 +13,7 @@
%else:
${h.link_to(_('Admin'),h.route_path('admin_home'))}
»
- ${h.link_to(_('Settings'),h.url('admin_settings'))}
+ ${h.link_to(_('Settings'),h.route_path('admin_settings'))}
%endif
%if c.current_IntegrationType:
»
diff --git a/rhodecode/templates/admin/integrations/new.mako b/rhodecode/templates/admin/integrations/new.mako
--- a/rhodecode/templates/admin/integrations/new.mako
+++ b/rhodecode/templates/admin/integrations/new.mako
@@ -18,7 +18,7 @@
%else:
${h.link_to(_('Admin'),h.route_path('admin_home'))}
»
- ${h.link_to(_('Settings'),h.url('admin_settings'))}
+ ${h.link_to(_('Settings'),h.route_path('admin_settings'))}
»
${h.link_to(_('Integrations'),request.route_url(route_name='global_integrations_home'))}
%endif
diff --git a/rhodecode/templates/admin/repos/repo_add_base.mako b/rhodecode/templates/admin/repos/repo_add_base.mako
--- a/rhodecode/templates/admin/repos/repo_add_base.mako
+++ b/rhodecode/templates/admin/repos/repo_add_base.mako
@@ -33,7 +33,7 @@
add authentication information to the URL: https://username:password@server.company.com/repo-name.
- The Git LFS/Mercurial Largefiles objects will not be imported.
- For very large repositories, it's recommended to manually copy them into the
- RhodeCode storage location and run Remap and Rescan.
+ RhodeCode storage location and run Remap and Rescan.
diff --git a/rhodecode/templates/admin/settings/settings_email.mako b/rhodecode/templates/admin/settings/settings_email.mako
--- a/rhodecode/templates/admin/settings/settings_email.mako
+++ b/rhodecode/templates/admin/settings/settings_email.mako
@@ -34,7 +34,7 @@
${_('Test Email')}
- ${h.secure_form(h.url('admin_settings_email'), request=request)}
+ ${h.secure_form(h.route_path('admin_settings_email_update'), request=request)}