##// END OF EJS Templates
files: fixed unicode problems on image preview, and make images center, no-stretch.
files: fixed unicode problems on image preview, and make images center, no-stretch.

File last commit:

r4306:09801de9 default
r4344:54aab712 default
Show More
repo_summary.py
314 lines | 11.8 KiB | text/x-python | PythonLexer
repo-summary: re-implemented summary view as pyramid....
r1785 # -*- coding: utf-8 -*-
code: update copyrights to 2020
r4306 # Copyright (C) 2011-2020 RhodeCode GmbH
repo-summary: re-implemented summary view as pyramid....
r1785 #
# 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/
import logging
import string
landing-rev: fixes #4102, use branches instead of landing tip refs by default....
r3881 import time
cache: turn off caches if expiration_time is 0
r2848 import rhodecode
repo-summary: re-implemented summary view as pyramid....
r1785
from pyramid.view import view_config
app: dropped deprecated controllers to view_utils which are actually proper name
r3346 from rhodecode.lib.view_utils import get_format_ref_id
repo-summary: re-implemented summary view as pyramid....
r1785 from rhodecode.apps._base import RepoAppView
from rhodecode.config.conf import (LANGUAGES_EXTENSIONS_MAP)
caches: don't use beaker for file caches anymore
r2846 from rhodecode.lib import helpers as h, rc_cache
repo-summary: re-implemented summary view as pyramid....
r1785 from rhodecode.lib.utils2 import safe_str, safe_int
from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
from rhodecode.lib.ext_json import json
from rhodecode.lib.vcs.backends.base import EmptyCommit
caches: don't use beaker for file caches anymore
r2846 from rhodecode.lib.vcs.exceptions import (
CommitError, EmptyRepositoryError, CommitDoesNotExistError)
repo-summary: re-implemented summary view as pyramid....
r1785 from rhodecode.model.db import Statistics, CacheKey, User
from rhodecode.model.meta import Session
from rhodecode.model.scm import ScmModel
log = logging.getLogger(__name__)
class RepoSummaryView(RepoAppView):
def load_default_context(self):
c = self._get_local_tmpl_context(include_app_defaults=True)
c.rhodecode_repo = None
if not c.repository_requirements_missing:
c.rhodecode_repo = self.rhodecode_vcs_repo
return c
def _load_commits_context(self, c):
p = safe_int(self.request.GET.get('page'), 1)
size = safe_int(self.request.GET.get('size'), 10)
dan
webhelpers: replaced paginate library with custom lib
r4091 def url_generator(page_num):
repo-summary: re-implemented summary view as pyramid....
r1785 query_params = {
dan
webhelpers: replaced paginate library with custom lib
r4091 'page': page_num,
repo-summary: re-implemented summary view as pyramid....
r1785 'size': size
}
return h.route_path(
'repo_summary_commits',
repo_name=c.rhodecode_db_repo.repo_name, _query=query_params)
pre_load = ['author', 'branch', 'date', 'message']
try:
commits: allow tag commit translation to be skipped for faster commit fetching in big chunks.
r3468 collection = self.rhodecode_vcs_repo.get_commits(
pre_load=pre_load, translate_tags=False)
repo-summary: re-implemented summary view as pyramid....
r1785 except EmptyRepositoryError:
collection = self.rhodecode_vcs_repo
caches: don't use beaker for file caches anymore
r2846 c.repo_commits = h.RepoPage(
dan
webhelpers: replaced paginate library with custom lib
r4091 collection, page=p, items_per_page=size, url_maker=url_generator)
repo-summary: re-implemented summary view as pyramid....
r1785 page_ids = [x.raw_id for x in c.repo_commits]
c.comments = self.db_repo.get_comments(page_ids)
c.statuses = self.db_repo.statuses(page_ids)
summary: fixed 500 errors on loading just summary commits and missing clone_url set....
r3545 def _prepare_and_set_clone_url(self, c):
username = ''
if self._rhodecode_user.username != User.DEFAULT_USER:
username = safe_str(self._rhodecode_user.username)
_def_clone_uri = _def_clone_uri_id = c.clone_uri_tmpl
_def_clone_uri_ssh = c.clone_uri_ssh_tmpl
if '{repo}' in _def_clone_uri:
_def_clone_uri_id = _def_clone_uri.replace('{repo}', '_{repoid}')
elif '{repoid}' in _def_clone_uri:
_def_clone_uri_id = _def_clone_uri.replace('_{repoid}', '{repo}')
c.clone_repo_url = self.db_repo.clone_url(
user=username, uri_tmpl=_def_clone_uri)
c.clone_repo_url_id = self.db_repo.clone_url(
user=username, uri_tmpl=_def_clone_uri_id)
c.clone_repo_url_ssh = self.db_repo.clone_url(
uri_tmpl=_def_clone_uri_ssh, ssh=True)
repo-summary: re-implemented summary view as pyramid....
r1785 @LoginRequired()
@HasRepoPermissionAnyDecorator(
'repository.read', 'repository.write', 'repository.admin')
@view_config(
route_name='repo_summary_commits', request_method='GET',
renderer='rhodecode:templates/summary/summary_commits.mako')
def summary_commits(self):
c = self.load_default_context()
summary: fixed 500 errors on loading just summary commits and missing clone_url set....
r3545 self._prepare_and_set_clone_url(c)
repo-summary: re-implemented summary view as pyramid....
r1785 self._load_commits_context(c)
return self._get_template_context(c)
@LoginRequired()
@HasRepoPermissionAnyDecorator(
'repository.read', 'repository.write', 'repository.admin')
@view_config(
route_name='repo_summary', request_method='GET',
renderer='rhodecode:templates/summary/summary.mako')
@view_config(
route_name='repo_summary_slash', request_method='GET',
renderer='rhodecode:templates/summary/summary.mako')
views: fixed some view names for better usage in view whitelist access
r1944 @view_config(
route_name='repo_summary_explicit', request_method='GET',
renderer='rhodecode:templates/summary/summary.mako')
repo-summary: re-implemented summary view as pyramid....
r1785 def summary(self):
c = self.load_default_context()
# Prepare the clone URL
summary: fixed 500 errors on loading just summary commits and missing clone_url set....
r3545 self._prepare_and_set_clone_url(c)
repo-summary: re-implemented summary view as pyramid....
r1785
# If enabled, get statistics data
c.show_stats = bool(self.db_repo.enable_statistics)
stats = Session().query(Statistics) \
.filter(Statistics.repository == self.db_repo) \
.scalar()
c.stats_percentage = 0
if stats and stats.languages:
c.no_data = False is self.db_repo.enable_statistics
lang_stats_d = json.loads(stats.languages)
# Sort first by decreasing count and second by the file extension,
# so we have a consistent output.
lang_stats_items = sorted(lang_stats_d.iteritems(),
key=lambda k: (-k[1], k[0]))[:10]
lang_stats = [(x, {"count": y,
"desc": LANGUAGES_EXTENSIONS_MAP.get(x)})
for x, y in lang_stats_items]
c.trending_languages = json.dumps(lang_stats)
else:
c.no_data = True
c.trending_languages = json.dumps({})
scm_model = ScmModel()
c.enable_downloads = self.db_repo.enable_downloads
c.repository_followers = scm_model.get_followers(self.db_repo)
c.repository_forks = scm_model.get_forks(self.db_repo)
# first interaction with the VCS instance after here...
if c.repository_requirements_missing:
self.request.override_renderer = \
'rhodecode:templates/summary/missing_requirements.mako'
return self._get_template_context(c)
c.readme_data, c.readme_file = \
self._get_readme_data(self.db_repo, c.visual.default_renderer)
# loads the summary commits template context
self._load_commits_context(c)
return self._get_template_context(c)
@LoginRequired()
@HasRepoPermissionAnyDecorator(
'repository.read', 'repository.write', 'repository.admin')
@view_config(
route_name='repo_stats', request_method='GET',
renderer='json_ext')
def repo_stats(self):
caches: don't use beaker for file caches anymore
r2846 show_stats = bool(self.db_repo.enable_statistics)
repo_id = self.db_repo.repo_id
repo-summary: re-implemented summary view as pyramid....
r1785
summary: use non-memory cache for readme, and cleanup cache for repo stats.
r3892 landing_commit = self.db_repo.get_landing_commit()
if isinstance(landing_commit, EmptyCommit):
return {'size': 0, 'code_stats': {}}
cache_seconds = safe_int(rhodecode.CONFIG.get('rc_cache.cache_repo.expiration_time'))
cache: turn off caches if expiration_time is 0
r2848 cache_on = cache_seconds > 0
summary: use non-memory cache for readme, and cleanup cache for repo stats.
r3892
cache: turn off caches if expiration_time is 0
r2848 log.debug(
summary: use non-memory cache for readme, and cleanup cache for repo stats.
r3892 'Computing REPO STATS for repo_id %s commit_id `%s` '
cache: turn off caches if expiration_time is 0
r2848 'with caching: %s[TTL: %ss]' % (
summary: use non-memory cache for readme, and cleanup cache for repo stats.
r3892 repo_id, landing_commit, cache_on, cache_seconds or 0))
cache: turn off caches if expiration_time is 0
r2848
caches: don't use beaker for file caches anymore
r2846 cache_namespace_uid = 'cache_repo.{}'.format(repo_id)
region = rc_cache.get_or_create_region('cache_repo', cache_namespace_uid)
repo-summary: re-implemented summary view as pyramid....
r1785
caches: use new decorator that uses conditional caches skipping dogpile if cache is disabled.
r2892 @region.conditional_cache_on_arguments(namespace=cache_namespace_uid,
condition=cache_on)
summary: use non-memory cache for readme, and cleanup cache for repo stats.
r3892 def compute_stats(repo_id, commit_id, _show_stats):
repo-summary: re-implemented summary view as pyramid....
r1785 code_stats = {}
size = 0
try:
summary: use non-memory cache for readme, and cleanup cache for repo stats.
r3892 commit = self.db_repo.get_commit(commit_id)
repo-summary: re-implemented summary view as pyramid....
r1785
for node in commit.get_filenodes_generator():
size += node.size
summary: use non-memory cache for readme, and cleanup cache for repo stats.
r3892 if not _show_stats:
repo-summary: re-implemented summary view as pyramid....
r1785 continue
ext = string.lower(node.extension)
ext_info = LANGUAGES_EXTENSIONS_MAP.get(ext)
if ext_info:
if ext in code_stats:
code_stats[ext]['count'] += 1
else:
code_stats[ext] = {"count": 1, "desc": ext_info}
repo-summary: protect against wrong commits in repo summary.
r2148 except (EmptyRepositoryError, CommitDoesNotExistError):
repo-summary: re-implemented summary view as pyramid....
r1785 pass
return {'size': h.format_byte_size_binary(size),
'code_stats': code_stats}
summary: use non-memory cache for readme, and cleanup cache for repo stats.
r3892 stats = compute_stats(self.db_repo.repo_id, landing_commit.raw_id, show_stats)
repo-summary: re-implemented summary view as pyramid....
r1785 return stats
@LoginRequired()
@HasRepoPermissionAnyDecorator(
'repository.read', 'repository.write', 'repository.admin')
@view_config(
route_name='repo_refs_data', request_method='GET',
renderer='json_ext')
def repo_refs_data(self):
_ = self.request.translate
self.load_default_context()
repo = self.rhodecode_vcs_repo
refs_to_create = [
(_("Branch"), repo.branches, 'branch'),
(_("Tag"), repo.tags, 'tag'),
(_("Bookmark"), repo.bookmarks, 'book'),
]
files: bring back ability to specify numeric commit number in files selector
r3667 res = self._create_reference_data(repo, self.db_repo_name, refs_to_create)
repo-summary: re-implemented summary view as pyramid....
r1785 data = {
'more': False,
'results': res
}
return data
@LoginRequired()
@HasRepoPermissionAnyDecorator(
'repository.read', 'repository.write', 'repository.admin')
@view_config(
route_name='repo_refs_changelog_data', request_method='GET',
renderer='json_ext')
def repo_refs_changelog_data(self):
_ = self.request.translate
self.load_default_context()
repo = self.rhodecode_vcs_repo
refs_to_create = [
(_("Branches"), repo.branches, 'branch'),
(_("Closed branches"), repo.branches_closed, 'branch_closed'),
# TODO: enable when vcs can handle bookmarks filters
# (_("Bookmarks"), repo.bookmarks, "book"),
]
res = self._create_reference_data(
repo, self.db_repo_name, refs_to_create)
data = {
'more': False,
'results': res
}
return data
def _create_reference_data(self, repo, full_repo_name, refs_to_create):
app: dropped deprecated controllers to view_utils which are actually proper name
r3346 format_ref_id = get_format_ref_id(repo)
repo-summary: re-implemented summary view as pyramid....
r1785
result = []
for title, refs, ref_type in refs_to_create:
if refs:
result.append({
'text': title,
'children': self._create_reference_items(
repo, full_repo_name, refs, ref_type,
format_ref_id),
})
return result
ui: new file tree switcher...
r3655 def _create_reference_items(self, repo, full_repo_name, refs, ref_type, format_ref_id):
repo-summary: re-implemented summary view as pyramid....
r1785 result = []
is_svn = h.is_svn(repo)
for ref_name, raw_id in refs.iteritems():
files_url = self._create_files_url(
repo, full_repo_name, ref_name, raw_id, is_svn)
result.append({
'text': ref_name,
'id': format_ref_id(ref_name, raw_id),
'raw_id': raw_id,
'type': ref_type,
'files_url': files_url,
ui: new file tree switcher...
r3655 'idx': 0,
repo-summary: re-implemented summary view as pyramid....
r1785 })
return result
def _create_files_url(self, repo, full_repo_name, ref_name, raw_id, is_svn):
use_commit_id = '/' in ref_name or is_svn
files: ported repository files controllers to pyramid views.
r1927 return h.route_path(
'repo_files',
repo-summary: re-implemented summary view as pyramid....
r1785 repo_name=full_repo_name,
f_path=ref_name if is_svn else '',
files: ported repository files controllers to pyramid views.
r1927 commit_id=raw_id if use_commit_id else ref_name,
_query=dict(at=ref_name))