##// 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 from pyramid.httpexceptions import HTTPFound
24 from pyramid.httpexceptions import HTTPFound
25
25
26 from rhodecode.lib import helpers as h
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 from rhodecode.lib.vcs.exceptions import RepositoryRequirementError
29 from rhodecode.lib.vcs.exceptions import RepositoryRequirementError
30 from rhodecode.lib.ext_json import json
29 from rhodecode.model import repo
31 from rhodecode.model import repo
30 from rhodecode.model.db import User
32 from rhodecode.model.db import User
31 from rhodecode.model.scm import ScmModel
33 from rhodecode.model.scm import ScmModel
@@ -37,6 +39,24 b" ADMIN_PREFIX = '/_admin'"
37 STATIC_FILE_PREFIX = '/_static'
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 class TemplateArgs(StrictAttributeDict):
60 class TemplateArgs(StrictAttributeDict):
41 pass
61 pass
42
62
@@ -170,6 +190,56 b' class DataGridAppView(object):'
170 return draw, start, length
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 class RepoRoutePredicate(object):
243 class RepoRoutePredicate(object):
174 def __init__(self, val, config):
244 def __init__(self, val, config):
175 self.val = val
245 self.val = val
@@ -21,6 +21,21 b''
21
21
22 def includeme(config):
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 # Settings
39 # Settings
25 config.add_route(
40 config.add_route(
26 name='edit_repo',
41 name='edit_repo',
@@ -18,24 +18,35 b''
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import pytest
21 from rhodecode.model.db import Repository
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 def test_index(self, backend):
40 def test_index(self, backend):
28 self.log_user()
29 if backend.alias == 'hg':
41 if backend.alias == 'hg':
30 response = self.app.get(url(controller='bookmarks',
42 response = self.app.get(
31 action='index',
43 route_path('bookmarks_home', repo_name=backend.repo_name))
32 repo_name=backend.repo_name))
33
44
34 repo = Repository.get_by_repo_name(backend.repo_name)
45 repo = Repository.get_by_repo_name(backend.repo_name)
35 for commit_id, obj_name in repo.scm_instance().bookmarks.items():
46 for commit_id, obj_name in repo.scm_instance().bookmarks.items():
36 assert commit_id in response
47 assert commit_id in response
37 assert obj_name in response
48 assert obj_name in response
38 else:
49 else:
39 self.app.get(url(controller='bookmarks',
50 self.app.get(
40 action='index',
51 route_path('bookmarks_home', repo_name=backend.repo_name),
41 repo_name=backend.repo_name), status=404) No newline at end of file
52 status=404)
@@ -18,17 +18,28 b''
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import pytest
21 from rhodecode.model.db import Repository
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 def test_index(self, backend):
40 def test_index(self, backend):
28 self.log_user()
41 response = self.app.get(
29 response = self.app.get(url(controller='branches',
42 route_path('branches_home', repo_name=backend.repo_name))
30 action='index',
31 repo_name=backend.repo_name))
32
43
33 repo = Repository.get_by_repo_name(backend.repo_name)
44 repo = Repository.get_by_repo_name(backend.repo_name)
34
45
@@ -18,16 +18,27 b''
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import pytest
21 from rhodecode.model.db import Repository
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 def test_index(self, backend):
39 def test_index(self, backend):
27 self.log_user()
40 response = self.app.get(
28 response = self.app.get(url(controller='tags',
41 route_path('tags_home', repo_name=backend.repo_name))
29 action='index',
30 repo_name=backend.repo_name))
31
42
32 repo = Repository.get_by_repo_name(backend.repo_name)
43 repo = Repository.get_by_repo_name(backend.repo_name)
33
44
@@ -890,18 +890,6 b' def make_map(config):'
890 controller='summary', conditions={'function': check_repo},
890 controller='summary', conditions={'function': check_repo},
891 requirements=URL_NAME_REQUIREMENTS)
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 rmap.connect('changelog_home', '/{repo_name}/changelog', jsroute=True,
893 rmap.connect('changelog_home', '/{repo_name}/changelog', jsroute=True,
906 controller='changelog', conditions={'function': check_repo},
894 controller='changelog', conditions={'function': check_repo},
907 requirements=URL_NAME_REQUIREMENTS)
895 requirements=URL_NAME_REQUIREMENTS)
@@ -96,6 +96,9 b' function registerRCRoutes() {'
96 pyroutes.register('user_group_autocomplete_data', '/_user_groups', []);
96 pyroutes.register('user_group_autocomplete_data', '/_user_groups', []);
97 pyroutes.register('repo_list_data', '/_repos', []);
97 pyroutes.register('repo_list_data', '/_repos', []);
98 pyroutes.register('goto_switcher_data', '/_goto_data', []);
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 pyroutes.register('edit_repo', '/%(repo_name)s/settings', ['repo_name']);
102 pyroutes.register('edit_repo', '/%(repo_name)s/settings', ['repo_name']);
100 pyroutes.register('edit_repo_caches', '/%(repo_name)s/settings/caches', ['repo_name']);
103 pyroutes.register('edit_repo_caches', '/%(repo_name)s/settings/caches', ['repo_name']);
101 pyroutes.register('edit_repo_perms', '/%(repo_name)s/settings/permissions', ['repo_name']);
104 pyroutes.register('edit_repo_perms', '/%(repo_name)s/settings/permissions', ['repo_name']);
@@ -1,27 +1,27 b''
1 <%def name="refs_counters(branches, closed_branches, tags, bookmarks)">
1 <%def name="refs_counters(branches, closed_branches, tags, bookmarks)">
2 <span class="branchtag tag">
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 <i class="icon-branch"></i>${ungettext(
4 <i class="icon-branch"></i>${ungettext(
5 '%(num)s Branch','%(num)s Branches', len(branches)) % {'num': len(branches)}}</a>
5 '%(num)s Branch','%(num)s Branches', len(branches)) % {'num': len(branches)}}</a>
6 </span>
6 </span>
7
7
8 %if closed_branches:
8 %if closed_branches:
9 <span class="branchtag tag">
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 <i class="icon-branch"></i>${ungettext(
11 <i class="icon-branch"></i>${ungettext(
12 '%(num)s Closed Branch', '%(num)s Closed Branches', len(closed_branches)) % {'num': len(closed_branches)}}</a>
12 '%(num)s Closed Branch', '%(num)s Closed Branches', len(closed_branches)) % {'num': len(closed_branches)}}</a>
13 </span>
13 </span>
14 %endif
14 %endif
15
15
16 <span class="tagtag tag">
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 <i class="icon-tag"></i>${ungettext(
18 <i class="icon-tag"></i>${ungettext(
19 '%(num)s Tag', '%(num)s Tags', len(tags)) % {'num': len(tags)}}</a>
19 '%(num)s Tag', '%(num)s Tags', len(tags)) % {'num': len(tags)}}</a>
20 </span>
20 </span>
21
21
22 %if bookmarks:
22 %if bookmarks:
23 <span class="booktag tag">
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 <i class="icon-bookmark"></i>${ungettext(
25 <i class="icon-bookmark"></i>${ungettext(
26 '%(num)s Bookmark', '%(num)s Bookmarks', len(bookmarks)) % {'num': len(bookmarks)}}</a>
26 '%(num)s Bookmark', '%(num)s Bookmarks', len(bookmarks)) % {'num': len(bookmarks)}}</a>
27 </span>
27 </span>
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now