diff --git a/rhodecode/apps/_base/__init__.py b/rhodecode/apps/_base/__init__.py
--- a/rhodecode/apps/_base/__init__.py
+++ b/rhodecode/apps/_base/__init__.py
@@ -42,8 +42,8 @@ from rhodecode.model.repo import ReadmeF
log = logging.getLogger(__name__)
-ADMIN_PREFIX = '/_admin'
-STATIC_FILE_PREFIX = '/_static'
+ADMIN_PREFIX: str = '/_admin'
+STATIC_FILE_PREFIX: str = '/_static'
URL_NAME_REQUIREMENTS = {
# group name can have a slash in them, but they must not end with a slash
diff --git a/rhodecode/apps/_base/navigation.py b/rhodecode/apps/_base/navigation.py
--- a/rhodecode/apps/_base/navigation.py
+++ b/rhodecode/apps/_base/navigation.py
@@ -101,8 +101,6 @@ class NavigationRegistry(object):
'admin_settings_sessions'),
NavEntry('open_source', _('Open Source Licenses'),
'admin_settings_open_source'),
- NavEntry('automation', _('Automation'),
- 'admin_settings_automation')
]
_labs_entry = NavEntry('labs', _('Labs'),
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
@@ -18,6 +18,8 @@
from rhodecode.apps._base import ADMIN_PREFIX
+from rhodecode.apps._base.navigation import includeme as nav_includeme
+from rhodecode.apps.admin.views.main_views import AdminMainView
def admin_routes(config):
@@ -26,9 +28,10 @@ def admin_routes(config):
"""
from rhodecode.apps.admin.views.audit_logs import AdminAuditLogsView
from rhodecode.apps.admin.views.artifacts import AdminArtifactsView
+ from rhodecode.apps.admin.views.automation import AdminAutomationView
+ from rhodecode.apps.admin.views.scheduler import AdminSchedulerView
from rhodecode.apps.admin.views.defaults import AdminDefaultSettingsView
from rhodecode.apps.admin.views.exception_tracker import ExceptionsTrackerView
- from rhodecode.apps.admin.views.main_views import AdminMainView
from rhodecode.apps.admin.views.open_source_licenses import OpenSourceLicensesAdminSettingsView
from rhodecode.apps.admin.views.permissions import AdminPermissionsView
from rhodecode.apps.admin.views.process_management import AdminProcessManagementView
@@ -76,6 +79,7 @@ def admin_routes(config):
attr='artifacts',
route_name='admin_artifacts_show_all', request_method='GET',
renderer='rhodecode:templates/admin/artifacts/artifacts.mako')
+
# EE views
config.add_route(
name='admin_artifacts_show_info',
@@ -87,6 +91,26 @@ def admin_routes(config):
name='admin_artifacts_update',
pattern=ADMIN_PREFIX + '/artifacts/{uid}/update')
+ # Automation EE feature
+ config.add_route(
+ 'admin_automation',
+ pattern=ADMIN_PREFIX + '/automation')
+ config.add_view(
+ AdminAutomationView,
+ attr='automation',
+ route_name='admin_automation', request_method='GET',
+ renderer='rhodecode:templates/admin/automation/automation.mako')
+
+ # Scheduler EE feature
+ config.add_route(
+ 'admin_scheduler',
+ pattern=ADMIN_PREFIX + '/scheduler')
+ config.add_view(
+ AdminSchedulerView,
+ attr='scheduler',
+ route_name='admin_scheduler', request_method='GET',
+ renderer='rhodecode:templates/admin/scheduler/scheduler.mako')
+
config.add_route(
name='admin_settings_open_source',
pattern='/settings/open_source')
@@ -440,16 +464,6 @@ def admin_routes(config):
route_name='admin_settings_labs_update', request_method='POST',
renderer='rhodecode:templates/admin/settings/settings.mako')
- # Automation EE feature
- config.add_route(
- 'admin_settings_automation',
- pattern=ADMIN_PREFIX + '/settings/automation')
- config.add_view(
- AdminSettingsView,
- attr='settings_automation',
- route_name='admin_settings_automation', request_method='GET',
- renderer='rhodecode:templates/admin/settings/settings.mako')
-
# global permissions
config.add_route(
@@ -1039,9 +1053,6 @@ def admin_routes(config):
def includeme(config):
- from rhodecode.apps._base.navigation import includeme as nav_includeme
- from rhodecode.apps.admin.views.main_views import AdminMainView
-
# Create admin navigation registry and add it to the pyramid registry.
nav_includeme(config)
diff --git a/rhodecode/apps/admin/views/automation.py b/rhodecode/apps/admin/views/automation.py
new file mode 100644
--- /dev/null
+++ b/rhodecode/apps/admin/views/automation.py
@@ -0,0 +1,38 @@
+# Copyright (C) 2016-2023 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
+
+from rhodecode.apps._base import BaseAppView
+from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator
+
+log = logging.getLogger(__name__)
+
+
+class AdminAutomationView(BaseAppView):
+
+ def load_default_context(self):
+ c = self._get_local_tmpl_context()
+ return c
+
+ @LoginRequired()
+ @HasPermissionAllDecorator('hg.admin')
+ def automation(self):
+ c = self.load_default_context()
+ c.active = 'automation'
+ return self._get_template_context(c)
diff --git a/rhodecode/apps/admin/views/scheduler.py b/rhodecode/apps/admin/views/scheduler.py
new file mode 100644
--- /dev/null
+++ b/rhodecode/apps/admin/views/scheduler.py
@@ -0,0 +1,38 @@
+# Copyright (C) 2016-2023 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
+
+from rhodecode.apps._base import BaseAppView
+from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator
+
+log = logging.getLogger(__name__)
+
+
+class AdminSchedulerView(BaseAppView):
+
+ def load_default_context(self):
+ c = self._get_local_tmpl_context()
+ return c
+
+ @LoginRequired()
+ @HasPermissionAllDecorator('hg.admin')
+ def scheduler(self):
+ c = self.load_default_context()
+ c.active = 'scheduler'
+ return self._get_template_context(c)
diff --git a/rhodecode/apps/admin/views/settings.py b/rhodecode/apps/admin/views/settings.py
--- a/rhodecode/apps/admin/views/settings.py
+++ b/rhodecode/apps/admin/views/settings.py
@@ -248,8 +248,9 @@ class AdminSettingsView(BaseAppView):
added, removed = repo2db_mapper(filesystem_repos, rm_obsolete)
PermissionModel().trigger_permission_flush()
- def _repr(l):
- return ', '.join(map(safe_str, l)) or '-'
+ def _repr(rm_repo):
+ return ', '.join(map(safe_str, rm_repo)) or '-'
+
h.flash(_('Repositories successfully '
'rescanned added: %s ; removed: %s') %
(_repr(added), _repr(removed)),
@@ -623,14 +624,6 @@ class AdminSettingsView(BaseAppView):
@LoginRequired()
@HasPermissionAllDecorator('hg.admin')
- def settings_automation(self):
- c = self.load_default_context()
- c.active = 'automation'
-
- return self._get_template_context(c)
-
- @LoginRequired()
- @HasPermissionAllDecorator('hg.admin')
def settings_labs(self):
c = self.load_default_context()
if not c.labs_active:
diff --git a/rhodecode/apps/repository/views/repo_files.py b/rhodecode/apps/repository/views/repo_files.py
--- a/rhodecode/apps/repository/views/repo_files.py
+++ b/rhodecode/apps/repository/views/repo_files.py
@@ -413,6 +413,7 @@ class RepoFilesView(RepoAppView):
archive_cache_disable = self.request.GET.get('no_cache')
d_cache = get_archival_cache_store(config=CONFIG)
+
# NOTE: we get the config to pass to a call to lazy-init the SAME type of cache on vcsserver
d_cache_conf = get_archival_config(config=CONFIG)
diff --git a/rhodecode/events/pullrequest.py b/rhodecode/events/pullrequest.py
--- a/rhodecode/events/pullrequest.py
+++ b/rhodecode/events/pullrequest.py
@@ -30,6 +30,9 @@ class PullRequestEvent(RepoEvent):
:param pullrequest: a :class:`PullRequest` instance
"""
+ name = 'pullrequest-event'
+ display_name = lazy_ugettext('pullrequest generic event')
+ description = lazy_ugettext('All events within a context of a pull request')
def __init__(self, pullrequest):
super().__init__(pullrequest.target_repo)
diff --git a/rhodecode/events/repo.py b/rhodecode/events/repo.py
--- a/rhodecode/events/repo.py
+++ b/rhodecode/events/repo.py
@@ -21,7 +21,7 @@ import logging
import datetime
from rhodecode.translation import lazy_ugettext
-from rhodecode.model.db import User, Repository, Session
+from rhodecode.model.db import User, Repository
from rhodecode.events.base import RhodeCodeIntegrationEvent
from rhodecode.lib.vcs.exceptions import CommitDoesNotExistError
@@ -34,7 +34,7 @@ def _commits_as_dict(event, commit_ids,
:param event: class calling this method
:param commit_ids: commits to get
- :param repos: list of repos to check
+ :param repos: a list of repos to check
"""
from rhodecode.lib.utils2 import extract_mentioned_users
from rhodecode.lib.helpers import (
@@ -154,11 +154,12 @@ def _issues_as_dict(commits):
class RepoEvent(RhodeCodeIntegrationEvent):
"""
Base class for events acting on a repository.
-
- :param repo: a :class:`Repository` instance
"""
def __init__(self, repo):
+ """
+ :param repo: a :class:`Repository` instance
+ """
super().__init__()
self.repo = repo
@@ -299,6 +300,9 @@ class RepoVCSEvent(RepoEvent):
"""
Base class for events triggered by the VCS
"""
+ name = ''
+ display_name = 'generic_vcs_event'
+
def __init__(self, repo_name, extras):
self.repo = Repository.get_by_repo_name(repo_name)
if not self.repo:
diff --git a/rhodecode/lib/celerylib/__init__.py b/rhodecode/lib/celerylib/__init__.py
--- a/rhodecode/lib/celerylib/__init__.py
+++ b/rhodecode/lib/celerylib/__init__.py
@@ -44,7 +44,7 @@ def run_task(task, *args, **kwargs):
import celery
log.debug('Got task `%s` for execution, celery mode enabled:%s', task, rhodecode.CELERY_ENABLED)
if task is None:
- raise ValueError('Got non-existing task for execution')
+ raise ValueError(f'Got non-existing task: {task} for execution')
exec_mode = 'sync'
allow_async = True
diff --git a/rhodecode/lib/jsonalchemy.py b/rhodecode/lib/jsonalchemy.py
--- a/rhodecode/lib/jsonalchemy.py
+++ b/rhodecode/lib/jsonalchemy.py
@@ -19,9 +19,7 @@
import sqlalchemy
from sqlalchemy import UnicodeText
-from sqlalchemy.ext.mutable import Mutable, \
- MutableList as MutationList, \
- MutableDict as MutationDict
+from sqlalchemy.ext.mutable import Mutable, MutableList, MutableDict
from rhodecode.lib import ext_json
@@ -30,7 +28,7 @@ class JsonRaw(str):
"""
Allows interacting with a JSON types field using a raw string.
- For example::
+ For example:
db_instance = JsonTable()
db_instance.enabled = True
db_instance.json_data = JsonRaw('{"a": 4}')
@@ -100,7 +98,7 @@ class MutationObj(Mutable):
return MutationList.coerce(key, value)
return value
- def de_coerce(self):
+ def de_coerce(self) -> "MutationObj":
return self
@classmethod
@@ -153,6 +151,16 @@ class MutationObj(Mutable):
propagate=True)
+class MutationList(MutableList):
+ def de_coerce(self):
+ return list(self)
+
+
+class MutationDict(MutableDict):
+ def de_coerce(self):
+ return dict(self)
+
+
def JsonType(impl=None, **kwargs):
"""
Helper for using a mutation obj, it allows to use .with_variant easily.
diff --git a/rhodecode/model/db.py b/rhodecode/model/db.py
--- a/rhodecode/model/db.py
+++ b/rhodecode/model/db.py
@@ -5378,14 +5378,14 @@ class ScheduleEntry(Base, BaseModel):
except ValueError:
return dict()
- def _as_raw(self, val, indent=None):
+ def _as_raw(self, val, indent=False):
if hasattr(val, 'de_coerce'):
val = val.de_coerce()
if val:
if indent:
- ext_json.formatted_json(val)
+ val = ext_json.formatted_str_json(val)
else:
- val = ext_json.json.dumps(val)
+ val = ext_json.str_json(val)
return val
@@ -5393,10 +5393,10 @@ class ScheduleEntry(Base, BaseModel):
def schedule_definition_raw(self):
return self._as_raw(self.schedule_definition)
- def args_raw(self, indent=None):
+ def args_raw(self, indent=False):
return self._as_raw(self.task_args, indent)
- def kwargs_raw(self, indent=None):
+ def kwargs_raw(self, indent=False):
return self._as_raw(self.task_kwargs, indent)
def __repr__(self):
@@ -5610,6 +5610,19 @@ class FileStore(Base, BaseModel):
repo_group = relationship('RepoGroup', lazy='joined')
@classmethod
+ def get_scope(cls, scope_type, scope_id):
+ if scope_type == 'repo':
+ return f'repo:{scope_id}'
+ elif scope_type == 'repo-group':
+ return f'repo-group:{scope_id}'
+ elif scope_type == 'user':
+ return f'user:{scope_id}'
+ elif scope_type == 'user-group':
+ return f'user-group:{scope_id}'
+ else:
+ return scope_type
+
+ @classmethod
def get_by_store_uid(cls, file_store_uid, safe=False):
if safe:
return FileStore.query().filter(FileStore.file_uid == file_store_uid).first()
diff --git a/rhodecode/model/validation_schema/validators.py b/rhodecode/model/validation_schema/validators.py
--- a/rhodecode/model/validation_schema/validators.py
+++ b/rhodecode/model/validation_schema/validators.py
@@ -25,7 +25,7 @@ import colander
from rhodecode.translation import _
from rhodecode.lib.utils2 import glob2re
from rhodecode.lib.str_utils import safe_str
-from rhodecode.lib.ext_json import json
+from rhodecode.lib.ext_json import json, sjson
log = logging.getLogger(__name__)
@@ -152,8 +152,9 @@ def json_validator(node, value):
def json_validator_with_exc(node, value):
+
try:
json.loads(value)
except (Exception,) as e:
- msg = _(f'Please enter a valid json object: `{e}`')
+ msg = _(f'Please enter a valid json object type={type(value)}: `{e}`')
raise colander.Invalid(node, msg)
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
@@ -20,6 +20,8 @@ function registerRCRoutes() {
pyroutes.register('admin_artifacts_update', '/_admin/artifacts/%(uid)s/update', ['uid']);
pyroutes.register('admin_audit_log_entry', '/_admin/audit_logs/%(audit_log_id)s', ['audit_log_id']);
pyroutes.register('admin_audit_logs', '/_admin/audit_logs', []);
+ pyroutes.register('admin_automation', '/_admin/automation', []);
+ pyroutes.register('admin_automation_update', '/_admin/automation/%(entry_id)s/update', ['entry_id']);
pyroutes.register('admin_defaults_repositories', '/_admin/defaults/repositories', []);
pyroutes.register('admin_defaults_repositories_update', '/_admin/defaults/repositories/update', []);
pyroutes.register('admin_home', '/_admin', []);
@@ -37,9 +39,9 @@ function registerRCRoutes() {
pyroutes.register('admin_permissions_ssh_keys', '/_admin/permissions/ssh_keys', []);
pyroutes.register('admin_permissions_ssh_keys_data', '/_admin/permissions/ssh_keys/data', []);
pyroutes.register('admin_permissions_ssh_keys_update', '/_admin/permissions/ssh_keys/update', []);
+ pyroutes.register('admin_scheduler', '/_admin/scheduler', []);
+ pyroutes.register('admin_scheduler_show_tasks', '/_admin/scheduler/_tasks', []);
pyroutes.register('admin_settings', '/_admin/settings', []);
- pyroutes.register('admin_settings_automation', '/_admin/settings/automation', []);
- pyroutes.register('admin_settings_automation_update', '/_admin/settings/automation/%(entry_id)s/update', ['entry_id']);
pyroutes.register('admin_settings_email', '/_admin/settings/email', []);
pyroutes.register('admin_settings_email_update', '/_admin/settings/email/update', []);
pyroutes.register('admin_settings_exception_tracker', '/_admin/settings/exceptions', []);
@@ -66,14 +68,12 @@ function registerRCRoutes() {
pyroutes.register('admin_settings_process_management_data', '/_admin/settings/process_management/data', []);
pyroutes.register('admin_settings_process_management_master_signal', '/_admin/settings/process_management/master_signal', []);
pyroutes.register('admin_settings_process_management_signal', '/_admin/settings/process_management/signal', []);
- pyroutes.register('admin_settings_scheduler_create', '/_admin/settings/scheduler/create', []);
- pyroutes.register('admin_settings_scheduler_delete', '/_admin/settings/scheduler/%(schedule_id)s/delete', ['schedule_id']);
- pyroutes.register('admin_settings_scheduler_edit', '/_admin/settings/scheduler/%(schedule_id)s', ['schedule_id']);
- pyroutes.register('admin_settings_scheduler_execute', '/_admin/settings/scheduler/%(schedule_id)s/execute', ['schedule_id']);
- pyroutes.register('admin_settings_scheduler_new', '/_admin/settings/scheduler/new', []);
- pyroutes.register('admin_settings_scheduler_show_all', '/_admin/settings/scheduler', []);
- pyroutes.register('admin_settings_scheduler_show_tasks', '/_admin/settings/scheduler/_tasks', []);
- pyroutes.register('admin_settings_scheduler_update', '/_admin/settings/scheduler/%(schedule_id)s/update', ['schedule_id']);
+ pyroutes.register('admin_settings_scheduler_create', '/_admin/scheduler/create', []);
+ pyroutes.register('admin_settings_scheduler_delete', '/_admin/scheduler/%(schedule_id)s/delete', ['schedule_id']);
+ pyroutes.register('admin_settings_scheduler_edit', '/_admin/scheduler/%(schedule_id)s', ['schedule_id']);
+ pyroutes.register('admin_settings_scheduler_execute', '/_admin/scheduler/%(schedule_id)s/execute', ['schedule_id']);
+ pyroutes.register('admin_settings_scheduler_new', '/_admin/scheduler/new', []);
+ pyroutes.register('admin_settings_scheduler_update', '/_admin/scheduler/%(schedule_id)s/update', ['schedule_id']);
pyroutes.register('admin_settings_search', '/_admin/settings/search', []);
pyroutes.register('admin_settings_sessions', '/_admin/settings/sessions', []);
pyroutes.register('admin_settings_sessions_cleanup', '/_admin/settings/sessions/cleanup', []);
@@ -308,7 +308,6 @@ function registerRCRoutes() {
pyroutes.register('repo_creating', '/%(repo_name)s/repo_creating', ['repo_name']);
pyroutes.register('repo_creating_check', '/%(repo_name)s/repo_creating_check', ['repo_name']);
pyroutes.register('repo_default_reviewers_data', '/%(repo_name)s/settings/review/default-reviewers', ['repo_name']);
- pyroutes.register('repo_edit_toggle_locking', '/%(repo_name)s/settings/toggle_locking', ['repo_name']);
pyroutes.register('repo_file_authors', '/%(repo_name)s/authors/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
pyroutes.register('repo_file_download', '/%(repo_name)s/download/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
pyroutes.register('repo_file_download:legacy', '/%(repo_name)s/rawfile/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
@@ -362,6 +361,7 @@ function registerRCRoutes() {
pyroutes.register('repo_reviewers_review_rule_delete', '/%(repo_name)s/settings/review/rules/%(rule_id)s/delete', ['repo_name', 'rule_id']);
pyroutes.register('repo_reviewers_review_rule_edit', '/%(repo_name)s/settings/review/rules/%(rule_id)s', ['repo_name', 'rule_id']);
pyroutes.register('repo_reviewers_review_rule_new', '/%(repo_name)s/settings/review/rules/new', ['repo_name']);
+ pyroutes.register('repo_settings_quick_actions', '/%(repo_name)s/settings/quick-action', ['repo_name']);
pyroutes.register('repo_stats', '/%(repo_name)s/repo_stats/%(commit_id)s', ['repo_name', 'commit_id']);
pyroutes.register('repo_summary', '/%(repo_name)s', ['repo_name']);
pyroutes.register('repo_summary_commits', '/%(repo_name)s/summary-commits', ['repo_name']);
diff --git a/rhodecode/templates/admin/artifacts/artifacts.mako b/rhodecode/templates/admin/artifacts/artifacts.mako
--- a/rhodecode/templates/admin/artifacts/artifacts.mako
+++ b/rhodecode/templates/admin/artifacts/artifacts.mako
@@ -27,7 +27,10 @@
${_('This feature is available in RhodeCode EE edition only. Contact {sales_email} to obtain a trial license.').format(sales_email='sales@rhodecode.com')|n}
-
+
+ Artifacts are a binary file storage within RhodeCode that allows asset management next to version control system with fine-grained access control.
+ This functionality allows release builds or other types of binary asset to be stored and managed by RhodeCode.
+
diff --git a/rhodecode/templates/admin/settings/settings_automation.mako b/rhodecode/templates/admin/automation/automation.mako
rename from rhodecode/templates/admin/settings/settings_automation.mako
rename to rhodecode/templates/admin/automation/automation.mako
--- a/rhodecode/templates/admin/settings/settings_automation.mako
+++ b/rhodecode/templates/admin/automation/automation.mako
@@ -1,9 +1,37 @@
-
-
-
${_('Admin Automation')}
+<%inherit file="/base/base.mako"/>
+
+<%def name="title()">
+ ${_('Artifacts Admin')}
+ %if c.rhodecode_name:
+ · ${h.branding(c.rhodecode_name)}
+ %endif
+%def>
+
+<%def name="breadcrumbs_links()">%def>
+
+<%def name="menu_bar_nav()">
+ ${self.menu_items(active='admin')}
+%def>
+
+<%def name="menu_bar_subnav()">
+ ${self.admin_menu(active='automation')}
+%def>
+
+<%def name="main()">
+
+
+
+
+
+
${_('Automation Administration.')}
+
+
+
${_('This feature is available in RhodeCode EE edition only. Contact {sales_email} to obtain a trial license.').format(sales_email='sales@rhodecode.com')|n}
+
+
-
-
${_('This feature is available in RhodeCode EE edition only. Contact {sales_email} to obtain a trial license.').format(sales_email='sales@rhodecode.com')|n}
-
-
+
+
+
+%def>
diff --git a/rhodecode/templates/admin/gists/gist_index.mako b/rhodecode/templates/admin/gists/gist_index.mako
--- a/rhodecode/templates/admin/gists/gist_index.mako
+++ b/rhodecode/templates/admin/gists/gist_index.mako
@@ -39,7 +39,7 @@
% if c.rhodecode_user.username != h.DEFAULT_USER:
% endif
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
@@ -61,7 +61,7 @@
create_url = h.route_path('global_integrations_new')
%>
- ${_(u'Create new integration')}
+ ${_('Create new integration')}
@@ -99,7 +99,7 @@
%>
%endif
- ${_(u'Create one')}
+ ${_('Create one')}
%endif
diff --git a/rhodecode/templates/admin/main.mako b/rhodecode/templates/admin/main.mako
--- a/rhodecode/templates/admin/main.mako
+++ b/rhodecode/templates/admin/main.mako
@@ -39,7 +39,7 @@
${len(c.auth_user.repository_groups_admin)} |
% if c.can_create_repo_group:
- ${_(u'Add Repository Group')}
+ ${_('Add Repository Group')}
% endif
|
@@ -48,7 +48,7 @@
${len(c.auth_user.user_groups_admin)} |
% if c.can_create_user_group:
- ${_(u'Add User Group')}
+ ${_('Add User Group')}
% endif
|
diff --git a/rhodecode/templates/admin/repo_groups/repo_groups.mako b/rhodecode/templates/admin/repo_groups/repo_groups.mako
--- a/rhodecode/templates/admin/repo_groups/repo_groups.mako
+++ b/rhodecode/templates/admin/repo_groups/repo_groups.mako
@@ -27,7 +27,7 @@
diff --git a/rhodecode/templates/admin/repos/repos.mako b/rhodecode/templates/admin/repos/repos.mako
--- a/rhodecode/templates/admin/repos/repos.mako
+++ b/rhodecode/templates/admin/repos/repos.mako
@@ -27,7 +27,7 @@
diff --git a/rhodecode/templates/admin/scheduler/scheduler.mako b/rhodecode/templates/admin/scheduler/scheduler.mako
new file mode 100644
--- /dev/null
+++ b/rhodecode/templates/admin/scheduler/scheduler.mako
@@ -0,0 +1,39 @@
+<%inherit file="/base/base.mako"/>
+
+<%def name="title()">
+ ${_('Artifacts Admin')}
+ %if c.rhodecode_name:
+ · ${h.branding(c.rhodecode_name)}
+ %endif
+%def>
+
+<%def name="breadcrumbs_links()">%def>
+
+<%def name="menu_bar_nav()">
+ ${self.menu_items(active='admin')}
+%def>
+
+<%def name="menu_bar_subnav()">
+ ${self.admin_menu(active='scheduler')}
+%def>
+
+<%def name="main()">
+
+
+
+
+
+
${_('Scheduler Administration.')}
+
+
+
${_('This feature is available in RhodeCode EE edition only. Contact {sales_email} to obtain a trial license.').format(sales_email='sales@rhodecode.com')|n}
+
+ Scheduler enables management of automation tasks, and defining new custom cron-like actions to be executed within RhodeCode system.
+
+
+
+
+
+
+
+%def>
diff --git a/rhodecode/templates/admin/user_groups/user_groups.mako b/rhodecode/templates/admin/user_groups/user_groups.mako
--- a/rhodecode/templates/admin/user_groups/user_groups.mako
+++ b/rhodecode/templates/admin/user_groups/user_groups.mako
@@ -27,7 +27,7 @@
diff --git a/rhodecode/templates/admin/users/users.mako b/rhodecode/templates/admin/users/users.mako
--- a/rhodecode/templates/admin/users/users.mako
+++ b/rhodecode/templates/admin/users/users.mako
@@ -27,7 +27,7 @@
diff --git a/rhodecode/templates/base/base.mako b/rhodecode/templates/base/base.mako
--- a/rhodecode/templates/base/base.mako
+++ b/rhodecode/templates/base/base.mako
@@ -107,7 +107,7 @@
- ## super-admin case
+ ## super-admin case (Top Menu)
% if c.is_super_admin:
- ${_('Admin audit logs')}
- ${_('Repositories')}
@@ -115,6 +115,8 @@
- ${_('Users')}
- ${_('User groups')}
- ${_('Artifacts')}
+ - ${_('Automation')}
+ - ${_('Scheduler')}
- ${_('Permissions')}
- ${_('Authentication')}
- ${_('Integrations')}
@@ -540,7 +542,7 @@
% if can_create_repo_groups_in_group:
-
- ${_(u'New Repository Group')}
+ ${_('New Repository Group')}
% endif
% endif
@@ -568,12 +570,12 @@
% if can_create_repo_groups:
-
- ${_(u'New Repository Group')}
+ ${_('New Repository Group')}
% endif
-
- ${_(u'New Gist')}
+ ${_('New Gist')}
diff --git a/rhodecode/templates/scheduler/automation.mako b/rhodecode/templates/scheduler/automation.mako
new file mode 100644
--- /dev/null
+++ b/rhodecode/templates/scheduler/automation.mako
@@ -0,0 +1,37 @@
+<%inherit file="/base/base.mako"/>
+
+<%def name="title()">
+ ${_('Artifacts Admin')}
+ %if c.rhodecode_name:
+ · ${h.branding(c.rhodecode_name)}
+ %endif
+%def>
+
+<%def name="breadcrumbs_links()">%def>
+
+<%def name="menu_bar_nav()">
+ ${self.menu_items(active='admin')}
+%def>
+
+<%def name="menu_bar_subnav()">
+ ${self.admin_menu(active='automation')}
+%def>
+
+<%def name="main()">
+
+
+
+
+
+
${_('Automation Administration.')}
+
+
+
${_('This feature is available in RhodeCode EE edition only. Contact {sales_email} to obtain a trial license.').format(sales_email='sales@rhodecode.com')|n}
+
+
+
+
+
+
+
+%def>