@@ -87,29 +87,31 @@ def make_map(config):
action="repo_stats", conditions=dict(method=["DELETE"],
function=check_repo))
m.connect('repo_cache', "/repos_cache/{repo_name:.*}",
action="repo_cache", conditions=dict(method=["DELETE"],
m.connect('repo_public_journal', "/repos_public_journal/{repo_name:.*}",
action="repo_public_journal", conditions=dict(method=["PUT"],
m.connect('repo_pull', "/repo_pull/{repo_name:.*}",
action="repo_pull", conditions=dict(method=["PUT"],
#ADMIN REPOS GROUP REST ROUTES
routes_map.resource('repos_group', 'repos_groups', controller='admin/repos_groups', path_prefix='/_admin')
#ADMIN USER REST ROUTES
routes_map.resource('user', 'users', controller='admin/users', path_prefix='/_admin')
#ADMIN USERS REST ROUTES
routes_map.resource('users_group', 'users_groups', controller='admin/users_groups', path_prefix='/_admin')
#ADMIN GROUP REST ROUTES
routes_map.resource('group', 'groups', controller='admin/groups', path_prefix='/_admin')
#ADMIN PERMISSIONS REST ROUTES
routes_map.resource('permission', 'permissions', controller='admin/permissions', path_prefix='/_admin')
##ADMIN LDAP SETTINGS
routes_map.connect('ldap_settings', '/_admin/ldap', controller='admin/ldap_settings',
action='ldap_settings', conditions=dict(method=["POST"]))
routes_map.connect('ldap_home', '/_admin/ldap', controller='admin/ldap_settings',)
new file 100644
import logging
from pylons import request, response, session, tmpl_context as c, url
from pylons.controllers.util import abort, redirect
from rhodecode.lib.base import BaseController, render
log = logging.getLogger(__name__)
class ReposGroupsController(BaseController):
"""REST Controller styled on the Atom Publishing Protocol"""
# To properly map this controller, ensure your config/routing.py
# file has a resource setup:
# map.resource('repos_group', 'repos_groups')
def index(self, format='html'):
"""GET /repos_groups: All items in the collection"""
# url('repos_groups')
def create(self):
"""POST /repos_groups: Create a new item"""
def new(self, format='html'):
"""GET /repos_groups/new: Form to create a new item"""
# url('new_repos_group')
def update(self, id):
"""PUT /repos_groups/id: Update an existing item"""
# Forms posted to this method should contain a hidden field:
# <input type="hidden" name="_method" value="PUT" />
# Or using helpers:
# h.form(url('repos_group', id=ID),
# method='put')
# url('repos_group', id=ID)
def delete(self, id):
"""DELETE /repos_groups/id: Delete an existing item"""
# <input type="hidden" name="_method" value="DELETE" />
# method='delete')
def show(self, id, format='html'):
"""GET /repos_groups/id: Show a specific item"""
def edit(self, id, format='html'):
"""GET /repos_groups/id/edit: Form to edit an existing item"""
# url('edit_repos_group', id=ID)
@@ -26,104 +26,106 @@
# MA 02110-1301, USA.
import calendar
from time import mktime
from datetime import datetime, timedelta, date
from vcs.exceptions import ChangesetError
from pylons import tmpl_context as c, request, url
from pylons.i18n.translation import _
from rhodecode.model.db import Statistics
from rhodecode.model.db import Statistics, Repository
from rhodecode.model.repo import RepoModel
from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
from rhodecode.lib.base import BaseRepoController, render
from rhodecode.lib.utils import OrderedDict, EmptyChangeset
from rhodecode.lib.celerylib import run_task
from rhodecode.lib.celerylib.tasks import get_commits_stats
from rhodecode.lib.helpers import RepoPage
try:
import json
except ImportError:
#python 2.5 compatibility
import simplejson as json
class SummaryController(BaseRepoController):
@LoginRequired()
@HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
'repository.admin')
def __before__(self):
super(SummaryController, self).__before__()
def index(self):
c.repo, dbrepo = self.scm_model.get(c.repo_name)
c.dbrepo = dbrepo
def index(self, repo_name):
e = request.environ
c.dbrepo = dbrepo = Repository.by_repo_name(repo_name)
c.following = self.scm_model.is_following_repo(c.repo_name,
self.rhodecode_user.user_id)
c.following = self.scm_model.is_following_repo(repo_name,
def url_generator(**kw):
return url('shortlog_home', repo_name=c.repo_name, **kw)
return url('shortlog_home', repo_name=repo_name, **kw)
c.repo_changesets = RepoPage(c.repo, page=1, items_per_page=10,
c.repo_changesets = RepoPage(c.rhodecode_repo, page=1, items_per_page=10,
url=url_generator)
if self.rhodecode_user.username == 'default':
#for default(anonymous) user we don't need to pass credentials
username = ''
password = ''
else:
username = str(self.rhodecode_user.username)
password = '@'
uri = u'%(protocol)s://%(user)s%(password)s%(host)s%(prefix)s/%(repo_name)s' % {
'protocol': e.get('wsgi.url_scheme'),
'user':username,
'password':password,
'host':e.get('HTTP_HOST'),
'prefix':e.get('SCRIPT_NAME'),
'repo_name':c.repo_name, }
'repo_name':repo_name, }
c.clone_repo_url = uri
c.repo_tags = OrderedDict()
for name, hash in c.repo.tags.items()[:10]:
for name, hash in c.rhodecode_repo.tags.items()[:10]:
c.repo_tags[name] = c.repo.get_changeset(hash)
c.repo_tags[name] = c.rhodecode_repo.get_changeset(hash)
except ChangesetError:
c.repo_tags[name] = EmptyChangeset(hash)
c.repo_branches = OrderedDict()
for name, hash in c.repo.branches.items()[:10]:
for name, hash in c.rhodecode_repo.branches.items()[:10]:
c.repo_branches[name] = c.repo.get_changeset(hash)
c.repo_branches[name] = c.rhodecode_repo.get_changeset(hash)
c.repo_branches[name] = EmptyChangeset(hash)
td = date.today() + timedelta(days=1)
td_1m = td - timedelta(days=calendar.mdays[td.month])
td_1y = td - timedelta(days=365)
ts_min_m = mktime(td_1m.timetuple())
ts_min_y = mktime(td_1y.timetuple())
ts_max_y = mktime(td.timetuple())
if dbrepo.enable_statistics:
c.no_data_msg = _('No data loaded yet')
run_task(get_commits_stats, c.repo.name, ts_min_y, ts_max_y)
run_task(get_commits_stats, c.dbrepo.repo_name, ts_min_y, ts_max_y)
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()
if stats and stats.languages:
c.no_data = False is dbrepo.enable_statistics
@@ -134,25 +136,25 @@ class SummaryController(BaseRepoControll
sorted(lang_stats.items(), reverse=True,
key=lambda k: k[1])[:10]
)
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.repo)
c.download_options = self._get_download_links(c.rhodecode_repo)
return render('summary/summary.html')
def _get_download_links(self, repo):
download_l = []
branches_group = ([], _("Branches"))
tags_group = ([], _("Tags"))
@@ -284,25 +284,25 @@ class CodeHtmlFormatter(HtmlFormatter):
yield 0, '</td></tr></table>'
def pygmentize(filenode, **kwargs):
"""pygmentize function using pygments
:param filenode:
"""
return literal(code_highlight(filenode.content,
filenode.lexer, CodeHtmlFormatter(**kwargs)))
def pygmentize_annotation(filenode, **kwargs):
def pygmentize_annotation(repo_name, filenode, **kwargs):
"""pygmentize function for annotation
color_dict = {}
def gen_color(n=10000):
"""generator for getting n of evenly distributed colors using
hsv color and golden ratio. It always return same order of colors
:returns: RGB tuple
@@ -317,45 +317,48 @@ def pygmentize_annotation(filenode, **kw
RGB_tuple = colorsys.hsv_to_rgb(*HSV_tuple)
yield map(lambda x:str(int(x * 256)), RGB_tuple)
cgenerator = gen_color()
def get_color_string(cs):
if color_dict.has_key(cs):
col = color_dict[cs]
col = color_dict[cs] = cgenerator.next()
return "color: rgb(%s)! important;" % (', '.join(col))
def url_func(changeset):
tooltip_html = "<div style='font-size:0.8em'><b>Author:</b>" + \
" %s<br/><b>Date:</b> %s</b><br/><b>Message:</b> %s<br/></div>"
def url_func(repo_name):
def _url_func(changeset):
tooltip_html = tooltip_html % (changeset.author,
changeset.date,
tooltip(changeset.message))
lnk_format = '%5s:%s' % ('r%s' % changeset.revision,
short_id(changeset.raw_id))
uri = link_to(
lnk_format,
url('changeset_home', repo_name=changeset.repository.name,
revision=changeset.raw_id),
style=get_color_string(changeset.raw_id),
class_='tooltip',
title=tooltip_html
url('changeset_home', repo_name=repo_name,
uri += '\n'
return uri
return literal(annotate_highlight(filenode, url_func, **kwargs))
return _url_func
return literal(annotate_highlight(filenode, url_func(repo_name), **kwargs))
def get_changeset_safe(repo, rev):
from vcs.backends.base import BaseRepository
from vcs.exceptions import RepositoryError
if not isinstance(repo, BaseRepository):
raise Exception('You must pass an Repository '
'object as first argument got %s', type(repo))
cs = repo.get_changeset(rev)
except RepositoryError:
from rhodecode.lib.utils import EmptyChangeset
@@ -681,17 +684,17 @@ def changed_tooltip(nodes):
return ': ' + _('No Files')
def repo_link(groups_and_repos):
groups, repo_name = groups_and_repos
if not groups:
return repo_name
def make_link(group):
return link_to(group.group_name, url('/', group.group_id))
return link_to(group.group_name, url('repos_group', id=group.group_id))
return literal(' » '.join(map(make_link, groups)) + \
" » " + repo_name)
@@ -82,25 +82,25 @@ class WhooshIndexingDaemon(object):
raise Exception('You have to provide index location')
self.repo_location = repo_location
if not repo_location:
raise Exception('You have to provide repositories location')
self.repo_paths = ScmModel(sa).repo_scan(self.repo_location)
if repo_list:
filtered_repo_paths = {}
for repo_name, repo in self.repo_paths.items():
if repo_name in repo_list:
filtered_repo_paths[repo.name] = repo
filtered_repo_paths[repo_name] = repo
self.repo_paths = filtered_repo_paths
self.initial = False
if not os.path.isdir(self.index_location):
os.makedirs(self.index_location)
log.info('Cannot run incremental index since it does not'
' yet exist running full build')
self.initial = True
def get_paths(self, repo):
@@ -121,69 +121,69 @@ class WhooshIndexingDaemon(object):
log.debug(traceback.format_exc())
pass
return index_paths_
def get_node(self, repo, path):
n_path = path[len(repo.path) + 1:]
node = repo.get_changeset().get_node(n_path)
return node
def get_node_mtime(self, node):
return mktime(node.last_changeset.date.timetuple())
def add_doc(self, writer, path, repo):
def add_doc(self, writer, path, repo, repo_name):
"""Adding doc to writer this function itself fetches data from
the instance of vcs backend"""
node = self.get_node(repo, path)
#we just index the content of chosen files, and skip binary files
if node.extension in INDEX_EXTENSIONS and not node.is_binary:
u_content = node.content
if not isinstance(u_content, unicode):
log.warning(' >> %s Could not get this content as unicode '
'replacing with empty content', path)
u_content = u''
log.debug(' >> %s [WITH CONTENT]' % path)
log.debug(' >> %s' % path)
#just index file name without it's content
writer.add_document(owner=unicode(repo.contact),
repository=safe_unicode(repo.name),
repository=safe_unicode(repo_name),
path=safe_unicode(path),
content=u_content,
modtime=self.get_node_mtime(node),
extension=node.extension)
def build_index(self):
if os.path.exists(self.index_location):
log.debug('removing previous index')
rmtree(self.index_location)
if not os.path.exists(self.index_location):
os.mkdir(self.index_location)
idx = create_in(self.index_location, SCHEMA, indexname=IDX_NAME)
writer = idx.writer()
for repo in self.repo_paths.values():
log.debug('building index @ %s' % repo.path)
for idx_path in self.get_paths(repo):
self.add_doc(writer, idx_path, repo)
self.add_doc(writer, idx_path, repo, repo_name)
log.debug('>> COMMITING CHANGES <<')
writer.commit(merge=True)
log.debug('>>> FINISHED BUILDING INDEX <<<')
def update_index(self):
log.debug('STARTING INCREMENTAL INDEXING UPDATE')
idx = open_dir(self.index_location, indexname=self.indexname)
# The set of all paths in the index
indexed_paths = set()
@@ -212,30 +212,30 @@ class WhooshIndexingDaemon(object):
indexed_time = fields['modtime']
mtime = self.get_node_mtime(node)
if mtime > indexed_time:
# The file has changed, delete it and add it to the list of
# files to reindex
log.debug('adding to reindex list %s' % indexed_path)
writer.delete_by_term('path', indexed_path)
to_index.add(indexed_path)
# Loop over the files in the filesystem
# Assume we have a function that gathers the filenames of the
# documents to be indexed
for path in self.get_paths(repo):
if path in to_index or path not in indexed_paths:
# This is either a file that's changed, or a new file
# that wasn't indexed before. So index it!
self.add_doc(writer, path, repo)
self.add_doc(writer, path, repo, repo_name)
log.debug('re indexing %s' % path)
log.debug('>>> FINISHED REBUILDING INDEX <<<')
def run(self, full_index=False):
"""Run daemon"""
if full_index or self.initial:
self.build_index()
self.update_index()
@@ -127,37 +127,37 @@
<img class="icon" title="${_('Mercurial repository')}" alt="${_('Mercurial repository')}" src="${h.url("/images/icons/hgicon.png")}"/>
%elif repo['dbrepo']['repo_type'] =='git':
<img class="icon" title="${_('Git repository')}" alt="${_('Git repository')}" src="${h.url("/images/icons/giticon.png")}"/>
%else:
%endif
%if repo['dbrepo']['private']:
<img class="icon" alt="${_('private')}" src="${h.url("/images/icons/lock.png")}"/>
<img class="icon" alt="${_('public')}" src="${h.url("/images/icons/lock_open.png")}"/>
${h.link_to(repo['repo'].name, h.url('summary_home',repo_name=repo['repo'].name),class_="repo_name")}
${h.link_to(repo['name'], h.url('summary_home',repo_name=repo['name']),class_="repo_name")}
%if repo['dbrepo_fork']:
<a href="${h.url('summary_home',repo_name=repo['dbrepo_fork']['repo_name'])}">
<img class="icon" alt="${_('public')}"
title="${_('Fork of')} ${repo['dbrepo_fork']['repo_name']}"
src="${h.url("/images/icons/arrow_divide.png")}"/></a>
</td>
<td><span class="tooltip" title="${repo['repo'].last_change}">${("r%s:%s") % (h.get_changeset_safe(repo['repo'],'tip').revision,h.short_id(h.get_changeset_safe(repo['repo'],'tip').raw_id))}</span></td>
<td><a href="${h.url('repo_settings_home',repo_name=repo['repo'].name)}" title="${_('edit')}"><img class="icon" alt="${_('private')}" src="${h.url("/images/icons/application_form_edit.png")}"/></a></td>
<td><a href="${h.url('repo_settings_home',repo_name=repo['name'])}" title="${_('edit')}"><img class="icon" alt="${_('private')}" src="${h.url("/images/icons/application_form_edit.png")}"/></a></td>
<td>
${h.form(url('repo_settings_delete', repo_name=repo['repo'].name),method='delete')}
${h.submit('remove_%s' % repo['repo'].name,'',class_="delete_icon action_button",onclick="return confirm('Confirm to delete this repository');")}
${h.form(url('repo_settings_delete', repo_name=repo['name']),method='delete')}
${h.submit('remove_%s' % repo['name'],'',class_="delete_icon action_button",onclick="return confirm('Confirm to delete this repository');")}
${h.end_form()}
</tr>
%endfor
${_('No repositories yet')}
%if h.HasPermissionAny('hg.admin','hg.create.repository')():
${h.link_to(_('create one now'),h.url('admin_settings_create_repository'))}
</tbody>
</table>
@@ -58,25 +58,25 @@
</dd>
</dl>
<div id="body" class="codeblock">
<div class="code-header">
<div class="revision">${c.file.name}@r${c.file.last_changeset.revision}:${h.short_id(c.file.last_changeset.raw_id)}</div>
<div class="commit">"${c.file.message}"</div>
</div>
<div class="code-body">
%if c.file.is_binary:
${_('Binary file')}
% if c.file.size < c.cut_off_limit:
${h.pygmentize_annotation(c.file,linenos=True,anchorlinenos=True,lineanchors='S',cssclass="code-highlight")}
${h.pygmentize_annotation(c.repo_name,c.file,linenos=True,anchorlinenos=True,lineanchors='S',cssclass="code-highlight")}
${_('File is to big to display')} ${h.link_to(_('show as raw'),
h.url('files_raw_home',repo_name=c.repo_name,revision=c.cs.revision,f_path=c.f_path))}
<script type="text/javascript">
YAHOO.util.Event.onDOMReady(function(){
YAHOO.util.Event.addListener('show_rev','click',function(e){
YAHOO.util.Event.preventDefault(e);
var cs = YAHOO.util.Dom.get('diff1').value;
var url = "${h.url('files_annotate_home',repo_name=c.repo_name,revision='__CS__',f_path=c.f_path)}".replace('__CS__',cs);
window.location = url;
});
## -*- coding: utf-8 -*-
%for repo in c.repos_list:
<li>
<img src="${h.url("/images/icons/lock.png")}" alt="${_('Private repository')}" class="repo_switcher_type"/>
${h.link_to(repo['name'].name,h.url('summary_home',repo_name=repo['name']),class_="%s" % repo['dbrepo']['repo_type'])}
${h.link_to(repo['name'],h.url('summary_home',repo_name=repo['name']),class_="%s" % repo['dbrepo']['repo_type'])}
</li>
<img src="${h.url("/images/icons/lock_open.png")}" alt="${_('Public repository')}" class="repo_switcher_type" />
\ No newline at end of file
<%inherit file="/base/base.html"/>
<%def name="title()">
${c.repo_name} ${_('Summary')} - ${c.rhodecode_name}
</%def>
<%def name="breadcrumbs_links()">
${h.link_to(u'Home',h.url('/'))}
»
${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))}
${h.link_to(c.dbrepo.just_name,h.url('summary_home',repo_name=c.repo_name))}
${_('summary')}
<%def name="page_nav()">
${self.menu('summary')}
<%def name="main()">
<div class="box box-left">
<!-- box / title -->
<div class="title">
${self.breadcrumbs()}
<!-- end box / title -->
<div class="form">
<div class="fields">
<div class="field">
<div class="label">
<label>${_('Name')}:</label>
<div class="input-short">
%if c.rhodecode_user.username != 'default':
%if c.following:
<span id="follow_toggle" class="following" title="${_('Stop following this repository')}"
onclick="javascript:toggleFollowingRepo(this,${c.dbrepo.repo_id},'${str(h.get_token())}')">
</span>
<span id="follow_toggle" class="follow" title="${_('Start following this repository')}"
%endif:
%if c.dbrepo.repo_type =='hg':
<img style="margin-bottom:2px" class="icon" title="${_('Mercurial repository')}" alt="${_('Mercurial repository')}" src="${h.url("/images/icons/hgicon.png")}"/>
%if c.dbrepo.repo_type =='git':
<img style="margin-bottom:2px" class="icon" title="${_('Git repository')}" alt="${_('Git repository')}" src="${h.url("/images/icons/giticon.png")}"/>
%if c.dbrepo.private:
<img style="margin-bottom:2px" class="icon" title="${_('private repository')}" alt="${_('private repository')}" src="${h.url("/images/icons/lock.png")}"/>
<img style="margin-bottom:2px" class="icon" title="${_('public repository')}" alt="${_('public repository')}" src="${h.url("/images/icons/lock_open.png")}"/>
<span style="font-size: 1.6em;font-weight: bold;vertical-align: baseline;">${c.repo.name}</span>
<br/>
<span style="font-size: 1.6em;font-weight: bold;vertical-align: baseline;">${h.repo_link(c.dbrepo.groups_and_repo)}</span>
%if c.dbrepo.fork:
<span style="margin-top:5px">
<a href="${h.url('summary_home',repo_name=c.dbrepo.fork.repo_name)}">
title="${_('Fork of')} ${c.dbrepo.fork.repo_name}"
src="${h.url("/images/icons/arrow_divide.png")}"/>
${_('Fork of')} ${c.dbrepo.fork.repo_name}
</a>
%if c.dbrepo.clone_uri:
@@ -100,26 +100,29 @@
${_('Username')}: ${c.dbrepo.user.username}<br/>
${_('Name')}: ${c.dbrepo.user.name} ${c.dbrepo.user.lastname}<br/>
${_('Email')}: <a href="mailto:${c.dbrepo.user.email}">${c.dbrepo.user.email}</a>
<label>${_('Last change')}:</label>
${h.age(c.repo.last_change)} - ${c.repo.last_change}
${_('by')} ${h.get_changeset_safe(c.repo,'tip').author}
<b>${'r%s:%s' % (h.get_changeset_safe(c.rhodecode_repo,'tip').revision,
h.get_changeset_safe(c.rhodecode_repo,'tip').short_id)}</b> -
<span class="tooltip" title="${c.rhodecode_repo.last_change}">
${h.age(c.rhodecode_repo.last_change)}</span><br/>
${_('by')} ${h.get_changeset_safe(c.rhodecode_repo,'tip').author}
<label>${_('Clone url')}:</label>
<input type="text" id="clone_url" readonly="readonly" value="hg clone ${c.clone_repo_url}" size="70"/>
@@ -129,57 +132,57 @@
<label>${_('Trending source files')}:</label>
<div id="lang_stats"></div>
<label>${_('Download')}:</label>
%if len(c.repo.revisions) == 0:
%if len(c.rhodecode_repo.revisions) == 0:
${_('There are no downloads yet')}
%elif c.enable_downloads is False:
${_('Downloads are disabled for this repository')}
%if h.HasPermissionAll('hg.admin')('enable stats on from summary'):
[${h.link_to(_('enable'),h.url('edit_repo',repo_name=c.repo_name))}]
${h.select('download_options',c.repo.get_changeset().raw_id,c.download_options)}
%for cnt,archive in enumerate(c.repo._get_archives()):
${h.select('download_options',c.rhodecode_repo.get_changeset().raw_id,c.download_options)}
%for cnt,archive in enumerate(c.rhodecode_repo._get_archives()):
%if cnt >=1:
|
<span class="tooltip" title="${_('Download %s as %s') %('tip',archive['type'])}"
id="${archive['type']+'_link'}">${h.link_to(archive['type'],
h.url('files_archive_home',repo_name=c.repo.name,
h.url('files_archive_home',repo_name=c.dbrepo.repo_name,
fname='tip'+archive['extension']),class_="archive_icon")}</span>
<label>${_('Feeds')}:</label>
${h.link_to(_('RSS'),h.url('rss_feed_home',repo_name=c.repo.name,api_key=c.rhodecode_user.api_key),class_='rss_icon')}
${h.link_to(_('Atom'),h.url('atom_feed_home',repo_name=c.repo.name,api_key=c.rhodecode_user.api_key),class_='atom_icon')}
${h.link_to(_('RSS'),h.url('rss_feed_home',repo_name=c.dbrepo.repo_name,api_key=c.rhodecode_user.api_key),class_='rss_icon')}
${h.link_to(_('Atom'),h.url('atom_feed_home',repo_name=c.dbrepo.repo_name,api_key=c.rhodecode_user.api_key),class_='atom_icon')}
${h.link_to(_('RSS'),h.url('rss_feed_home',repo_name=c.repo.name),class_='rss_icon')}
${h.link_to(_('Atom'),h.url('atom_feed_home',repo_name=c.repo.name),class_='atom_icon')}
${h.link_to(_('RSS'),h.url('rss_feed_home',repo_name=c.dbrepo.repo_name),class_='rss_icon')}
${h.link_to(_('Atom'),h.url('atom_feed_home',repo_name=c.dbrepo.repo_name),class_='atom_icon')}
YUE.onDOMReady(function(e){
id = 'clone_url';
YUE.on(id,'click',function(e){
YUD.get('clone_url').select();
})
@@ -256,27 +259,27 @@
l = YUD.getElementsByClassName('stats_hidden')
for (e in l){
YUD.setStyle(l[e],'display','');
};
YUD.setStyle(YUD.get('code_stats_show_more'),
'display','none');
YUE.on('download_options','change',function(e){
var new_cs = e.target.options[e.target.selectedIndex];
var tmpl_links = {}
tmpl_links['${archive['type']}'] = '${h.link_to(archive['type'],
fname='__CS__'+archive['extension']),class_="archive_icon")}';
for(k in tmpl_links){
var s = YUD.get(k+'_link')
title_tmpl = "${_('Download %s as %s') % ('__CS_NAME__',archive['type'])}";
s.title = title_tmpl.replace('__CS_NAME__',new_cs.text)
s.innerHTML = tmpl_links[k].replace('__CS__',new_cs.value);
}
from rhodecode.tests import *
class TestReposGroupsController(TestController):
def test_index(self):
response = self.app.get(url('repos_groups'))
# Test response...
def test_index_as_xml(self):
response = self.app.get(url('formatted_repos_groups', format='xml'))
def test_create(self):
response = self.app.post(url('repos_groups'))
def test_new(self):
response = self.app.get(url('new_repos_group'))
def test_new_as_xml(self):
response = self.app.get(url('formatted_new_repos_group', format='xml'))
def test_update(self):
response = self.app.put(url('repos_group', id=1))
def test_update_browser_fakeout(self):
response = self.app.post(url('repos_group', id=1), params=dict(_method='put'))
def test_delete(self):
response = self.app.delete(url('repos_group', id=1))
def test_delete_browser_fakeout(self):
response = self.app.post(url('repos_group', id=1), params=dict(_method='delete'))
def test_show(self):
response = self.app.get(url('repos_group', id=1))
def test_show_as_xml(self):
response = self.app.get(url('formatted_repos_group', id=1, format='xml'))
def test_edit(self):
response = self.app.get(url('edit_repos_group', id=1))
def test_edit_as_xml(self):
response = self.app.get(url('formatted_edit_repos_group', id=1, format='xml'))
Status change: