diff --git a/rhodecode/config/routing.py b/rhodecode/config/routing.py
--- a/rhodecode/config/routing.py
+++ b/rhodecode/config/routing.py
@@ -96,11 +96,13 @@ def make_map(config):
action="repo_pull", conditions=dict(method=["PUT"],
function=check_repo))
+ #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 USER REST ROUTES
+ #ADMIN USERS REST ROUTES
routes_map.resource('users_group', 'users_groups', controller='admin/users_groups', path_prefix='/_admin')
#ADMIN GROUP REST ROUTES
diff --git a/rhodecode/controllers/admin/repos_groups.py b/rhodecode/controllers/admin/repos_groups.py
new file mode 100644
--- /dev/null
+++ b/rhodecode/controllers/admin/repos_groups.py
@@ -0,0 +1,52 @@
+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"""
+ # url('repos_groups')
+
+ 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:
+ #
+ # 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"""
+ # Forms posted to this method should contain a hidden field:
+ #
+ # Or using helpers:
+ # h.form(url('repos_group', id=ID),
+ # method='delete')
+ # url('repos_group', id=ID)
+
+ def show(self, id, format='html'):
+ """GET /repos_groups/id: Show a specific item"""
+ # url('repos_group', id=ID)
+
+ def edit(self, id, format='html'):
+ """GET /repos_groups/id/edit: Form to edit an existing item"""
+ # url('edit_repos_group', id=ID)
diff --git a/rhodecode/controllers/summary.py b/rhodecode/controllers/summary.py
--- a/rhodecode/controllers/summary.py
+++ b/rhodecode/controllers/summary.py
@@ -35,7 +35,8 @@ from vcs.exceptions import ChangesetErro
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
@@ -60,19 +61,20 @@ class SummaryController(BaseRepoControll
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,
+ self.rhodecode_user.user_id)
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)
- e = request.environ
+
if self.rhodecode_user.username == 'default':
#for default(anonymous) user we don't need to pass credentials
@@ -88,19 +90,19 @@ class SummaryController(BaseRepoControll
'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]:
try:
- 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]:
try:
- c.repo_branches[name] = c.repo.get_changeset(hash)
+ c.repo_branches[name] = c.rhodecode_repo.get_changeset(hash)
except ChangesetError:
c.repo_branches[name] = EmptyChangeset(hash)
@@ -114,7 +116,7 @@ class SummaryController(BaseRepoControll
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)
else:
c.no_data_msg = _('Statistics are disabled for this repository')
c.ts_min = ts_min_m
@@ -143,7 +145,7 @@ class SummaryController(BaseRepoControll
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')
diff --git a/rhodecode/lib/helpers.py b/rhodecode/lib/helpers.py
--- a/rhodecode/lib/helpers.py
+++ b/rhodecode/lib/helpers.py
@@ -293,7 +293,7 @@ def pygmentize(filenode, **kwargs):
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
:param filenode:
@@ -326,27 +326,30 @@ def pygmentize_annotation(filenode, **kw
col = color_dict[cs] = cgenerator.next()
return "color: rgb(%s)! important;" % (', '.join(col))
- def url_func(changeset):
- tooltip_html = "
Author:" + \
- " %s
Date: %s
Message: %s
"
+ def url_func(repo_name):
+ def _url_func(changeset):
+ tooltip_html = "Author:" + \
+ " %s
Date: %s
Message: %s
"
- 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
- )
+ 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=repo_name,
+ revision=changeset.raw_id),
+ style=get_color_string(changeset.raw_id),
+ class_='tooltip',
+ title=tooltip_html
+ )
- uri += '\n'
- return uri
- return literal(annotate_highlight(filenode, url_func, **kwargs))
+ uri += '\n'
+ return uri
+ 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
@@ -690,7 +693,7 @@ def repo_link(groups_and_repos):
return repo_name
else:
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)
diff --git a/rhodecode/lib/indexers/daemon.py b/rhodecode/lib/indexers/daemon.py
--- a/rhodecode/lib/indexers/daemon.py
+++ b/rhodecode/lib/indexers/daemon.py
@@ -91,7 +91,7 @@ class WhooshIndexingDaemon(object):
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
@@ -130,7 +130,7 @@ class WhooshIndexingDaemon(object):
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)
@@ -152,7 +152,7 @@ class WhooshIndexingDaemon(object):
u_content = u''
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),
@@ -170,11 +170,11 @@ class WhooshIndexingDaemon(object):
idx = create_in(self.index_location, SCHEMA, indexname=IDX_NAME)
writer = idx.writer()
- for repo in self.repo_paths.values():
+ for repo_name, repo in self.repo_paths.items():
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)
@@ -221,12 +221,12 @@ class WhooshIndexingDaemon(object):
# Loop over the files in the filesystem
# Assume we have a function that gathers the filenames of the
# documents to be indexed
- for repo in self.repo_paths.values():
+ for repo_name, repo in self.repo_paths.items():
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('>> COMMITING CHANGES <<')
diff --git a/rhodecode/templates/admin/users/user_edit_my_account.html b/rhodecode/templates/admin/users/user_edit_my_account.html
--- a/rhodecode/templates/admin/users/user_edit_my_account.html
+++ b/rhodecode/templates/admin/users/user_edit_my_account.html
@@ -136,7 +136,7 @@
%endif
- ${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']:
${("r%s:%s") % (h.get_changeset_safe(repo['repo'],'tip').revision,h.short_id(h.get_changeset_safe(repo['repo'],'tip').raw_id))} |
- |
+ |
- ${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()}
|
diff --git a/rhodecode/templates/files/files_annotate.html b/rhodecode/templates/files/files_annotate.html
--- a/rhodecode/templates/files/files_annotate.html
+++ b/rhodecode/templates/files/files_annotate.html
@@ -67,7 +67,7 @@
${_('Binary file')}
%else:
% 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")}
%else:
${_('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))}
diff --git a/rhodecode/templates/repo_switcher_list.html b/rhodecode/templates/repo_switcher_list.html
--- a/rhodecode/templates/repo_switcher_list.html
+++ b/rhodecode/templates/repo_switcher_list.html
@@ -4,7 +4,7 @@
%if repo['dbrepo']['private']:
- ${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'])}
%else:
diff --git a/rhodecode/templates/summary/summary.html b/rhodecode/templates/summary/summary.html
--- a/rhodecode/templates/summary/summary.html
+++ b/rhodecode/templates/summary/summary.html
@@ -7,7 +7,7 @@
<%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>
@@ -31,6 +31,17 @@
- ${h.age(c.repo.last_change)} - ${c.repo.last_change}
- ${_('by')} ${h.get_changeset_safe(c.repo,'tip').author}
+ ${'r%s:%s' % (h.get_changeset_safe(c.rhodecode_repo,'tip').revision,
+ h.get_changeset_safe(c.rhodecode_repo,'tip').short_id)} -
+
+ ${h.age(c.rhodecode_repo.last_change)}
+ ${_('by')} ${h.get_changeset_safe(c.rhodecode_repo,'tip').author}
@@ -138,7 +141,7 @@
- %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')}
@@ -146,14 +149,14 @@
[${h.link_to(_('enable'),h.url('edit_repo',repo_name=c.repo_name))}]
%endif
%else:
- ${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:
|
%endif
${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")}
%endfor
%endif
@@ -166,11 +169,11 @@
%if c.rhodecode_user.username != 'default':
- ${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')}
%else:
- ${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')}
%endif
@@ -265,9 +268,9 @@
YUE.on('download_options','change',function(e){
var new_cs = e.target.options[e.target.selectedIndex];
var tmpl_links = {}
- %for cnt,archive in enumerate(c.repo._get_archives()):
+ %for cnt,archive in enumerate(c.rhodecode_repo._get_archives()):
tmpl_links['${archive['type']}'] = '${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='__CS__'+archive['extension']),class_="archive_icon")}';
%endfor
diff --git a/rhodecode/tests/functional/test_repos_groups.py b/rhodecode/tests/functional/test_repos_groups.py
new file mode 100644
--- /dev/null
+++ b/rhodecode/tests/functional/test_repos_groups.py
@@ -0,0 +1,43 @@
+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'))