@@ -133,53 +133,51 @@ class SummaryController(BaseRepoControll
c.no_data_msg = _('No data loaded yet')
run_task(get_commits_stats, c.dbrepo.repo_name, ts_min_y, ts_max_y)
else:
c.show_stats = False
c.no_data_msg = _('Statistics are disabled for this repository')
c.ts_min = ts_min_m
c.ts_max = ts_max_y
stats = self.sa.query(Statistics)\
.filter(Statistics.repository == dbrepo)\
.scalar()
c.stats_percentage = 0
if stats and stats.languages:
c.no_data = False is dbrepo.enable_statistics
lang_stats_d = json.loads(stats.languages)
c.commit_data = stats.commit_activity
c.overview_data = stats.commit_activity_combined
lang_stats = ((x, {"count": y,
"desc": LANGUAGES_EXTENSIONS_MAP.get(x)})
for x, y in lang_stats_d.items())
c.trending_languages = json.dumps(OrderedDict(
sorted(lang_stats, reverse=True,
key=lambda k: k[1])[:10]
)
c.trending_languages = json.dumps(
sorted(lang_stats, reverse=True, key=lambda k: k[1])[:10]
last_rev = stats.stat_on_revision + 1
c.repo_last_rev = c.rhodecode_repo.count()\
if c.rhodecode_repo.revisions else 0
if last_rev == 0 or c.repo_last_rev == 0:
pass
c.stats_percentage = '%.2f' % ((float((last_rev)) /
c.repo_last_rev) * 100)
c.commit_data = json.dumps({})
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_repo)
return render('summary/summary.html')
def __get_readme_data(self, repo):
@cache_region('long_term')
@@ -66,48 +66,49 @@ except ImportError:
# Python Software Foundation License
# XXX: it feels like using the class with "is" and "is not" instead of "==" and
# "!=" should be faster.
class _Nil(object):
def __repr__(self):
return "nil"
def __eq__(self, other):
if (isinstance(other, _Nil)):
return True
return NotImplemented
def __ne__(self, other):
return False
_nil = _Nil()
class _odict(object):
"""Ordered dict data structure, with O(1) complexity for dict operations
that modify one element.
Overwriting values doesn't change their original sequential order.
"""
def _dict_impl(self):
return None
def __init__(self, data=(), **kwds):
"""This doesn't accept keyword initialization as normal dicts to avoid
a trap - inside a function or method the keyword args are accessible
only as a dict, without a defined order, so their original order is
lost.
if kwds:
raise TypeError("__init__() of ordered dict takes no keyword "
"arguments to avoid an ordering trap.")
self._dict_impl().__init__(self)
# If you give a normal dict, then the order of elements is undefined
if hasattr(data, "iteritems"):
for key, val in data.iteritems():
self[key] = val
@@ -125,61 +126,61 @@ class _odict(object):
def _set_lh(self, val):
self._dict_impl().__setattr__(self, '_lh', val)
lh = property(_get_lh, _set_lh)
# Double-linked list tail
def _get_lt(self):
dict_impl = self._dict_impl()
if not hasattr(self, '_lt'):
dict_impl.__setattr__(self, '_lt', _nil)
return dict_impl.__getattribute__(self, '_lt')
def _set_lt(self, val):
self._dict_impl().__setattr__(self, '_lt', val)
lt = property(_get_lt, _set_lt)
def __getitem__(self, key):
return self._dict_impl().__getitem__(self, key)[1]
def __setitem__(self, key, val):
try:
dict_impl.__getitem__(self, key)[1] = val
except KeyError, e:
except KeyError:
new = [dict_impl.__getattribute__(self, 'lt'), val, _nil]
dict_impl.__setitem__(self, key, new)
if dict_impl.__getattribute__(self, 'lt') == _nil:
dict_impl.__setattr__(self, 'lh', key)
dict_impl.__getitem__(
self, dict_impl.__getattribute__(self, 'lt'))[2] = key
dict_impl.__setattr__(self, 'lt', key)
def __delitem__(self, key):
pred, _ , succ = self._dict_impl().__getitem__(self, key)
pred, _, succ = self._dict_impl().__getitem__(self, key)
if pred == _nil:
dict_impl.__setattr__(self, 'lh', succ)
dict_impl.__getitem__(self, pred)[2] = succ
if succ == _nil:
dict_impl.__setattr__(self, 'lt', pred)
dict_impl.__getitem__(self, succ)[0] = pred
dict_impl.__delitem__(self, key)
def __contains__(self, key):
return key in self.keys()
def __len__(self):
return len(self.keys())
def __str__(self):
pairs = ("%r: %r" % (k, v) for k, v in self.iteritems())
return "{%s}" % ", ".join(pairs)
if self:
pairs = ("(%r, %r)" % (k, v) for k, v in self.iteritems())
return "odict([%s])" % ", ".join(pairs)
@@ -330,48 +331,49 @@ class _odict(object):
return self._dict_impl().__getattribute__(self, 'lh')
raise KeyError("'firstkey(): ordered dictionary is empty'")
def lastkey(self):
return self._dict_impl().__getattribute__(self, 'lt')
raise KeyError("'lastkey(): ordered dictionary is empty'")
def as_dict(self):
return self._dict_impl()(self.items())
def _repr(self):
"""_repr(): low level repr of the whole data contained in the odict.
Useful for debugging.
form = "odict low level repr lh,lt,data: %r, %r, %s"
return form % (dict_impl.__getattribute__(self, 'lh'),
dict_impl.__getattribute__(self, 'lt'),
dict_impl.__repr__(self))
class OrderedDict(_odict, dict):
return dict
#==============================================================================
# OrderedSet
from sqlalchemy.util import OrderedSet
# kill FUNCTIONS
if __platform__ in PLATFORM_WIN:
import ctypes
def kill(pid, sig):
"""kill function for Win32"""
kernel32 = ctypes.windll.kernel32
handle = kernel32.OpenProcess(1, 0, pid)
return (0 != kernel32.TerminateProcess(handle, 0))
@@ -274,75 +274,77 @@ YUE.on(['download_options','archive_subr
var sm = YUD.get('download_options');
var new_cs = sm.options[sm.selectedIndex];
for(k in tmpl_links){
var s = YUD.get(k+'_link');
if(s){
var title_tmpl = "${_('Download %s as %s') % ('__CS_NAME__','__CS_EXT__')}";
title_tmpl= title_tmpl.replace('__CS_NAME__',new_cs.text);
title_tmpl = title_tmpl.replace('__CS_EXT__',k);
var url = tmpl_links[k].replace('__CS__',new_cs.value);
var subrepos = YUD.get('archive_subrepos').checked;
url = url.replace('__SUB__',subrepos);
url = url.replace('__NAME__',title_tmpl);
s.innerHTML = url
}
});
</script>
%if c.show_stats:
<script type="text/javascript">
var data = ${c.trending_languages|n};
var total = 0;
var no_data = true;
for (k in data){
total += data[k].count;
no_data = false;
var tbl = document.createElement('table');
tbl.setAttribute('class','trending_language_tbl');
var cnt = 0;
for (var i=0;i<data.length;i++){
total += data[i][1].count;
cnt += 1;
var hide = cnt>2;
var tr = document.createElement('tr');
if (hide){
tr.setAttribute('style','display:none');
tr.setAttribute('class','stats_hidden');
var percentage = Math.round((data[k].count/total*100),2);
var value = data[k].count;
var k = data[i][0];
var obj = data[i][1];
var percentage = Math.round((obj.count/total*100),2);
var td1 = document.createElement('td');
td1.width = 150;
var trending_language_label = document.createElement('div');
trending_language_label.innerHTML = data[k].desc+" ("+k+")";
trending_language_label.innerHTML = obj.desc+" ("+k+")";
td1.appendChild(trending_language_label);
var td2 = document.createElement('td');
td2.setAttribute('style','padding-right:14px !important');
var trending_language = document.createElement('div');
var nr_files = value+" ${_('files')}";
var nr_files = obj.count+" ${_('files')}";
trending_language.title = k+" "+nr_files;
if (percentage>22){
trending_language.innerHTML = "<b style='font-size:0.8em'>"+percentage+"% "+nr_files+ "</b>";
else{
trending_language.innerHTML = "<b style='font-size:0.8em'>"+percentage+"%</b>";
trending_language.setAttribute("class", 'trending_language top-right-rounded-corner bottom-right-rounded-corner');
trending_language.style.width=percentage+"%";
td2.appendChild(trending_language);
tr.appendChild(td1);
tr.appendChild(td2);
tbl.appendChild(tr);
if(cnt == 3){
var show_more = document.createElement('tr');
var td = document.createElement('td');
lnk = document.createElement('a');
lnk.href='#';
lnk.innerHTML = "${_('show more')}";
Status change: