@@ -413,24 +413,28 @@ def make_map(config):
rmap.connect('atom_feed_home', '/{repo_name:.*?}/feed/atom',
controller='feed', action='atom',
conditions=dict(function=check_repo))
#==========================================================================
# REPOSITORY ROUTES
rmap.connect('summary_home', '/{repo_name:.*?}',
controller='summary',
rmap.connect('repo_size', '/{repo_name:.*?}/repo_size',
controller='summary', action='repo_size',
rmap.connect('repos_group_home', '/{group_name:.*}',
controller='admin/repos_groups', action="show_by_name",
conditions=dict(function=check_group))
rmap.connect('changeset_home', '/{repo_name:.*?}/changeset/{revision}',
controller='changeset', revision='tip',
#still working url for backward compat.
rmap.connect('raw_changeset_home_depraced',
'/{repo_name:.*?}/raw-changeset/{revision}',
controller='changeset', action='changeset_raw',
@@ -21,38 +21,40 @@
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import traceback
import calendar
import logging
import urllib
from time import mktime
from datetime import timedelta, date
from urlparse import urlparse
from rhodecode.lib.compat import product
from rhodecode.lib.vcs.exceptions import ChangesetError, EmptyRepositoryError, \
NodeDoesNotExistError
from pylons import tmpl_context as c, request, url, config
from pylons.i18n.translation import _
from webob.exc import HTTPBadRequest
from beaker.cache import cache_region, region_invalidate
from rhodecode.config.conf import ALL_READMES, ALL_EXTS, LANGUAGES_EXTENSIONS_MAP
from rhodecode.model.db import Statistics, CacheInvalidation
from rhodecode.lib.utils import jsonify
from rhodecode.lib.utils2 import safe_unicode
from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator,\
NotAnonymous
from rhodecode.lib.base import BaseRepoController, render
from rhodecode.lib.vcs.backends.base import EmptyChangeset
from rhodecode.lib.markup_renderer import MarkupRenderer
from rhodecode.lib.celerylib import run_task
from rhodecode.lib.celerylib.tasks import get_commits_stats
from rhodecode.lib.helpers import RepoPage
from rhodecode.lib.compat import json, OrderedDict
from rhodecode.lib.vcs.nodes import FileNode
log = logging.getLogger(__name__)
README_FILES = [''.join([x[0][0], x[1][0]]) for x in
@@ -177,24 +179,32 @@ class SummaryController(BaseRepoControll
c.overview_data = json.dumps([[ts_min_y, 0], [ts_max_y, 10]])
c.trending_languages = json.dumps({})
c.no_data = True
c.enable_downloads = dbrepo.enable_downloads
if c.enable_downloads:
c.download_options = self._get_download_links(c.rhodecode_repo)
c.readme_data, c.readme_file = \
self.__get_readme_data(c.rhodecode_db_repo)
return render('summary/summary.html')
@NotAnonymous()
@jsonify
def repo_size(self, repo_name):
if request.is_xhr:
return _('repository size: %s') % c.rhodecode_db_repo._repo_size()
else:
raise HTTPBadRequest()
def __get_readme_data(self, db_repo):
repo_name = db_repo.repo_name
@cache_region('long_term')
def _get_readme_from_cache(key):
readme_data = None
readme_file = None
log.debug('Looking for README file')
try:
# get's the landing revision! or tip if fails
cs = db_repo.get_landing_changeset()
if isinstance(cs, EmptyChangeset):
@@ -1067,24 +1067,29 @@ class Repository(Base, BaseModel):
pr_repo = pr.other_repo.repo_name
grouped[rev] = [stat, status_lbl, pr_id, pr_repo]
for stat in statuses.all():
pr_id = pr_repo = None
if stat.pull_request:
pr_id = stat.pull_request.pull_request_id
pr_repo = stat.pull_request.other_repo.repo_name
grouped[stat.revision] = [str(stat.status), stat.status_lbl,
pr_id, pr_repo]
return grouped
def _repo_size(self):
from rhodecode.lib import helpers as h
log.debug('calculating repository size...')
return h.format_byte_size(self.scm_instance.size)
# SCM CACHE INSTANCE
@property
def invalidate(self):
return CacheInvalidation.invalidate(self.repo_name)
def set_invalidate(self):
"""
set a cache for invalidation for this instance
@@ -3193,24 +3193,41 @@ table.code-browser .submodule-dir {
}
.following {
background: url("../images/icons/heart_delete.png") no-repeat scroll 3px;
height: 16px;
width: 20px;
cursor: pointer;
display: block;
float: right;
margin-top: 2px;
.reposize {
background: url("../images/icons/server.png") no-repeat scroll 3px;
#repo_size{
margin-top: 4px;
color: #666;
float:right;
.locking_locked{
background: #FFF url("../images/icons/block_16.png") no-repeat scroll 3px;
.locking_unlocked{
background: #FFF url("../images/icons/accept.png") no-repeat scroll 3px;
@@ -382,24 +382,37 @@ var toggleFollowingRepo = function(targe
args+= '&auth_token='+token;
if(user_id != undefined){
args+="&user_id="+user_id;
YUC.asyncRequest('POST',TOGGLE_FOLLOW_URL,{
success:function(o){
onSuccessFollow(target);
},args);
return false;
var showRepoSize = function(target, repo_name, token){
var args= 'auth_token='+token;
// start loading
YUD.get(target).innerHTML = _TM['loading...'];
var url = REPO_SIZE_URL.replace('__NAME__', repo_name);
YUC.asyncRequest('POST',url,{
YUD.get(target).innerHTML = JSON.parse(o.responseText);
/**
* TOOLTIP IMPL.
*/
YAHOO.namespace('yuitip');
YAHOO.yuitip.main = {
$: YAHOO.util.Dom.get,
bgColor: '#000',
speed: 0.3,
opacity: 0.9,
@@ -45,25 +45,27 @@
'Group':"${_('Group')}",
'members':"${_('members')}",
'loading...':"${_('loading...')}",
'search truncated': "${_('search truncated')}",
'no matching files': "${_('no matching files')}",
'Open new pull request': "${_('Open new pull request')}",
'Open new pull request for selected changesets': "${_('Open new pull request for selected changesets')}",
'Show selected changes __S -> __E': "${_('Show selected changes __S -> __E')}",
'Selection link': "${_('Selection link')}",
};
var _TM = TRANSLATION_MAP;
var TOGGLE_FOLLOW_URL = "${h.url('toggle_following')}";
var LAZY_CS_URL = "${h.url('changeset_info', repo_name='__NAME__', revision='__REV__')}"
var LAZY_CS_URL = "${h.url('changeset_info', repo_name='__NAME__', revision='__REV__')}";
var REPO_SIZE_URL = "${h.url('repo_size', repo_name='__NAME__')}";
</script>
<script type="text/javascript" src="${h.url('/js/yui.2.9.js', ver=c.rhodecode_version)}"></script>
<!--[if lt IE 9]>
<script language="javascript" type="text/javascript" src="${h.url('/js/excanvas.min.js')}"></script>
<![endif]-->
<script type="text/javascript" src="${h.url('/js/yui.flot.js', ver=c.rhodecode_version)}"></script>
<script type="text/javascript" src="${h.url('/js/native.history.js', ver=c.rhodecode_version)}"></script>
<script type="text/javascript" src="${h.url('/js/rhodecode.js', ver=c.rhodecode_version)}"></script>
## EXTRA FOR JS
${self.js_extra()}
<script type="text/javascript">
(function(window,undefined){
@@ -53,24 +53,30 @@
%endif
</div>
%if c.rhodecode_user.username != 'default':
%if c.following:
<span id="follow_toggle" class="following tooltip" title="${_('Stop following this repository')}"
onclick="javascript:toggleFollowingRepo(this,${c.dbrepo.repo_id},'${str(h.get_token())}')">
</span>
%else:
<span id="follow_toggle" class="follow tooltip" title="${_('Start following this repository')}"
<div style="float:right;padding:0px 0px 0px 0px">
<span class="reposize tooltip" title="${_('Click to show size of repository')}"
onclick="javascript:showRepoSize('repo_size','${c.dbrepo.repo_name}','${str(h.get_token())}')">
<span id="repo_size"></span>
%endif:
## locking icon
%if c.rhodecode_db_repo.enable_locking:
%if c.rhodecode_db_repo.locked[0]:
<span class="locking_locked tooltip" title="${_('Repository locked by %s') % h.person_by_id(c.rhodecode_db_repo.locked[0])}"></span>
<span class="locking_unlocked tooltip" title="${_('Repository unlocked')}"></span>
##REPO TYPE
%if h.is_hg(c.dbrepo):
Status change: