##// END OF EJS Templates
dev(makefile): added sh shortcut for faster launch of dev env and shell
dev(makefile): added sh shortcut for faster launch of dev env and shell

File last commit:

r5192:2a29ebef default
r5209:2d475c54 default
Show More
__init__.py
947 lines | 31.7 KiB | text/x-python | PythonLexer
copyrights: updated for 2023
r5088 # Copyright (C) 2016-2023 RhodeCode GmbH
user-profile: migrated to pyramid views.
r1502 #
# 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 <http://www.gnu.org/licenses/>.
#
# 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/
pyramid: added checks for password change for authenticated users.
r1539 import time
user-profile: migrated to pyramid views.
r1502 import logging
data-grid-app: added universal function for extracting ordering....
r2040 import operator
core: make pylons global be used in obsolete parts of the code....
r1895
core: handle edge case requesting matched routes but with hg/svn/git or api context....
r3036 from pyramid.httpexceptions import HTTPFound, HTTPForbidden, HTTPBadRequest
user-profile: migrated to pyramid views.
r1502
files: render readme files found in repository file browser....
r3924 from rhodecode.lib import helpers as h, diffs, rc_cache
apps: base app fixes for python3
r5086 from rhodecode.lib.str_utils import safe_str
routing: detect invalid repo/group names before we hit DB checks to prevent some errors for bad repo names
r4841 from rhodecode.lib.utils import repo_name_slug
exceptions: use python3 compatible exception handling
r3104 from rhodecode.lib.utils2 import (
fix(apps): fixed readme generator from async to sync runner....
r5192 StrictAttributeDict,
str2bool,
safe_int,
datetime_to_time,
)
files: render readme files found in repository file browser....
r3924 from rhodecode.lib.markup_renderer import MarkupRenderer, relative_links
from rhodecode.lib.vcs.backends.base import EmptyCommit
repo-view: handle empty repo or missing requirements in base view for repositories.
r1714 from rhodecode.lib.vcs.exceptions import RepositoryRequirementError
core: added supports of repo based views via pyramid.
r1554 from rhodecode.model import repo
home: moved home and repo group views into pyramid....
r1774 from rhodecode.model import repo_group
user-groups: rewrote the app to pyramid...
r2068 from rhodecode.model import user_group
users: ported controllers from pylons into pyramid views.
r2114 from rhodecode.model import user
pyramid: added checks for password change for authenticated users.
r1539 from rhodecode.model.db import User
core: added supports of repo based views via pyramid.
r1554 from rhodecode.model.scm import ScmModel
issue-tracker: use stored issueTracker patterns for repo instead of initializing model every time.
r4201 from rhodecode.model.settings import VcsSettingsModel, IssueTrackerSettingsModel
files: render readme files found in repository file browser....
r3924 from rhodecode.model.repo import ReadmeFinder
user-profile: migrated to pyramid views.
r1502
log = logging.getLogger(__name__)
fix(apps): fixed readme generator from async to sync runner....
r5192 ADMIN_PREFIX: str = "/_admin"
STATIC_FILE_PREFIX: str = "/_static"
my-account-auth-tokens: moved into pyramid apps....
r1505
pyramid: moved add_route_requirements into pyramid base app....
r1928 URL_NAME_REQUIREMENTS = {
# group name can have a slash in them, but they must not end with a slash
fix(apps): fixed readme generator from async to sync runner....
r5192 "group_name": r".*?[^/]",
"repo_group_name": r".*?[^/]",
pyramid: moved add_route_requirements into pyramid base app....
r1928 # repo names can have a slash in them, but they must not end with a slash
fix(apps): fixed readme generator from async to sync runner....
r5192 "repo_name": r".*?[^/]",
pyramid: moved add_route_requirements into pyramid base app....
r1928 # file path eats up everything at the end
fix(apps): fixed readme generator from async to sync runner....
r5192 "f_path": r".*",
pyramid: moved add_route_requirements into pyramid base app....
r1928 # reference types
fix(apps): fixed readme generator from async to sync runner....
r5192 "source_ref_type": r"(branch|book|tag|rev|\%\(source_ref_type\)s)",
"target_ref_type": r"(branch|book|tag|rev|\%\(target_ref_type\)s)",
pyramid: moved add_route_requirements into pyramid base app....
r1928 }
my-account-auth-tokens: moved into pyramid apps....
r1505
fix(apps): fixed readme generator from async to sync runner....
r5192 def add_route_with_slash(config, name, pattern, **kw):
home: moved home and repo group views into pyramid....
r1774 config.add_route(name, pattern, **kw)
fix(apps): fixed readme generator from async to sync runner....
r5192 if not pattern.endswith("/"):
config.add_route(name + "_slash", pattern + "/", **kw)
home: moved home and repo group views into pyramid....
r1774
routing: fix default argument mutability.
r3091 def add_route_requirements(route_path, requirements=None):
pyramid: moved add_route_requirements into pyramid base app....
r1928 """
Adds regex requirements to pyramid routes using a mapping dict
e.g::
add_route_requirements('{repo_name}/settings')
"""
routing: fix default argument mutability.
r3091 requirements = requirements or URL_NAME_REQUIREMENTS
apps: base app fixes for python3
r5086 for key, regex in list(requirements.items()):
fix(apps): fixed readme generator from async to sync runner....
r5192 route_path = route_path.replace("{%s}" % key, "{%s:%s}" % (key, regex))
pyramid: moved add_route_requirements into pyramid base app....
r1928 return route_path
tags/branches/bookmarks: moved views into pyramid.
r1746 def get_format_ref_id(repo):
"""Returns a `repo` specific reference formatter function"""
if h.is_svn(repo):
return _format_ref_id_svn
else:
return _format_ref_id
def _format_ref_id(name, raw_id):
"""Default formatting of a given reference `name`"""
return name
def _format_ref_id_svn(name, raw_id):
"""Special way of formatting a reference for Subversion including path"""
fix(apps): fixed readme generator from async to sync runner....
r5192 return f"{name}@{raw_id}"
tags/branches/bookmarks: moved views into pyramid.
r1746
user-profile: migrated to pyramid views.
r1502 class TemplateArgs(StrictAttributeDict):
pass
class BaseAppView(object):
def __init__(self, context, request):
self.request = request
self.context = context
self.session = request.session
fix(apps): fixed readme generator from async to sync runner....
r5192 if not hasattr(request, "user"):
core: handle edge case requesting matched routes but with hg/svn/git or api context....
r3036 # NOTE(marcink): edge case, we ended up in matched route
# but probably of web-app context, e.g API CALL/VCS CALL
fix(apps): fixed readme generator from async to sync runner....
r5192 if hasattr(request, "vcs_call") or hasattr(request, "rpc_method"):
log.warning("Unable to process request `%s` in this scope", request)
core: handle edge case requesting matched routes but with hg/svn/git or api context....
r3036 raise HTTPBadRequest()
pyramid: base view improvements
r1534 self._rhodecode_user = request.user # auth user
my-account: switched my-password view to pyramid.
r1537 self._rhodecode_db_user = self._rhodecode_user.get_instance()
pyramid: added checks for password change for authenticated users.
r1539 self._maybe_needs_password_change(
fix(apps): fixed readme generator from async to sync runner....
r5192 request.matched_route.name, self._rhodecode_db_user
)
pyramid: added checks for password change for authenticated users.
r1539
def _maybe_needs_password_change(self, view_name, user_obj):
fix(apps): fixed readme generator from async to sync runner....
r5192 dont_check_views = ["channelstream_connect", "ops_ping"]
core: don't check channelstream connections for faster handling of this route.
r4700 if view_name in dont_check_views:
return
fix(apps): fixed readme generator from async to sync runner....
r5192 log.debug(
"Checking if user %s needs password change on view %s", user_obj, view_name
)
core: don't check channelstream connections for faster handling of this route.
r4700
pyramid: added checks for password change for authenticated users.
r1539 skip_user_views = [
fix(apps): fixed readme generator from async to sync runner....
r5192 "logout",
"login",
"my_account_password",
"my_account_password_update",
pyramid: added checks for password change for authenticated users.
r1539 ]
if not user_obj:
return
if user_obj.username == User.DEFAULT_USER:
return
now = time.time()
fix(apps): fixed readme generator from async to sync runner....
r5192 should_change = user_obj.user_data.get("force_password_change")
pyramid: added checks for password change for authenticated users.
r1539 change_after = safe_int(should_change) or 0
if should_change and now > change_after:
fix(apps): fixed readme generator from async to sync runner....
r5192 log.debug("User %s requires password change", user_obj)
h.flash(
"You are required to change your password",
"warning",
ignore_duplicate=True,
)
pyramid: added checks for password change for authenticated users.
r1539
if view_name not in skip_user_views:
fix(apps): fixed readme generator from async to sync runner....
r5192 raise HTTPFound(self.request.route_path("my_account_password"))
user-profile: migrated to pyramid views.
r1502
repositories: handle in a nicer way a filesystem damaged repositories....
r1984 def _log_creation_exception(self, e, repo_name):
_ = self.request.translate
reason = None
if len(e.args) == 2:
reason = e.args[1]
fix(apps): fixed readme generator from async to sync runner....
r5192 if reason == "INVALID_CERTIFICATE":
log.exception("Exception creating a repository: invalid certificate")
msg = _("Error creating repository %s: invalid certificate") % repo_name
repositories: handle in a nicer way a filesystem damaged repositories....
r1984 else:
log.exception("Exception creating a repository")
fix(apps): fixed readme generator from async to sync runner....
r5192 msg = _("Error creating repository %s") % repo_name
repositories: handle in a nicer way a filesystem damaged repositories....
r1984 return msg
pyramid: turn on inclusion of app defaults. This will be required...
r2332 def _get_local_tmpl_context(self, include_app_defaults=True):
pyramid-views: always register auth_user for via the base view....
r1533 c = TemplateArgs()
c.auth_user = self.request.user
pyramid: changes for pyramid migration.
r1908 # TODO(marcink): migrate the usage of c.rhodecode_user to c.auth_user
c.rhodecode_user = self.request.user
repo-summary: re-implemented summary view as pyramid....
r1785 if include_app_defaults:
from rhodecode.lib.base import attach_context_attributes
fix(apps): fixed readme generator from async to sync runner....
r5192
repo-summary: re-implemented summary view as pyramid....
r1785 attach_context_attributes(c, self.request, self.request.user.user_id)
pyramid: changes for pyramid migration.
r1908
auth: reduced usage of raw auth calls inside templates
r3587 c.is_super_admin = c.auth_user.is_admin
c.can_create_repo = c.is_super_admin
c.can_create_repo_group = c.is_super_admin
c.can_create_user_group = c.is_super_admin
c.is_delegated_admin = False
auth: don't check for delegated admin if we are super admin.
r3588 if not c.auth_user.is_default and not c.is_super_admin:
fix(apps): fixed readme generator from async to sync runner....
r5192 c.can_create_repo = h.HasPermissionAny("hg.create.repository")(
user=self.request.user
)
auth: reduced usage of raw auth calls inside templates
r3587 repositories = c.auth_user.repositories_admin or c.can_create_repo
fix(apps): fixed readme generator from async to sync runner....
r5192 c.can_create_repo_group = h.HasPermissionAny("hg.repogroup.create.true")(
user=self.request.user
)
repository_groups = (
c.auth_user.repository_groups_admin or c.can_create_repo_group
)
auth: reduced usage of raw auth calls inside templates
r3587
fix(apps): fixed readme generator from async to sync runner....
r5192 c.can_create_user_group = h.HasPermissionAny("hg.usergroup.create.true")(
user=self.request.user
)
auth: reduced usage of raw auth calls inside templates
r3587 user_groups = c.auth_user.user_groups_admin or c.can_create_user_group
# delegated admin can create, or manage some objects
c.is_delegated_admin = repositories or repository_groups or user_groups
pyramid-views: always register auth_user for via the base view....
r1533 return c
user-profile: migrated to pyramid views.
r1502
pylons: remove pylons as dependency...
r2351 def _get_template_context(self, tmpl_args, **kwargs):
fix(apps): fixed readme generator from async to sync runner....
r5192 local_tmpl_args = {"defaults": {}, "errors": {}, "c": tmpl_args}
pylons: remove pylons as dependency...
r2351 local_tmpl_args.update(kwargs)
login: switch to re-use the baseApp pyramid view.
r1536 return local_tmpl_args
user-profile: migrated to pyramid views.
r1502
pyramid: base view improvements
r1534 def load_default_context(self):
"""
example:
def load_default_context(self):
c = self._get_local_tmpl_context()
c.custom_var = 'foobar'
pylons: remove pylons as dependency...
r2351
pyramid: base view improvements
r1534 return c
"""
fix(apps): fixed readme generator from async to sync runner....
r5192 raise NotImplementedError("Needs implementation in view class")
pyramid: base view improvements
r1534
core: added supports of repo based views via pyramid.
r1554
class RepoAppView(BaseAppView):
def __init__(self, context, request):
apps: modernize for python3
r5093 super().__init__(context, request)
core: added supports of repo based views via pyramid.
r1554 self.db_repo = request.db_repo
self.db_repo_name = self.db_repo.repo_name
self.db_repo_pull_requests = ScmModel().get_pull_requests(self.db_repo)
menu: expose artifacts count into menu
r3984 self.db_repo_artifacts = ScmModel().get_artifacts(self.db_repo)
issue-tracker: use stored issueTracker patterns for repo instead of initializing model every time.
r4201 self.db_repo_patterns = IssueTrackerSettingsModel(repo=self.db_repo)
core: added supports of repo based views via pyramid.
r1554
repo-view: handle empty repo or missing requirements in base view for repositories.
r1714 def _handle_missing_requirements(self, error):
log.error(
fix(apps): fixed readme generator from async to sync runner....
r5192 "Requirements are missing for repository %s: %s",
self.db_repo_name,
safe_str(error),
)
repo-view: handle empty repo or missing requirements in base view for repositories.
r1714
ui: links to tags/branches/bookmarks render that in a context of summary page for better navigation.
r4977 def _prepare_and_set_clone_url(self, c):
fix(apps): fixed readme generator from async to sync runner....
r5192 username = ""
ui: links to tags/branches/bookmarks render that in a context of summary page for better navigation.
r4977 if self._rhodecode_user.username != User.DEFAULT_USER:
username = self._rhodecode_user.username
_def_clone_uri = c.clone_uri_tmpl
_def_clone_uri_id = c.clone_uri_id_tmpl
_def_clone_uri_ssh = c.clone_uri_ssh_tmpl
c.clone_repo_url = self.db_repo.clone_url(
fix(apps): fixed readme generator from async to sync runner....
r5192 user=username, uri_tmpl=_def_clone_uri
)
ui: links to tags/branches/bookmarks render that in a context of summary page for better navigation.
r4977 c.clone_repo_url_id = self.db_repo.clone_url(
fix(apps): fixed readme generator from async to sync runner....
r5192 user=username, uri_tmpl=_def_clone_uri_id
)
ui: links to tags/branches/bookmarks render that in a context of summary page for better navigation.
r4977 c.clone_repo_url_ssh = self.db_repo.clone_url(
fix(apps): fixed readme generator from async to sync runner....
r5192 uri_tmpl=_def_clone_uri_ssh, ssh=True
)
ui: links to tags/branches/bookmarks render that in a context of summary page for better navigation.
r4977
pylons: remove pylons as dependency...
r2351 def _get_local_tmpl_context(self, include_app_defaults=True):
repositories: handle in a nicer way a filesystem damaged repositories....
r1984 _ = self.request.translate
fix(apps): fixed readme generator from async to sync runner....
r5192 c = super()._get_local_tmpl_context(include_app_defaults=include_app_defaults)
repo-summary: re-implemented summary view as pyramid....
r1785
core: added supports of repo based views via pyramid.
r1554 # register common vars for this type of view
c.rhodecode_db_repo = self.db_repo
c.repo_name = self.db_repo_name
c.repository_pull_requests = self.db_repo_pull_requests
menu: expose artifacts count into menu
r3984 c.repository_artifacts = self.db_repo_artifacts
repositories: bring back watch action in summary view
r3670 c.repository_is_user_following = ScmModel().is_following_repo(
fix(apps): fixed readme generator from async to sync runner....
r5192 self.db_repo_name, self._rhodecode_user.user_id
)
path-permissions: handle case of missing requirements and initializing self.path_filter with None value....
r2624 self.path_filter = PathFilter(None)
repo-view: handle empty repo or missing requirements in base view for repositories.
r1714
missing requirements: better handling of missing requirements for repositories....
r2625 c.repository_requirements_missing = {}
repo-view: handle empty repo or missing requirements in base view for repositories.
r1714 try:
self.rhodecode_vcs_repo = self.db_repo.scm_instance()
repositories: use remote function to check if repo is empty...
r3723 # NOTE(marcink):
# comparison to None since if it's an object __bool__ is expensive to
# calculate
if self.rhodecode_vcs_repo is not None:
code: code fixes and small adjustments
r2623 path_perms = self.rhodecode_vcs_repo.get_path_permissions(
fix(apps): fixed readme generator from async to sync runner....
r5192 c.auth_user.username
)
code: code fixes and small adjustments
r2623 self.path_filter = PathFilter(path_perms)
repo-view: handle empty repo or missing requirements in base view for repositories.
r1714 except RepositoryRequirementError as e:
fix(apps): fixed readme generator from async to sync runner....
r5192 c.repository_requirements_missing = {"error": str(e)}
repo-view: handle empty repo or missing requirements in base view for repositories.
r1714 self._handle_missing_requirements(e)
repositories: handle in a nicer way a filesystem damaged repositories....
r1984 self.rhodecode_vcs_repo = None
path-permissions: Initial support for path-based permissions
r2618
code: code fixes and small adjustments
r2623 c.path_filter = self.path_filter # used by atom_feed_entry.mako
repositories: handle in a nicer way a filesystem damaged repositories....
r1984
missing requirements: better handling of missing requirements for repositories....
r2625 if self.rhodecode_vcs_repo is None:
repositories: handle in a nicer way a filesystem damaged repositories....
r1984 # unable to fetch this repo as vcs instance, report back to user
fix(apps): fixed readme generator from async to sync runner....
r5192 log.debug(
"Repository was not found on filesystem, check if it exists or is not damaged"
)
h.flash(
_(
"The repository `%(repo_name)s` cannot be loaded in filesystem. "
"Please check if it exist, or is not damaged."
)
% {"repo_name": c.repo_name},
category="error",
ignore_duplicate=True,
)
missing requirements: better handling of missing requirements for repositories....
r2625 if c.repository_requirements_missing:
route = self.request.matched_route.name
fix(apps): fixed readme generator from async to sync runner....
r5192 if route.startswith(("edit_repo", "repo_summary")):
missing requirements: better handling of missing requirements for repositories....
r2625 # allow summary and edit repo on missing requirements
return c
raise HTTPFound(
fix(apps): fixed readme generator from async to sync runner....
r5192 h.route_path("repo_summary", repo_name=self.db_repo_name)
)
missing requirements: better handling of missing requirements for repositories....
r2625
else: # redirect if we don't show missing requirements
fix(apps): fixed readme generator from async to sync runner....
r5192 raise HTTPFound(h.route_path("home"))
repo-view: handle empty repo or missing requirements in base view for repositories.
r1714
forks: don't expose fork link if we don't have permission to read it, and also don't pre-select in pull request.
r3367 c.has_origin_repo_read_perm = False
if self.db_repo.fork:
c.has_origin_repo_read_perm = h.HasRepoPermissionAny(
fix(apps): fixed readme generator from async to sync runner....
r5192 "repository.write", "repository.read", "repository.admin"
)(self.db_repo.fork.repo_name, "summary fork link")
forks: don't expose fork link if we don't have permission to read it, and also don't pre-select in pull request.
r3367
core: added supports of repo based views via pyramid.
r1554 return c
path-permissions: Introduced a _get_f_path_unchecked method, which can be used by redirects, which don't have to create a template context
r2620 def _get_f_path_unchecked(self, matchdict, default=None):
"""
Should only be used by redirects, everything else should call _get_f_path
"""
fix(apps): fixed readme generator from async to sync runner....
r5192 f_path = matchdict.get("f_path")
routing: use a common method to extract the f_path for repo views....
r1929 if f_path:
# fix for multiple initial slashes that causes errors for GIT
fix(apps): fixed readme generator from async to sync runner....
r5192 return f_path.lstrip("/")
path-permissions: Initial support for path-based permissions
r2618
path-permissions: Introduced a _get_f_path_unchecked method, which can be used by redirects, which don't have to create a template context
r2620 return default
def _get_f_path(self, matchdict, default=None):
code: code fixes and small adjustments
r2623 f_path_match = self._get_f_path_unchecked(matchdict, default)
return self.path_filter.assert_path_permissions(f_path_match)
path-permissions: Initial support for path-based permissions
r2618
Bartłomiej Wołyńczyk
caching: add option to cache diffs for commits and pull requests....
r2685 def _get_general_setting(self, target_repo, settings_key, default=False):
settings_model = VcsSettingsModel(repo=target_repo)
settings = settings_model.get_general_settings()
return settings.get(settings_key, default)
files: only check for git_lfs/hg_largefiles if they are enabled....
r3894 def _get_repo_setting(self, target_repo, settings_key, default=False):
settings_model = VcsSettingsModel(repo=target_repo)
settings = settings_model.get_repo_settings_inherited()
return settings.get(settings_key, default)
fix(apps): fixed readme generator from async to sync runner....
r5192 def _get_readme_data(self, db_repo, renderer_type, commit_id=None, path="/"):
log.debug("Looking for README file at path %s", path)
files: render readme files found in repository file browser....
r3924 if commit_id:
landing_commit_id = commit_id
else:
landing_commit = db_repo.get_landing_commit()
if isinstance(landing_commit, EmptyCommit):
return None, None
landing_commit_id = landing_commit.raw_id
fix(apps): fixed readme generator from async to sync runner....
r5192 cache_namespace_uid = f"repo.{db_repo.repo_id}"
region = rc_cache.get_or_create_region(
"cache_repo", cache_namespace_uid, use_async_runner=False
)
files: render readme files found in repository file browser....
r3924 start = time.time()
@region.conditional_cache_on_arguments(namespace=cache_namespace_uid)
fix(apps): fixed readme generator from async to sync runner....
r5192 def generate_repo_readme(
repo_id, _commit_id, _repo_name, _readme_search_path, _renderer_type
):
files: render readme files found in repository file browser....
r3924 readme_data = None
readme_filename = None
commit = db_repo.get_commit(_commit_id)
log.debug("Searching for a README file at commit %s.", _commit_id)
fix(apps): fixed readme generator from async to sync runner....
r5192 readme_node = ReadmeFinder(_renderer_type).search(
commit, path=_readme_search_path
)
files: render readme files found in repository file browser....
r3924
if readme_node:
fix(apps): fixed readme generator from async to sync runner....
r5192 log.debug("Found README node: %s", readme_node)
files: render readme files found in repository file browser....
r3924 relative_urls = {
fix(apps): fixed readme generator from async to sync runner....
r5192 "raw": h.route_path(
"repo_file_raw",
repo_name=_repo_name,
commit_id=commit.raw_id,
f_path=readme_node.path,
),
"standard": h.route_path(
"repo_files",
repo_name=_repo_name,
commit_id=commit.raw_id,
f_path=readme_node.path,
),
files: render readme files found in repository file browser....
r3924 }
ui: links to tags/branches/bookmarks render that in a context of summary page for better navigation.
r4977
fix(apps): fixed readme generator from async to sync runner....
r5192 readme_data = self._render_readme_or_none(
commit, readme_node, relative_urls
)
apps: base app fixes for python3
r5086 readme_filename = readme_node.str_path
files: render readme files found in repository file browser....
r3924
return readme_data, readme_filename
readme_data, readme_filename = generate_repo_readme(
fix(apps): fixed readme generator from async to sync runner....
r5192 db_repo.repo_id,
landing_commit_id,
db_repo.repo_name,
path,
renderer_type,
)
ui: links to tags/branches/bookmarks render that in a context of summary page for better navigation.
r4977
files: render readme files found in repository file browser....
r3924 compute_time = time.time() - start
fix(apps): fixed readme generator from async to sync runner....
r5192 log.debug(
"Repo README for path %s generated and computed in %.4fs",
path,
compute_time,
)
files: render readme files found in repository file browser....
r3924 return readme_data, readme_filename
def _render_readme_or_none(self, commit, readme_node, relative_urls):
fix(apps): fixed readme generator from async to sync runner....
r5192 log.debug("Found README file `%s` rendering...", readme_node.path)
files: render readme files found in repository file browser....
r3924 renderer = MarkupRenderer()
try:
html_source = renderer.render(
fix(apps): fixed readme generator from async to sync runner....
r5192 readme_node.str_content, filename=readme_node.path
)
files: render readme files found in repository file browser....
r3924 if relative_urls:
return relative_links(html_source, relative_urls)
return html_source
except Exception:
apps: base app fixes for python3
r5086 log.exception("Exception while trying to render the README")
files: render readme files found in repository file browser....
r3924
caches: allow cache disable for file tree
r3469 def get_recache_flag(self):
fix(apps): fixed readme generator from async to sync runner....
r5192 for flag_name in ["force_recache", "force-recache", "no-cache"]:
caches: allow cache disable for file tree
r3469 flag_val = self.request.GET.get(flag_name)
if str2bool(flag_val):
return True
return False
commits/summary: unify fetching remote attribute in summary and commits page to properly and in the same way show the data.
r4750 def get_commit_preload_attrs(cls):
fix(apps): fixed readme generator from async to sync runner....
r5192 pre_load = [
"author",
"branch",
"date",
"message",
"parents",
"obsolete",
"phase",
"hidden",
]
commits/summary: unify fetching remote attribute in summary and commits page to properly and in the same way show the data.
r4750 return pre_load
path-permissions: Initial support for path-based permissions
r2618
class PathFilter(object):
# Expects and instance of BasePathPermissionChecker or None
def __init__(self, permission_checker):
self.permission_checker = permission_checker
def assert_path_permissions(self, path):
path-filter: enable for quick search menu.
r3817 if self.path_access_allowed(path):
return path
raise HTTPForbidden()
def path_access_allowed(self, path):
fix(apps): fixed readme generator from async to sync runner....
r5192 log.debug("Checking ACL permissions for PathFilter for `%s`", path)
path-filter: enable for quick search menu.
r3817 if self.permission_checker:
acl: added some nicer logging for file path ACL checks.
r4285 has_access = path and self.permission_checker.has_access(path)
fix(apps): fixed readme generator from async to sync runner....
r5192 log.debug(
"ACL Permissions checker enabled, ACL Check has_access: %s", has_access
)
acl: added some nicer logging for file path ACL checks.
r4285 return has_access
fix(apps): fixed readme generator from async to sync runner....
r5192 log.debug("ACL permissions checker not enabled, skipping...")
path-filter: enable for quick search menu.
r3817 return True
routing: use a common method to extract the f_path for repo views....
r1929
path-permissions: Initial support for path-based permissions
r2618 def filter_patchset(self, patchset):
if not self.permission_checker or not patchset:
return patchset, False
had_filtered = False
filtered_patchset = []
for patch in patchset:
fix(apps): fixed readme generator from async to sync runner....
r5192 filename = patch.get("filename", None)
path-permissions: Initial support for path-based permissions
r2618 if not filename or self.permission_checker.has_access(filename):
filtered_patchset.append(patch)
else:
had_filtered = True
if had_filtered:
if isinstance(patchset, diffs.LimitedDiffContainer):
fix(apps): fixed readme generator from async to sync runner....
r5192 filtered_patchset = diffs.LimitedDiffContainer(
patchset.diff_limit, patchset.cur_diff_size, filtered_patchset
)
path-permissions: Initial support for path-based permissions
r2618 return filtered_patchset, True
else:
return patchset, False
fix(apps): fixed readme generator from async to sync runner....
r5192 def render_patchset_filtered(
self, diffset, patchset, source_ref=None, target_ref=None
):
path-permissions: Initial support for path-based permissions
r2618 filtered_patchset, has_hidden_changes = self.filter_patchset(patchset)
pull-requests: allow to show range diff in pr view
r3124 result = diffset.render_patchset(
fix(apps): fixed readme generator from async to sync runner....
r5192 filtered_patchset, source_ref=source_ref, target_ref=target_ref
)
path-permissions: Initial support for path-based permissions
r2618 result.has_hidden_changes = has_hidden_changes
return result
def get_raw_patch(self, diff_processor):
if self.permission_checker is None:
return diff_processor.as_raw()
elif self.permission_checker.has_full_access:
return diff_processor.as_raw()
else:
fix(apps): fixed readme generator from async to sync runner....
r5192 return "# Repository has user-specific filters, raw patch generation is disabled."
path-permissions: Initial support for path-based permissions
r2618
@property
def is_enabled(self):
return self.permission_checker is not None
core: added supports of repo based views via pyramid.
r1554
core: no longer rely on webob exception inside get_or_404 function....
r1956
routing: optionally use explicit db object on route....
r1989 class RepoGroupAppView(BaseAppView):
def __init__(self, context, request):
apps: modernize for python3
r5093 super().__init__(context, request)
routing: optionally use explicit db object on route....
r1989 self.db_repo_group = request.db_repo_group
self.db_repo_group_name = self.db_repo_group.group_name
dan
search: new UI for search, and repo group context search...
r3442 def _get_local_tmpl_context(self, include_app_defaults=True):
_ = self.request.translate
fix(apps): fixed readme generator from async to sync runner....
r5192 c = super()._get_local_tmpl_context(include_app_defaults=include_app_defaults)
dan
search: new UI for search, and repo group context search...
r3442 c.repo_group = self.db_repo_group
return c
repo-groups: moved to pyramid
r2175 def _revoke_perms_on_yourself(self, form_result):
fix(apps): fixed readme generator from async to sync runner....
r5192 _updates = [
u
for u in form_result["perm_updates"]
if self._rhodecode_user.user_id == int(u[0])
]
_additions = [
u
for u in form_result["perm_additions"]
if self._rhodecode_user.user_id == int(u[0])
]
_deletions = [
u
for u in form_result["perm_deletions"]
if self._rhodecode_user.user_id == int(u[0])
]
admin_perm = "group.admin"
if (
_updates
and _updates[0][1] != admin_perm
or _additions
and _additions[0][1] != admin_perm
or _deletions
and _deletions[0][1] != admin_perm
):
repo-groups: moved to pyramid
r2175 return True
return False
routing: optionally use explicit db object on route....
r1989
user-groups: rewrote the app to pyramid...
r2068 class UserGroupAppView(BaseAppView):
def __init__(self, context, request):
apps: modernize for python3
r5093 super().__init__(context, request)
user-groups: rewrote the app to pyramid...
r2068 self.db_user_group = request.db_user_group
self.db_user_group_name = self.db_user_group.users_group_name
users: ported controllers from pylons into pyramid views.
r2114 class UserAppView(BaseAppView):
def __init__(self, context, request):
apps: modernize for python3
r5093 super().__init__(context, request)
users: ported controllers from pylons into pyramid views.
r2114 self.db_user = request.db_user
self.db_user_id = self.db_user.user_id
_ = self.request.translate
if not request.db_user_supports_default:
if self.db_user.username == User.DEFAULT_USER:
fix(apps): fixed readme generator from async to sync runner....
r5192 h.flash(
_("Editing user `{}` is disabled.".format(User.DEFAULT_USER)),
category="warning",
)
raise HTTPFound(h.route_path("users"))
users: ported controllers from pylons into pyramid views.
r2114
data-grid: create a common re-usable app with datagrid rendering helpers
r1646 class DataGridAppView(object):
"""
Common class to have re-usable grid rendering components
"""
base-grid-view: allow specifing custom mapping for sort columns.
r1649 def _extract_ordering(self, request, column_map=None):
column_map = column_map or {}
fix(apps): fixed readme generator from async to sync runner....
r5192 column_index = safe_int(request.GET.get("order[0][column]"))
order_dir = request.GET.get("order[0][dir]", "desc")
order_by = request.GET.get("columns[%s][data][sort]" % column_index, "name_raw")
data-grid: create a common re-usable app with datagrid rendering helpers
r1646
# translate datatable to DB columns
base-grid-view: allow specifing custom mapping for sort columns.
r1649 order_by = column_map.get(order_by) or order_by
data-grid: create a common re-usable app with datagrid rendering helpers
r1646
fix(apps): fixed readme generator from async to sync runner....
r5192 search_q = request.GET.get("search[value]")
data-grid: create a common re-usable app with datagrid rendering helpers
r1646 return search_q, order_by, order_dir
def _extract_chunk(self, request):
fix(apps): fixed readme generator from async to sync runner....
r5192 start = safe_int(request.GET.get("start"), 0)
length = safe_int(request.GET.get("length"), 25)
draw = safe_int(request.GET.get("draw"))
data-grid: create a common re-usable app with datagrid rendering helpers
r1646 return draw, start, length
data-grid-app: added universal function for extracting ordering....
r2040 def _get_order_col(self, order_by, model):
py3: remove use of pyramid.compat
r4908 if isinstance(order_by, str):
data-grid-app: added universal function for extracting ordering....
r2040 try:
return operator.attrgetter(order_by)(model)
except AttributeError:
return None
else:
return order_by
data-grid: create a common re-usable app with datagrid rendering helpers
r1646
tags/branches/bookmarks: moved views into pyramid.
r1746 class BaseReferencesView(RepoAppView):
"""
Base for reference view for branches, tags and bookmarks.
"""
fix(apps): fixed readme generator from async to sync runner....
r5192
tags/branches/bookmarks: moved views into pyramid.
r1746 def load_default_context(self):
c = self._get_local_tmpl_context()
return c
def load_refs_context(self, ref_items, partials_template):
core: use new style pyramid partial renderer where possible.
r1897 _render = self.request.get_partial_renderer(partials_template)
vcs: optimized pre-load attributes for better caching.
r3850 pre_load = ["author", "date", "message", "parents"]
tags/branches/bookmarks: moved views into pyramid.
r1746
is_svn = h.is_svn(self.rhodecode_vcs_repo)
refs: refactored references code to remove any pylons elements....
r1898 is_hg = h.is_hg(self.rhodecode_vcs_repo)
tags/branches/bookmarks: moved views into pyramid.
r1746 format_ref_id = get_format_ref_id(self.rhodecode_vcs_repo)
refs: refactored references code to remove any pylons elements....
r1898 closed_refs = {}
if is_hg:
closed_refs = self.rhodecode_vcs_repo.branches_closed
data = []
tags/branches/bookmarks: moved views into pyramid.
r1746 for ref_name, commit_id in ref_items:
commit = self.rhodecode_vcs_repo.get_commit(
fix(apps): fixed readme generator from async to sync runner....
r5192 commit_id=commit_id, pre_load=pre_load
)
refs: refactored references code to remove any pylons elements....
r1898 closed = ref_name in closed_refs
tags/branches/bookmarks: moved views into pyramid.
r1746
# TODO: johbo: Unify generation of reference links
fix(apps): fixed readme generator from async to sync runner....
r5192 use_commit_id = "/" in ref_name or is_svn
files: ported repository files controllers to pyramid views.
r1927
if use_commit_id:
files_url = h.route_path(
fix(apps): fixed readme generator from async to sync runner....
r5192 "repo_files",
files: ported repository files controllers to pyramid views.
r1927 repo_name=self.db_repo_name,
fix(apps): fixed readme generator from async to sync runner....
r5192 f_path=ref_name if is_svn else "",
files: use a common function to handle url-by-refs, and fix landing refs for SVN....
r4373 commit_id=commit_id,
fix(apps): fixed readme generator from async to sync runner....
r5192 _query=dict(at=ref_name),
files: use a common function to handle url-by-refs, and fix landing refs for SVN....
r4373 )
files: ported repository files controllers to pyramid views.
r1927
else:
files_url = h.route_path(
fix(apps): fixed readme generator from async to sync runner....
r5192 "repo_files",
files: ported repository files controllers to pyramid views.
r1927 repo_name=self.db_repo_name,
fix(apps): fixed readme generator from async to sync runner....
r5192 f_path=ref_name if is_svn else "",
files: ported repository files controllers to pyramid views.
r1927 commit_id=ref_name,
fix(apps): fixed readme generator from async to sync runner....
r5192 _query=dict(at=ref_name),
files: use a common function to handle url-by-refs, and fix landing refs for SVN....
r4373 )
tags/branches/bookmarks: moved views into pyramid.
r1746
fix(apps): fixed readme generator from async to sync runner....
r5192 data.append(
{
"name": _render("name", ref_name, files_url, closed),
"name_raw": ref_name,
"date": _render("date", commit.date),
"date_raw": datetime_to_time(commit.date),
"author": _render("author", commit.author),
"commit": _render(
"commit", commit.message, commit.raw_id, commit.idx
),
"commit_raw": commit.idx,
"compare": _render(
"compare", format_ref_id(ref_name, commit.raw_id)
),
}
)
refs: refactored references code to remove any pylons elements....
r1898
return data
tags/branches/bookmarks: moved views into pyramid.
r1746
core: added supports of repo based views via pyramid.
r1554 class RepoRoutePredicate(object):
def __init__(self, val, config):
self.val = val
def text(self):
fix(apps): fixed readme generator from async to sync runner....
r5192 return f"repo_route = {self.val}"
core: added supports of repo based views via pyramid.
r1554
phash = text
def __call__(self, info, request):
fix(apps): fixed readme generator from async to sync runner....
r5192 if hasattr(request, "vcs_call"):
predicates: skip route matching for vcs type calls.
r1778 # skip vcs calls
return
fix(apps): fixed readme generator from async to sync runner....
r5192 repo_name = info["match"]["repo_name"]
routing: improve bad character detection on repo names
r4843
fix(apps): fixed readme generator from async to sync runner....
r5192 repo_name_parts = repo_name.split("/")
apps: base app fixes for python3
r5086 repo_slugs = [x for x in (repo_name_slug(x) for x in repo_name_parts)]
routing: improve bad character detection on repo names
r4843
if repo_name_parts != repo_slugs:
routing: detect invalid repo/group names before we hit DB checks to prevent some errors for bad repo names
r4841 # short-skip if the repo-name doesn't follow slug rule
fix(apps): fixed readme generator from async to sync runner....
r5192 log.warning(
"repo_name: %s is different than slug %s", repo_name_parts, repo_slugs
)
routing: detect invalid repo/group names before we hit DB checks to prevent some errors for bad repo names
r4841 return False
core: added supports of repo based views via pyramid.
r1554 repo_model = repo.RepoModel()
caches: disable caches in predicates....
r2893
by_name_match = repo_model.get_by_repo_name(repo_name, cache=False)
home: moved home and repo group views into pyramid....
r1774
routing: skip advanced delete for repo creating so we can remove stuck repositories.
r2913 def redirect_if_creating(route_info, db_repo):
fix(apps): fixed readme generator from async to sync runner....
r5192 skip_views = ["edit_repo_advanced_delete"]
route = route_info["route"]
routing: skip advanced delete for repo creating so we can remove stuck repositories.
r2913 # we should skip delete view so we can actually "remove" repositories
# if they get stuck in creating state.
if route.name in skip_views:
return
repositories: ported repo_creating checks to pyramid....
r1985 if db_repo.repo_state in [repo.Repository.STATE_PENDING]:
caches: disable caches in predicates....
r2893 repo_creating_url = request.route_path(
fix(apps): fixed readme generator from async to sync runner....
r5192 "repo_creating", repo_name=db_repo.repo_name
)
caches: disable caches in predicates....
r2893 raise HTTPFound(repo_creating_url)
repositories: ported repo_creating checks to pyramid....
r1985
core: added supports of repo based views via pyramid.
r1554 if by_name_match:
# register this as request object we can re-use later
request.db_repo = by_name_match
apps: base app fixes for python3
r5086 request.db_repo_name = request.db_repo.repo_name
routing: skip advanced delete for repo creating so we can remove stuck repositories.
r2913 redirect_if_creating(info, by_name_match)
core: added supports of repo based views via pyramid.
r1554 return True
by_id_match = repo_model.get_repo_by_id(repo_name)
if by_id_match:
request.db_repo = by_id_match
apps: base app fixes for python3
r5086 request.db_repo_name = request.db_repo.repo_name
routing: skip advanced delete for repo creating so we can remove stuck repositories.
r2913 redirect_if_creating(info, by_id_match)
core: added supports of repo based views via pyramid.
r1554 return True
return False
repositories: added option to archive repositories instead of deleting them....
r3090 class RepoForbidArchivedRoutePredicate(object):
def __init__(self, val, config):
self.val = val
def text(self):
fix(apps): fixed readme generator from async to sync runner....
r5192 return f"repo_forbid_archived = {self.val}"
repositories: added option to archive repositories instead of deleting them....
r3090
phash = text
def __call__(self, info, request):
_ = request.translate
rhodecode_db_repo = request.db_repo
log.debug(
fix(apps): fixed readme generator from async to sync runner....
r5192 "%s checking if archived flag for repo for %s",
self.__class__.__name__,
rhodecode_db_repo.repo_name,
)
repositories: added option to archive repositories instead of deleting them....
r3090
if rhodecode_db_repo.archived:
fix(apps): fixed readme generator from async to sync runner....
r5192 log.warning(
"Current view is not supported for archived repo:%s",
rhodecode_db_repo.repo_name,
)
repositories: added option to archive repositories instead of deleting them....
r3090
h.flash(
fix(apps): fixed readme generator from async to sync runner....
r5192 h.literal(_("Action not supported for archived repository.")),
category="warning",
)
repositories: added option to archive repositories instead of deleting them....
r3090 summary_url = request.route_path(
fix(apps): fixed readme generator from async to sync runner....
r5192 "repo_summary", repo_name=rhodecode_db_repo.repo_name
)
repositories: added option to archive repositories instead of deleting them....
r3090 raise HTTPFound(summary_url)
return True
pull-requests: moved the listing of pull requests for repo into pyramid....
r1766 class RepoTypeRoutePredicate(object):
def __init__(self, val, config):
fix(apps): fixed readme generator from async to sync runner....
r5192 self.val = val or ["hg", "git", "svn"]
pull-requests: moved the listing of pull requests for repo into pyramid....
r1766
def text(self):
fix(apps): fixed readme generator from async to sync runner....
r5192 return f"repo_accepted_type = {self.val}"
pull-requests: moved the listing of pull requests for repo into pyramid....
r1766
phash = text
def __call__(self, info, request):
fix(apps): fixed readme generator from async to sync runner....
r5192 if hasattr(request, "vcs_call"):
predicates: skip route matching for vcs type calls.
r1778 # skip vcs calls
return
pull-requests: moved the listing of pull requests for repo into pyramid....
r1766
rhodecode_db_repo = request.db_repo
log.debug(
fix(apps): fixed readme generator from async to sync runner....
r5192 "%s checking repo type for %s in %s",
self.__class__.__name__,
rhodecode_db_repo.repo_type,
self.val,
)
pull-requests: moved the listing of pull requests for repo into pyramid....
r1766
if rhodecode_db_repo.repo_type in self.val:
return True
else:
fix(apps): fixed readme generator from async to sync runner....
r5192 log.warning(
"Current view is not supported for repo type:%s",
rhodecode_db_repo.repo_type,
)
pull-requests: moved the listing of pull requests for repo into pyramid....
r1766 return False
home: moved home and repo group views into pyramid....
r1774 class RepoGroupRoutePredicate(object):
def __init__(self, val, config):
self.val = val
def text(self):
fix(apps): fixed readme generator from async to sync runner....
r5192 return f"repo_group_route = {self.val}"
home: moved home and repo group views into pyramid....
r1774
phash = text
def __call__(self, info, request):
fix(apps): fixed readme generator from async to sync runner....
r5192 if hasattr(request, "vcs_call"):
predicates: skip route matching for vcs type calls.
r1778 # skip vcs calls
return
fix(apps): fixed readme generator from async to sync runner....
r5192 repo_group_name = info["match"]["repo_group_name"]
routing: improve bad character detection on repo names
r4843
fix(apps): fixed readme generator from async to sync runner....
r5192 repo_group_name_parts = repo_group_name.split("/")
repo_group_slugs = [
x for x in [repo_name_slug(x) for x in repo_group_name_parts]
]
routing: improve bad character detection on repo names
r4843 if repo_group_name_parts != repo_group_slugs:
# short-skip if the repo-name doesn't follow slug rule
fix(apps): fixed readme generator from async to sync runner....
r5192 log.warning(
"repo_group_name: %s is different than slug %s",
repo_group_name_parts,
repo_group_slugs,
)
routing: detect invalid repo/group names before we hit DB checks to prevent some errors for bad repo names
r4841 return False
home: moved home and repo group views into pyramid....
r1774 repo_group_model = repo_group.RepoGroupModel()
caches: disable caches in predicates....
r2893 by_name_match = repo_group_model.get_by_group_name(repo_group_name, cache=False)
home: moved home and repo group views into pyramid....
r1774
if by_name_match:
# register this as request object we can re-use later
request.db_repo_group = by_name_match
apps: base app fixes for python3
r5086 request.db_repo_group_name = request.db_repo_group.group_name
home: moved home and repo group views into pyramid....
r1774 return True
return False
pull-requests: moved the listing of pull requests for repo into pyramid....
r1766
user-groups: rewrote the app to pyramid...
r2068 class UserGroupRoutePredicate(object):
def __init__(self, val, config):
self.val = val
def text(self):
fix(apps): fixed readme generator from async to sync runner....
r5192 return f"user_group_route = {self.val}"
user-groups: rewrote the app to pyramid...
r2068
phash = text
def __call__(self, info, request):
fix(apps): fixed readme generator from async to sync runner....
r5192 if hasattr(request, "vcs_call"):
user-groups: rewrote the app to pyramid...
r2068 # skip vcs calls
return
fix(apps): fixed readme generator from async to sync runner....
r5192 user_group_id = info["match"]["user_group_id"]
user-groups: rewrote the app to pyramid...
r2068 user_group_model = user_group.UserGroup()
caches: disable caches in predicates....
r2893 by_id_match = user_group_model.get(user_group_id, cache=False)
user-groups: rewrote the app to pyramid...
r2068
users: ported controllers from pylons into pyramid views.
r2114 if by_id_match:
user-groups: rewrote the app to pyramid...
r2068 # register this as request object we can re-use later
users: ported controllers from pylons into pyramid views.
r2114 request.db_user_group = by_id_match
user-groups: rewrote the app to pyramid...
r2068 return True
return False
users: ported controllers from pylons into pyramid views.
r2114 class UserRoutePredicateBase(object):
supports_default = None
def __init__(self, val, config):
self.val = val
def text(self):
raise NotImplementedError()
def __call__(self, info, request):
fix(apps): fixed readme generator from async to sync runner....
r5192 if hasattr(request, "vcs_call"):
users: ported controllers from pylons into pyramid views.
r2114 # skip vcs calls
return
fix(apps): fixed readme generator from async to sync runner....
r5192 user_id = info["match"]["user_id"]
users: ported controllers from pylons into pyramid views.
r2114 user_model = user.User()
caches: disable caches in predicates....
r2893 by_id_match = user_model.get(user_id, cache=False)
users: ported controllers from pylons into pyramid views.
r2114
if by_id_match:
# register this as request object we can re-use later
request.db_user = by_id_match
request.db_user_supports_default = self.supports_default
return True
return False
class UserRoutePredicate(UserRoutePredicateBase):
supports_default = False
def text(self):
fix(apps): fixed readme generator from async to sync runner....
r5192 return f"user_route = {self.val}"
users: ported controllers from pylons into pyramid views.
r2114
phash = text
class UserRouteWithDefaultPredicate(UserRoutePredicateBase):
supports_default = True
def text(self):
fix(apps): fixed readme generator from async to sync runner....
r5192 return f"user_with_default_route = {self.val}"
users: ported controllers from pylons into pyramid views.
r2114
phash = text
core: added supports of repo based views via pyramid.
r1554 def includeme(config):
fix(apps): fixed readme generator from async to sync runner....
r5192 config.add_route_predicate("repo_route", RepoRoutePredicate)
config.add_route_predicate("repo_accepted_types", RepoTypeRoutePredicate)
repositories: added option to archive repositories instead of deleting them....
r3090 config.add_route_predicate(
fix(apps): fixed readme generator from async to sync runner....
r5192 "repo_forbid_when_archived", RepoForbidArchivedRoutePredicate
)
config.add_route_predicate("repo_group_route", RepoGroupRoutePredicate)
config.add_route_predicate("user_group_route", UserGroupRoutePredicate)
config.add_route_predicate("user_route_with_default", UserRouteWithDefaultPredicate)
config.add_route_predicate("user_route", UserRoutePredicate)