##// END OF EJS Templates
tags/branches/bookmarks: moved views into pyramid.
marcink -
r1746:198df317 default
parent child Browse files
Show More
@@ -0,0 +1,50 b''
1 # -*- coding: utf-8 -*-
2
3 # Copyright (C) 2011-2017 RhodeCode GmbH
4 #
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 import logging
21
22 from pyramid.httpexceptions import HTTPNotFound
23 from pyramid.view import view_config
24
25 from rhodecode.apps._base import BaseReferencesView
26 from rhodecode.lib.auth import (LoginRequired, HasRepoPermissionAnyDecorator)
27 from rhodecode.lib import helpers as h
28
29 log = logging.getLogger(__name__)
30
31
32 class RepoBookmarksView(BaseReferencesView):
33
34 @LoginRequired()
35 @HasRepoPermissionAnyDecorator(
36 'repository.read', 'repository.write', 'repository.admin')
37 @view_config(
38 route_name='bookmarks_home', request_method='GET',
39 renderer='rhodecode:templates/bookmarks/bookmarks.mako')
40 def bookmarks(self):
41 c = self.load_default_context()
42
43 if not h.is_hg(self.db_repo):
44 raise HTTPNotFound()
45
46 ref_items = self.rhodecode_vcs_repo.bookmarks.items()
47 self.load_refs_context(
48 ref_items=ref_items, partials_template='bookmarks/bookmarks_data.mako')
49
50 return self._get_template_context(c)
@@ -0,0 +1,51 b''
1 # -*- coding: utf-8 -*-
2
3 # Copyright (C) 2011-2017 RhodeCode GmbH
4 #
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
21 import logging
22 from pyramid.view import view_config
23
24 from rhodecode.apps._base import BaseReferencesView
25 from rhodecode.lib.auth import (LoginRequired, HasRepoPermissionAnyDecorator)
26
27
28 log = logging.getLogger(__name__)
29
30
31 class RepoBranchesView(BaseReferencesView):
32
33 @LoginRequired()
34 @HasRepoPermissionAnyDecorator(
35 'repository.read', 'repository.write', 'repository.admin')
36 @view_config(
37 route_name='branches_home', request_method='GET',
38 renderer='rhodecode:templates/branches/branches.mako')
39 def branches(self):
40 c = self.load_default_context()
41 c.closed_branches = self.rhodecode_vcs_repo.branches_closed
42 # NOTE(marcink):
43 # we need this trick because of PartialRenderer still uses the
44 # global 'c', we might not need this after full pylons migration
45 self._register_global_c(c)
46
47 ref_items = self.rhodecode_vcs_repo.branches_all.items()
48 self.load_refs_context(
49 ref_items=ref_items, partials_template='branches/branches_data.mako')
50
51 return self._get_template_context(c)
@@ -0,0 +1,45 b''
1 # -*- coding: utf-8 -*-
2
3 # Copyright (C) 2011-2017 RhodeCode GmbH
4 #
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
21 import logging
22 from pyramid.view import view_config
23
24 from rhodecode.apps._base import BaseReferencesView
25 from rhodecode.lib.auth import (LoginRequired, HasRepoPermissionAnyDecorator)
26
27 log = logging.getLogger(__name__)
28
29
30 class RepoTagsView(BaseReferencesView):
31
32 @LoginRequired()
33 @HasRepoPermissionAnyDecorator(
34 'repository.read', 'repository.write', 'repository.admin')
35 @view_config(
36 route_name='tags_home', request_method='GET',
37 renderer='rhodecode:templates/tags/tags.mako')
38 def tags(self):
39 c = self.load_default_context()
40
41 ref_items = self.rhodecode_vcs_repo.tags.items()
42 self.load_refs_context(
43 ref_items=ref_items, partials_template='tags/tags_data.mako')
44
45 return self._get_template_context(c)
@@ -24,8 +24,10 b' from pylons import tmpl_context as c'
24 24 from pyramid.httpexceptions import HTTPFound
25 25
26 26 from rhodecode.lib import helpers as h
27 from rhodecode.lib.utils2 import StrictAttributeDict, safe_int
27 from rhodecode.lib.utils import PartialRenderer
28 from rhodecode.lib.utils2 import StrictAttributeDict, safe_int, datetime_to_time
28 29 from rhodecode.lib.vcs.exceptions import RepositoryRequirementError
30 from rhodecode.lib.ext_json import json
29 31 from rhodecode.model import repo
30 32 from rhodecode.model.db import User
31 33 from rhodecode.model.scm import ScmModel
@@ -37,6 +39,24 b" ADMIN_PREFIX = '/_admin'"
37 39 STATIC_FILE_PREFIX = '/_static'
38 40
39 41
42 def get_format_ref_id(repo):
43 """Returns a `repo` specific reference formatter function"""
44 if h.is_svn(repo):
45 return _format_ref_id_svn
46 else:
47 return _format_ref_id
48
49
50 def _format_ref_id(name, raw_id):
51 """Default formatting of a given reference `name`"""
52 return name
53
54
55 def _format_ref_id_svn(name, raw_id):
56 """Special way of formatting a reference for Subversion including path"""
57 return '%s@%s' % (name, raw_id)
58
59
40 60 class TemplateArgs(StrictAttributeDict):
41 61 pass
42 62
@@ -170,6 +190,56 b' class DataGridAppView(object):'
170 190 return draw, start, length
171 191
172 192
193 class BaseReferencesView(RepoAppView):
194 """
195 Base for reference view for branches, tags and bookmarks.
196 """
197 def load_default_context(self):
198 c = self._get_local_tmpl_context()
199
200 # TODO(marcink): remove repo_info and use c.rhodecode_db_repo instead
201 c.repo_info = self.db_repo
202
203 self._register_global_c(c)
204 return c
205
206 def load_refs_context(self, ref_items, partials_template):
207 _render = PartialRenderer(partials_template)
208 _data = []
209 pre_load = ["author", "date", "message"]
210
211 is_svn = h.is_svn(self.rhodecode_vcs_repo)
212 format_ref_id = get_format_ref_id(self.rhodecode_vcs_repo)
213
214 for ref_name, commit_id in ref_items:
215 commit = self.rhodecode_vcs_repo.get_commit(
216 commit_id=commit_id, pre_load=pre_load)
217
218 # TODO: johbo: Unify generation of reference links
219 use_commit_id = '/' in ref_name or is_svn
220 files_url = h.url(
221 'files_home',
222 repo_name=c.repo_name,
223 f_path=ref_name if is_svn else '',
224 revision=commit_id if use_commit_id else ref_name,
225 at=ref_name)
226
227 _data.append({
228 "name": _render('name', ref_name, files_url),
229 "name_raw": ref_name,
230 "date": _render('date', commit.date),
231 "date_raw": datetime_to_time(commit.date),
232 "author": _render('author', commit.author),
233 "commit": _render(
234 'commit', commit.message, commit.raw_id, commit.idx),
235 "commit_raw": commit.idx,
236 "compare": _render(
237 'compare', format_ref_id(ref_name, commit.raw_id)),
238 })
239 c.has_references = bool(_data)
240 c.data = json.dumps(_data)
241
242
173 243 class RepoRoutePredicate(object):
174 244 def __init__(self, val, config):
175 245 self.val = val
@@ -21,6 +21,21 b''
21 21
22 22 def includeme(config):
23 23
24 # Tags
25 config.add_route(
26 name='tags_home',
27 pattern='/{repo_name:.*?[^/]}/tags', repo_route=True)
28
29 # Branches
30 config.add_route(
31 name='branches_home',
32 pattern='/{repo_name:.*?[^/]}/branches', repo_route=True)
33
34 # Bookmarks
35 config.add_route(
36 name='bookmarks_home',
37 pattern='/{repo_name:.*?[^/]}/bookmarks', repo_route=True)
38
24 39 # Settings
25 40 config.add_route(
26 41 name='edit_repo',
@@ -18,24 +18,35 b''
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 import pytest
21 22 from rhodecode.model.db import Repository
22 from rhodecode.tests import *
23 23
24 24
25 class TestBookmarksController(TestController):
25 def route_path(name, params=None, **kwargs):
26 import urllib
27
28 base_url = {
29 'bookmarks_home': '/{repo_name}/bookmarks',
30 }[name].format(**kwargs)
31
32 if params:
33 base_url = '{}?{}'.format(base_url, urllib.urlencode(params))
34 return base_url
35
36
37 @pytest.mark.usefixtures('autologin_user', 'app')
38 class TestBookmarks(object):
26 39
27 40 def test_index(self, backend):
28 self.log_user()
29 41 if backend.alias == 'hg':
30 response = self.app.get(url(controller='bookmarks',
31 action='index',
32 repo_name=backend.repo_name))
42 response = self.app.get(
43 route_path('bookmarks_home', repo_name=backend.repo_name))
33 44
34 45 repo = Repository.get_by_repo_name(backend.repo_name)
35 46 for commit_id, obj_name in repo.scm_instance().bookmarks.items():
36 47 assert commit_id in response
37 48 assert obj_name in response
38 49 else:
39 self.app.get(url(controller='bookmarks',
40 action='index',
41 repo_name=backend.repo_name), status=404) No newline at end of file
50 self.app.get(
51 route_path('bookmarks_home', repo_name=backend.repo_name),
52 status=404)
@@ -18,17 +18,28 b''
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 import pytest
21 22 from rhodecode.model.db import Repository
22 from rhodecode.tests import *
23 23
24 24
25 class TestBranchesController(TestController):
25 def route_path(name, params=None, **kwargs):
26 import urllib
27
28 base_url = {
29 'branches_home': '/{repo_name}/branches',
30 }[name].format(**kwargs)
31
32 if params:
33 base_url = '{}?{}'.format(base_url, urllib.urlencode(params))
34 return base_url
35
36
37 @pytest.mark.usefixtures('autologin_user', 'app')
38 class TestBranchesController(object):
26 39
27 40 def test_index(self, backend):
28 self.log_user()
29 response = self.app.get(url(controller='branches',
30 action='index',
31 repo_name=backend.repo_name))
41 response = self.app.get(
42 route_path('branches_home', repo_name=backend.repo_name))
32 43
33 44 repo = Repository.get_by_repo_name(backend.repo_name)
34 45
@@ -18,16 +18,27 b''
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 import pytest
21 22 from rhodecode.model.db import Repository
22 from rhodecode.tests import *
23 23
24 24
25 class TestTagsController(TestController):
25 def route_path(name, params=None, **kwargs):
26 import urllib
27
28 base_url = {
29 'tags_home': '/{repo_name}/tags',
30 }[name].format(**kwargs)
31
32 if params:
33 base_url = '{}?{}'.format(base_url, urllib.urlencode(params))
34 return base_url
35
36
37 @pytest.mark.usefixtures('autologin_user', 'app')
38 class TestTagsController(object):
26 39 def test_index(self, backend):
27 self.log_user()
28 response = self.app.get(url(controller='tags',
29 action='index',
30 repo_name=backend.repo_name))
40 response = self.app.get(
41 route_path('tags_home', repo_name=backend.repo_name))
31 42
32 43 repo = Repository.get_by_repo_name(backend.repo_name)
33 44
@@ -890,18 +890,6 b' def make_map(config):'
890 890 controller='summary', conditions={'function': check_repo},
891 891 requirements=URL_NAME_REQUIREMENTS)
892 892
893 rmap.connect('branches_home', '/{repo_name}/branches',
894 controller='branches', conditions={'function': check_repo},
895 requirements=URL_NAME_REQUIREMENTS)
896
897 rmap.connect('tags_home', '/{repo_name}/tags',
898 controller='tags', conditions={'function': check_repo},
899 requirements=URL_NAME_REQUIREMENTS)
900
901 rmap.connect('bookmarks_home', '/{repo_name}/bookmarks',
902 controller='bookmarks', conditions={'function': check_repo},
903 requirements=URL_NAME_REQUIREMENTS)
904
905 893 rmap.connect('changelog_home', '/{repo_name}/changelog', jsroute=True,
906 894 controller='changelog', conditions={'function': check_repo},
907 895 requirements=URL_NAME_REQUIREMENTS)
@@ -96,6 +96,9 b' function registerRCRoutes() {'
96 96 pyroutes.register('user_group_autocomplete_data', '/_user_groups', []);
97 97 pyroutes.register('repo_list_data', '/_repos', []);
98 98 pyroutes.register('goto_switcher_data', '/_goto_data', []);
99 pyroutes.register('tags_home', '/%(repo_name)s/tags', ['repo_name']);
100 pyroutes.register('branches_home', '/%(repo_name)s/branches', ['repo_name']);
101 pyroutes.register('bookmarks_home', '/%(repo_name)s/bookmarks', ['repo_name']);
99 102 pyroutes.register('edit_repo', '/%(repo_name)s/settings', ['repo_name']);
100 103 pyroutes.register('edit_repo_caches', '/%(repo_name)s/settings/caches', ['repo_name']);
101 104 pyroutes.register('edit_repo_perms', '/%(repo_name)s/settings/permissions', ['repo_name']);
@@ -1,27 +1,27 b''
1 1 <%def name="refs_counters(branches, closed_branches, tags, bookmarks)">
2 2 <span class="branchtag tag">
3 <a href="${h.url('branches_home',repo_name=c.repo_name)}" class="childs">
3 <a href="${h.route_path('branches_home',repo_name=c.repo_name)}" class="childs">
4 4 <i class="icon-branch"></i>${ungettext(
5 5 '%(num)s Branch','%(num)s Branches', len(branches)) % {'num': len(branches)}}</a>
6 6 </span>
7 7
8 8 %if closed_branches:
9 9 <span class="branchtag tag">
10 <a href="${h.url('branches_home',repo_name=c.repo_name)}" class="childs">
10 <a href="${h.route_path('branches_home',repo_name=c.repo_name)}" class="childs">
11 11 <i class="icon-branch"></i>${ungettext(
12 12 '%(num)s Closed Branch', '%(num)s Closed Branches', len(closed_branches)) % {'num': len(closed_branches)}}</a>
13 13 </span>
14 14 %endif
15 15
16 16 <span class="tagtag tag">
17 <a href="${h.url('tags_home',repo_name=c.repo_name)}" class="childs">
17 <a href="${h.route_path('tags_home',repo_name=c.repo_name)}" class="childs">
18 18 <i class="icon-tag"></i>${ungettext(
19 19 '%(num)s Tag', '%(num)s Tags', len(tags)) % {'num': len(tags)}}</a>
20 20 </span>
21 21
22 22 %if bookmarks:
23 23 <span class="booktag tag">
24 <a href="${h.url('bookmarks_home',repo_name=c.repo_name)}" class="childs">
24 <a href="${h.route_path('bookmarks_home',repo_name=c.repo_name)}" class="childs">
25 25 <i class="icon-bookmark"></i>${ungettext(
26 26 '%(num)s Bookmark', '%(num)s Bookmarks', len(bookmarks)) % {'num': len(bookmarks)}}</a>
27 27 </span>
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now