##// END OF EJS Templates
repo-feed: moved from pylons controller to pyramid views.
dan -
r1899:4c10034c default
parent child Browse files
Show More
@@ -0,0 +1,203 b''
1 # -*- coding: utf-8 -*-
2
3 # Copyright (C) 2017-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 pytz
22 import logging
23
24 from beaker.cache import cache_region
25 from pyramid.view import view_config
26 from pyramid.response import Response
27 from webhelpers.feedgenerator import Rss201rev2Feed, Atom1Feed
28
29 from rhodecode.apps._base import RepoAppView
30 from rhodecode.lib import audit_logger
31 from rhodecode.lib import helpers as h
32 from rhodecode.lib.auth import (LoginRequired, HasRepoPermissionAnyDecorator,
33 NotAnonymous, CSRFRequired)
34 from rhodecode.lib.diffs import DiffProcessor, LimitedDiffContainer
35 from rhodecode.lib.ext_json import json
36 from rhodecode.lib.utils2 import str2bool, safe_int
37 from rhodecode.model.db import UserApiKeys, CacheKey
38
39 log = logging.getLogger(__name__)
40
41
42 class RepoFeedView(RepoAppView):
43 def load_default_context(self):
44 c = self._get_local_tmpl_context()
45
46 # TODO(marcink): remove repo_info and use c.rhodecode_db_repo instead
47 c.repo_info = self.db_repo
48
49 self._register_global_c(c)
50 self._load_defaults()
51 return c
52
53 def _get_config(self):
54 import rhodecode
55 config = rhodecode.CONFIG
56
57 return {
58 'language': 'en-us',
59 'feed_ttl': '5', # TTL of feed,
60 'feed_include_diff':
61 str2bool(config.get('rss_include_diff', False)),
62 'feed_items_per_page':
63 safe_int(config.get('rss_items_per_page', 20)),
64 'feed_diff_limit':
65 # we need to protect from parsing huge diffs here other way
66 # we can kill the server
67 safe_int(config.get('rss_cut_off_limit', 32 * 1024)),
68 }
69
70 def _load_defaults(self):
71 _ = self.request.translate
72 config = self._get_config()
73 # common values for feeds
74 self.description = _('Changes on %s repository')
75 self.title = self.title = _('%s %s feed') % (self.db_repo_name, '%s')
76 self.language = config["language"]
77 self.ttl = config["feed_ttl"]
78 self.feed_include_diff = config['feed_include_diff']
79 self.feed_diff_limit = config['feed_diff_limit']
80 self.feed_items_per_page = config['feed_items_per_page']
81
82 def _changes(self, commit):
83 diff_processor = DiffProcessor(
84 commit.diff(), diff_limit=self.feed_diff_limit)
85 _parsed = diff_processor.prepare(inline_diff=False)
86 limited_diff = isinstance(_parsed, LimitedDiffContainer)
87
88 return _parsed, limited_diff
89
90 def _get_title(self, commit):
91 return h.shorter(commit.message, 160)
92
93 def _get_description(self, commit):
94 _renderer = self.request.get_partial_renderer(
95 'feed/atom_feed_entry.mako')
96 parsed_diff, limited_diff = self._changes(commit)
97 return _renderer(
98 'body',
99 commit=commit,
100 parsed_diff=parsed_diff,
101 limited_diff=limited_diff,
102 feed_include_diff=self.feed_include_diff,
103 )
104
105 def _set_timezone(self, date, tzinfo=pytz.utc):
106 if not getattr(date, "tzinfo", None):
107 date.replace(tzinfo=tzinfo)
108 return date
109
110 def _get_commits(self):
111 return list(self.rhodecode_vcs_repo[-self.feed_items_per_page:])
112
113 @LoginRequired(auth_token_access=[UserApiKeys.ROLE_FEED])
114 @HasRepoPermissionAnyDecorator(
115 'repository.read', 'repository.write', 'repository.admin')
116 @view_config(
117 route_name='atom_feed_home', request_method='GET',
118 renderer=None)
119 def atom(self):
120 """
121 Produce an atom-1.0 feed via feedgenerator module
122 """
123 self.load_default_context()
124
125 @cache_region('long_term')
126 def _generate_feed(cache_key):
127 feed = Atom1Feed(
128 title=self.title % self.db_repo_name,
129 link=h.route_url('repo_summary', repo_name=self.db_repo_name),
130 description=self.description % self.db_repo_name,
131 language=self.language,
132 ttl=self.ttl
133 )
134
135 for commit in reversed(self._get_commits()):
136 date = self._set_timezone(commit.date)
137 feed.add_item(
138 title=self._get_title(commit),
139 author_name=commit.author,
140 description=self._get_description(commit),
141 link=h.route_url(
142 'changeset_home', repo_name=self.db_repo_name,
143 revision=commit.raw_id),
144 pubdate=date,)
145
146 return feed.mime_type, feed.writeString('utf-8')
147
148 invalidator_context = CacheKey.repo_context_cache(
149 _generate_feed, self.db_repo_name, CacheKey.CACHE_TYPE_ATOM)
150
151 with invalidator_context as context:
152 context.invalidate()
153 mime_type, feed = context.compute()
154
155 response = Response(feed)
156 response.content_type = mime_type
157 return response
158
159 @LoginRequired(auth_token_access=[UserApiKeys.ROLE_FEED])
160 @HasRepoPermissionAnyDecorator(
161 'repository.read', 'repository.write', 'repository.admin')
162 @view_config(
163 route_name='rss_feed_home', request_method='GET',
164 renderer=None)
165 def rss(self):
166 """
167 Produce an rss2 feed via feedgenerator module
168 """
169 self.load_default_context()
170
171 @cache_region('long_term')
172 def _generate_feed(cache_key):
173 feed = Rss201rev2Feed(
174 title=self.title % self.db_repo_name,
175 link=h.route_url('repo_summary', repo_name=self.db_repo_name),
176 description=self.description % self.db_repo_name,
177 language=self.language,
178 ttl=self.ttl
179 )
180
181 for commit in reversed(self._get_commits()):
182 date = self._set_timezone(commit.date)
183 feed.add_item(
184 title=self._get_title(commit),
185 author_name=commit.author,
186 description=self._get_description(commit),
187 link=h.route_url(
188 'changeset_home', repo_name=self.db_repo_name,
189 revision=commit.raw_id),
190 pubdate=date,)
191
192 return feed.mime_type, feed.writeString('utf-8')
193
194 invalidator_context = CacheKey.repo_context_cache(
195 _generate_feed, self.db_repo_name, CacheKey.CACHE_TYPE_RSS)
196
197 with invalidator_context as context:
198 context.invalidate()
199 mime_type, feed = context.compute()
200
201 response = Response(feed)
202 response.content_type = mime_type
203 return response
@@ -1,153 +1,177 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2016-2017 RhodeCode GmbH
4 4 #
5 5 # This program is free software: you can redistribute it and/or modify
6 6 # it under the terms of the GNU Affero General Public License, version 3
7 7 # (only), as published by the Free Software Foundation.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU Affero General Public License
15 15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 16 #
17 17 # This program is dual-licensed. If you wish to learn more about the
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 from rhodecode.apps._base import add_route_with_slash
21 21
22 22
23 23 def includeme(config):
24 24
25 25 # Summary
26 26 # NOTE(marcink): one additional route is defined in very bottom, catch
27 27 # all pattern
28 28 config.add_route(
29 29 name='repo_summary_explicit',
30 30 pattern='/{repo_name:.*?[^/]}/summary', repo_route=True)
31 31 config.add_route(
32 32 name='repo_summary_commits',
33 33 pattern='/{repo_name:.*?[^/]}/summary-commits', repo_route=True)
34 34
35 35 # repo commits
36 36 config.add_route(
37 37 name='repo_commit',
38 38 pattern='/{repo_name:.*?[^/]}/changeset/{commit_id}', repo_route=True)
39 39
40 40 # refs data
41 41 config.add_route(
42 42 name='repo_refs_data',
43 43 pattern='/{repo_name:.*?[^/]}/refs-data', repo_route=True)
44 44
45 45 config.add_route(
46 46 name='repo_refs_changelog_data',
47 47 pattern='/{repo_name:.*?[^/]}/refs-data-changelog', repo_route=True)
48 48
49 49 config.add_route(
50 50 name='repo_stats',
51 51 pattern='/{repo_name:.*?[^/]}/repo_stats/{commit_id}', repo_route=True)
52 52
53 53 # Tags
54 54 config.add_route(
55 55 name='tags_home',
56 56 pattern='/{repo_name:.*?[^/]}/tags', repo_route=True)
57 57
58 58 # Branches
59 59 config.add_route(
60 60 name='branches_home',
61 61 pattern='/{repo_name:.*?[^/]}/branches', repo_route=True)
62 62
63 63 config.add_route(
64 64 name='bookmarks_home',
65 65 pattern='/{repo_name:.*?[^/]}/bookmarks', repo_route=True)
66 66
67 67 # Pull Requests
68 68 config.add_route(
69 69 name='pullrequest_show',
70 70 pattern='/{repo_name:.*?[^/]}/pull-request/{pull_request_id}',
71 71 repo_route=True)
72 72
73 73 config.add_route(
74 74 name='pullrequest_show_all',
75 75 pattern='/{repo_name:.*?[^/]}/pull-request',
76 76 repo_route=True, repo_accepted_types=['hg', 'git'])
77 77
78 78 config.add_route(
79 79 name='pullrequest_show_all_data',
80 80 pattern='/{repo_name:.*?[^/]}/pull-request-data',
81 81 repo_route=True, repo_accepted_types=['hg', 'git'])
82 82
83 # commits aka changesets
84 # TODO(dan): handle default landing revision ?
85 config.add_route(
86 name='changeset_home',
87 pattern='/{repo_name:.*?[^/]}/changeset/{revision}',
88 repo_route=True)
89 config.add_route(
90 name='changeset_children',
91 pattern='/{repo_name:.*?[^/]}/changeset_children/{revision}',
92 repo_route=True)
93 config.add_route(
94 name='changeset_parents',
95 pattern='/{repo_name:.*?[^/]}/changeset_parents/{revision}',
96 repo_route=True)
97
83 98 # Settings
84 99 config.add_route(
85 100 name='edit_repo',
86 101 pattern='/{repo_name:.*?[^/]}/settings', repo_route=True)
87 102
88 103 # Settings advanced
89 104 config.add_route(
90 105 name='edit_repo_advanced',
91 106 pattern='/{repo_name:.*?[^/]}/settings/advanced', repo_route=True)
92 107 config.add_route(
93 108 name='edit_repo_advanced_delete',
94 109 pattern='/{repo_name:.*?[^/]}/settings/advanced/delete', repo_route=True)
95 110 config.add_route(
96 111 name='edit_repo_advanced_locking',
97 112 pattern='/{repo_name:.*?[^/]}/settings/advanced/locking', repo_route=True)
98 113 config.add_route(
99 114 name='edit_repo_advanced_journal',
100 115 pattern='/{repo_name:.*?[^/]}/settings/advanced/journal', repo_route=True)
101 116 config.add_route(
102 117 name='edit_repo_advanced_fork',
103 118 pattern='/{repo_name:.*?[^/]}/settings/advanced/fork', repo_route=True)
104 119
105 120 # Caches
106 121 config.add_route(
107 122 name='edit_repo_caches',
108 123 pattern='/{repo_name:.*?[^/]}/settings/caches', repo_route=True)
109 124
110 125 # Permissions
111 126 config.add_route(
112 127 name='edit_repo_perms',
113 128 pattern='/{repo_name:.*?[^/]}/settings/permissions', repo_route=True)
114 129
115 130 # Repo Review Rules
116 131 config.add_route(
117 132 name='repo_reviewers',
118 133 pattern='/{repo_name:.*?[^/]}/settings/review/rules', repo_route=True)
119 134
120 135 config.add_route(
121 136 name='repo_default_reviewers_data',
122 137 pattern='/{repo_name:.*?[^/]}/settings/review/default-reviewers', repo_route=True)
123 138
124 139 # Maintenance
125 140 config.add_route(
126 141 name='repo_maintenance',
127 142 pattern='/{repo_name:.*?[^/]}/settings/maintenance', repo_route=True)
128 143
129 144 config.add_route(
130 145 name='repo_maintenance_execute',
131 146 pattern='/{repo_name:.*?[^/]}/settings/maintenance/execute', repo_route=True)
132 147
133 148 # Strip
134 149 config.add_route(
135 150 name='strip',
136 151 pattern='/{repo_name:.*?[^/]}/settings/strip', repo_route=True)
137 152
138 153 config.add_route(
139 154 name='strip_check',
140 155 pattern='/{repo_name:.*?[^/]}/settings/strip_check', repo_route=True)
141 156
142 157 config.add_route(
143 158 name='strip_execute',
144 159 pattern='/{repo_name:.*?[^/]}/settings/strip_execute', repo_route=True)
145 160
161 # ATOM/RSS Feed
162 config.add_route(
163 name='rss_feed_home',
164 pattern='/{repo_name:.*?[^/]}/feed/rss', repo_route=True)
165
166 config.add_route(
167 name='atom_feed_home',
168 pattern='/{repo_name:.*?[^/]}/feed/atom', repo_route=True)
169
146 170 # NOTE(marcink): needs to be at the end for catch-all
147 171 add_route_with_slash(
148 172 config,
149 173 name='repo_summary',
150 174 pattern='/{repo_name:.*?[^/]}', repo_route=True)
151 175
152 176 # Scan module for configuration decorators.
153 177 config.scan()
@@ -1,75 +1,94 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2010-2017 RhodeCode GmbH
4 4 #
5 5 # This program is free software: you can redistribute it and/or modify
6 6 # it under the terms of the GNU Affero General Public License, version 3
7 7 # (only), as published by the Free Software Foundation.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU Affero General Public License
15 15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 16 #
17 17 # This program is dual-licensed. If you wish to learn more about the
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 import pytest
20 21 from rhodecode.model.auth_token import AuthTokenModel
21 from rhodecode.model.db import User
22 from rhodecode.tests import *
22 from rhodecode.tests import TestController
23
24
25 def route_path(name, params=None, **kwargs):
26 import urllib
27
28 base_url = {
29 'rss_feed_home': '/{repo_name}/feed/rss',
30 'atom_feed_home': '/{repo_name}/feed/atom',
31 }[name].format(**kwargs)
32
33 if params:
34 base_url = '{}?{}'.format(base_url, urllib.urlencode(params))
35 return base_url
23 36
24 37
25 class TestFeedController(TestController):
38 class TestFeedView(TestController):
26 39
27 def test_rss(self, backend):
40 @pytest.mark.parametrize("feed_type,response_types,content_type",[
41 ('rss', ['<rss version="2.0">'],
42 "application/rss+xml"),
43 ('atom', ['<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-us">'],
44 "application/atom+xml"),
45 ])
46 def test_feed(self, backend, feed_type, response_types, content_type):
28 47 self.log_user()
29 response = self.app.get(url(controller='feed', action='rss',
30 repo_name=backend.repo_name))
48 response = self.app.get(
49 route_path('{}_feed_home'.format(feed_type), repo_name=backend.repo_name))
50
51 for content in response_types:
52 assert content in response
31 53
32 assert response.content_type == "application/rss+xml"
33 assert """<rss version="2.0">""" in response
54 assert response.content_type == content_type
34 55
35 def test_rss_with_auth_token(self, backend, user_admin):
56 @pytest.mark.parametrize("feed_type, content_type", [
57 ('rss', "application/rss+xml"),
58 ('atom', "application/atom+xml")
59 ])
60 def test_feed_with_auth_token(
61 self, backend, user_admin, feed_type, content_type):
36 62 auth_token = user_admin.feed_token
37 63 assert auth_token != ''
38 response = self.app.get(
39 url(controller='feed', action='rss',
40 repo_name=backend.repo_name, auth_token=auth_token,
41 status=200))
42 64
43 assert response.content_type == "application/rss+xml"
44 assert """<rss version="2.0">""" in response
65 response = self.app.get(
66 route_path(
67 '{}_feed_home'.format(feed_type), repo_name=backend.repo_name,
68 params=dict(auth_token=auth_token)),
69 status=200)
45 70
46 def test_rss_with_auth_token_of_wrong_type(self, backend, user_util):
71 assert response.content_type == content_type
72
73 @pytest.mark.parametrize("feed_type", ['rss', 'atom'])
74 def test_feed_with_auth_token_of_wrong_type(
75 self, backend, user_util, feed_type):
47 76 user = user_util.create_user()
48 77 auth_token = AuthTokenModel().create(
49 78 user.user_id, 'test-token', -1, AuthTokenModel.cls.ROLE_API)
50 79 auth_token = auth_token.api_key
51 80
52 81 self.app.get(
53 url(controller='feed', action='rss',
54 repo_name=backend.repo_name, auth_token=auth_token),
82 route_path(
83 '{}_feed_home'.format(feed_type), repo_name=backend.repo_name,
84 params=dict(auth_token=auth_token)),
55 85 status=302)
56 86
57 87 auth_token = AuthTokenModel().create(
58 88 user.user_id, 'test-token', -1, AuthTokenModel.cls.ROLE_FEED)
59 89 auth_token = auth_token.api_key
60 90 self.app.get(
61 url(controller='feed', action='rss',
62 repo_name=backend.repo_name, auth_token=auth_token),
91 route_path(
92 '{}_feed_home'.format(feed_type), repo_name=backend.repo_name,
93 params=dict(auth_token=auth_token)),
63 94 status=200)
64
65 def test_atom(self, backend):
66 self.log_user()
67 response = self.app.get(url(controller='feed', action='atom',
68 repo_name=backend.repo_name))
69
70 assert response.content_type == """application/atom+xml"""
71 assert """<?xml version="1.0" encoding="utf-8"?>""" in response
72
73 tag1 = '<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-us">'
74 tag2 = '<feed xml:lang="en-us" xmlns="http://www.w3.org/2005/Atom">'
75 assert tag1 in response or tag2 in response
@@ -1,904 +1,893 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 # Copyright (C) 2010-2017 RhodeCode GmbH
4 4 #
5 5 # This program is free software: you can redistribute it and/or modify
6 6 # it under the terms of the GNU Affero General Public License, version 3
7 7 # (only), as published by the Free Software Foundation.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU Affero General Public License
15 15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 16 #
17 17 # This program is dual-licensed. If you wish to learn more about the
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 21 """
22 22 Routes configuration
23 23
24 24 The more specific and detailed routes should be defined first so they
25 25 may take precedent over the more generic routes. For more information
26 26 refer to the routes manual at http://routes.groovie.org/docs/
27 27
28 28 IMPORTANT: if you change any routing here, make sure to take a look at lib/base.py
29 29 and _route_name variable which uses some of stored naming here to do redirects.
30 30 """
31 31 import os
32 32 import re
33 33 from routes import Mapper
34 34
35 35 # prefix for non repository related links needs to be prefixed with `/`
36 36 ADMIN_PREFIX = '/_admin'
37 37 STATIC_FILE_PREFIX = '/_static'
38 38
39 39 # Default requirements for URL parts
40 40 URL_NAME_REQUIREMENTS = {
41 41 # group name can have a slash in them, but they must not end with a slash
42 42 'group_name': r'.*?[^/]',
43 43 'repo_group_name': r'.*?[^/]',
44 44 # repo names can have a slash in them, but they must not end with a slash
45 45 'repo_name': r'.*?[^/]',
46 46 # file path eats up everything at the end
47 47 'f_path': r'.*',
48 48 # reference types
49 49 'source_ref_type': '(branch|book|tag|rev|\%\(source_ref_type\)s)',
50 50 'target_ref_type': '(branch|book|tag|rev|\%\(target_ref_type\)s)',
51 51 }
52 52
53 53
54 54 def add_route_requirements(route_path, requirements):
55 55 """
56 56 Adds regex requirements to pyramid routes using a mapping dict
57 57
58 58 >>> add_route_requirements('/{action}/{id}', {'id': r'\d+'})
59 59 '/{action}/{id:\d+}'
60 60
61 61 """
62 62 for key, regex in requirements.items():
63 63 route_path = route_path.replace('{%s}' % key, '{%s:%s}' % (key, regex))
64 64 return route_path
65 65
66 66
67 67 class JSRoutesMapper(Mapper):
68 68 """
69 69 Wrapper for routes.Mapper to make pyroutes compatible url definitions
70 70 """
71 71 _named_route_regex = re.compile(r'^[a-z-_0-9A-Z]+$')
72 72 _argument_prog = re.compile('\{(.*?)\}|:\((.*)\)')
73 73 def __init__(self, *args, **kw):
74 74 super(JSRoutesMapper, self).__init__(*args, **kw)
75 75 self._jsroutes = []
76 76
77 77 def connect(self, *args, **kw):
78 78 """
79 79 Wrapper for connect to take an extra argument jsroute=True
80 80
81 81 :param jsroute: boolean, if True will add the route to the pyroutes list
82 82 """
83 83 if kw.pop('jsroute', False):
84 84 if not self._named_route_regex.match(args[0]):
85 85 raise Exception('only named routes can be added to pyroutes')
86 86 self._jsroutes.append(args[0])
87 87
88 88 super(JSRoutesMapper, self).connect(*args, **kw)
89 89
90 90 def _extract_route_information(self, route):
91 91 """
92 92 Convert a route into tuple(name, path, args), eg:
93 93 ('show_user', '/profile/%(username)s', ['username'])
94 94 """
95 95 routepath = route.routepath
96 96 def replace(matchobj):
97 97 if matchobj.group(1):
98 98 return "%%(%s)s" % matchobj.group(1).split(':')[0]
99 99 else:
100 100 return "%%(%s)s" % matchobj.group(2)
101 101
102 102 routepath = self._argument_prog.sub(replace, routepath)
103 103 return (
104 104 route.name,
105 105 routepath,
106 106 [(arg[0].split(':')[0] if arg[0] != '' else arg[1])
107 107 for arg in self._argument_prog.findall(route.routepath)]
108 108 )
109 109
110 110 def jsroutes(self):
111 111 """
112 112 Return a list of pyroutes.js compatible routes
113 113 """
114 114 for route_name in self._jsroutes:
115 115 yield self._extract_route_information(self._routenames[route_name])
116 116
117 117
118 118 def make_map(config):
119 119 """Create, configure and return the routes Mapper"""
120 120 rmap = JSRoutesMapper(
121 121 directory=config['pylons.paths']['controllers'],
122 122 always_scan=config['debug'])
123 123 rmap.minimization = False
124 124 rmap.explicit = False
125 125
126 126 from rhodecode.lib.utils2 import str2bool
127 127 from rhodecode.model import repo, repo_group
128 128
129 129 def check_repo(environ, match_dict):
130 130 """
131 131 check for valid repository for proper 404 handling
132 132
133 133 :param environ:
134 134 :param match_dict:
135 135 """
136 136 repo_name = match_dict.get('repo_name')
137 137
138 138 if match_dict.get('f_path'):
139 139 # fix for multiple initial slashes that causes errors
140 140 match_dict['f_path'] = match_dict['f_path'].lstrip('/')
141 141 repo_model = repo.RepoModel()
142 142 by_name_match = repo_model.get_by_repo_name(repo_name)
143 143 # if we match quickly from database, short circuit the operation,
144 144 # and validate repo based on the type.
145 145 if by_name_match:
146 146 return True
147 147
148 148 by_id_match = repo_model.get_repo_by_id(repo_name)
149 149 if by_id_match:
150 150 repo_name = by_id_match.repo_name
151 151 match_dict['repo_name'] = repo_name
152 152 return True
153 153
154 154 return False
155 155
156 156 def check_group(environ, match_dict):
157 157 """
158 158 check for valid repository group path for proper 404 handling
159 159
160 160 :param environ:
161 161 :param match_dict:
162 162 """
163 163 repo_group_name = match_dict.get('group_name')
164 164 repo_group_model = repo_group.RepoGroupModel()
165 165 by_name_match = repo_group_model.get_by_group_name(repo_group_name)
166 166 if by_name_match:
167 167 return True
168 168
169 169 return False
170 170
171 171 def check_user_group(environ, match_dict):
172 172 """
173 173 check for valid user group for proper 404 handling
174 174
175 175 :param environ:
176 176 :param match_dict:
177 177 """
178 178 return True
179 179
180 180 def check_int(environ, match_dict):
181 181 return match_dict.get('id').isdigit()
182 182
183 183
184 184 #==========================================================================
185 185 # CUSTOM ROUTES HERE
186 186 #==========================================================================
187 187
188 188 # ping and pylons error test
189 189 rmap.connect('ping', '%s/ping' % (ADMIN_PREFIX,), controller='home', action='ping')
190 190 rmap.connect('error_test', '%s/error_test' % (ADMIN_PREFIX,), controller='home', action='error_test')
191 191
192 192 # ADMIN REPOSITORY ROUTES
193 193 with rmap.submapper(path_prefix=ADMIN_PREFIX,
194 194 controller='admin/repos') as m:
195 195 m.connect('repos', '/repos',
196 196 action='create', conditions={'method': ['POST']})
197 197 m.connect('repos', '/repos',
198 198 action='index', conditions={'method': ['GET']})
199 199 m.connect('new_repo', '/create_repository', jsroute=True,
200 200 action='create_repository', conditions={'method': ['GET']})
201 201 m.connect('delete_repo', '/repos/{repo_name}',
202 202 action='delete', conditions={'method': ['DELETE']},
203 203 requirements=URL_NAME_REQUIREMENTS)
204 204 m.connect('repo', '/repos/{repo_name}',
205 205 action='show', conditions={'method': ['GET'],
206 206 'function': check_repo},
207 207 requirements=URL_NAME_REQUIREMENTS)
208 208
209 209 # ADMIN REPOSITORY GROUPS ROUTES
210 210 with rmap.submapper(path_prefix=ADMIN_PREFIX,
211 211 controller='admin/repo_groups') as m:
212 212 m.connect('repo_groups', '/repo_groups',
213 213 action='create', conditions={'method': ['POST']})
214 214 m.connect('repo_groups', '/repo_groups',
215 215 action='index', conditions={'method': ['GET']})
216 216 m.connect('new_repo_group', '/repo_groups/new',
217 217 action='new', conditions={'method': ['GET']})
218 218 m.connect('update_repo_group', '/repo_groups/{group_name}',
219 219 action='update', conditions={'method': ['PUT'],
220 220 'function': check_group},
221 221 requirements=URL_NAME_REQUIREMENTS)
222 222
223 223 # EXTRAS REPO GROUP ROUTES
224 224 m.connect('edit_repo_group', '/repo_groups/{group_name}/edit',
225 225 action='edit',
226 226 conditions={'method': ['GET'], 'function': check_group},
227 227 requirements=URL_NAME_REQUIREMENTS)
228 228 m.connect('edit_repo_group', '/repo_groups/{group_name}/edit',
229 229 action='edit',
230 230 conditions={'method': ['PUT'], 'function': check_group},
231 231 requirements=URL_NAME_REQUIREMENTS)
232 232
233 233 m.connect('edit_repo_group_advanced', '/repo_groups/{group_name}/edit/advanced',
234 234 action='edit_repo_group_advanced',
235 235 conditions={'method': ['GET'], 'function': check_group},
236 236 requirements=URL_NAME_REQUIREMENTS)
237 237 m.connect('edit_repo_group_advanced', '/repo_groups/{group_name}/edit/advanced',
238 238 action='edit_repo_group_advanced',
239 239 conditions={'method': ['PUT'], 'function': check_group},
240 240 requirements=URL_NAME_REQUIREMENTS)
241 241
242 242 m.connect('edit_repo_group_perms', '/repo_groups/{group_name}/edit/permissions',
243 243 action='edit_repo_group_perms',
244 244 conditions={'method': ['GET'], 'function': check_group},
245 245 requirements=URL_NAME_REQUIREMENTS)
246 246 m.connect('edit_repo_group_perms', '/repo_groups/{group_name}/edit/permissions',
247 247 action='update_perms',
248 248 conditions={'method': ['PUT'], 'function': check_group},
249 249 requirements=URL_NAME_REQUIREMENTS)
250 250
251 251 m.connect('delete_repo_group', '/repo_groups/{group_name}',
252 252 action='delete', conditions={'method': ['DELETE'],
253 253 'function': check_group},
254 254 requirements=URL_NAME_REQUIREMENTS)
255 255
256 256 # ADMIN USER ROUTES
257 257 with rmap.submapper(path_prefix=ADMIN_PREFIX,
258 258 controller='admin/users') as m:
259 259 m.connect('users', '/users',
260 260 action='create', conditions={'method': ['POST']})
261 261 m.connect('new_user', '/users/new',
262 262 action='new', conditions={'method': ['GET']})
263 263 m.connect('update_user', '/users/{user_id}',
264 264 action='update', conditions={'method': ['PUT']})
265 265 m.connect('delete_user', '/users/{user_id}',
266 266 action='delete', conditions={'method': ['DELETE']})
267 267 m.connect('edit_user', '/users/{user_id}/edit',
268 268 action='edit', conditions={'method': ['GET']}, jsroute=True)
269 269 m.connect('user', '/users/{user_id}',
270 270 action='show', conditions={'method': ['GET']})
271 271 m.connect('force_password_reset_user', '/users/{user_id}/password_reset',
272 272 action='reset_password', conditions={'method': ['POST']})
273 273 m.connect('create_personal_repo_group', '/users/{user_id}/create_repo_group',
274 274 action='create_personal_repo_group', conditions={'method': ['POST']})
275 275
276 276 # EXTRAS USER ROUTES
277 277 m.connect('edit_user_advanced', '/users/{user_id}/edit/advanced',
278 278 action='edit_advanced', conditions={'method': ['GET']})
279 279 m.connect('edit_user_advanced', '/users/{user_id}/edit/advanced',
280 280 action='update_advanced', conditions={'method': ['PUT']})
281 281
282 282 m.connect('edit_user_global_perms', '/users/{user_id}/edit/global_permissions',
283 283 action='edit_global_perms', conditions={'method': ['GET']})
284 284 m.connect('edit_user_global_perms', '/users/{user_id}/edit/global_permissions',
285 285 action='update_global_perms', conditions={'method': ['PUT']})
286 286
287 287 m.connect('edit_user_perms_summary', '/users/{user_id}/edit/permissions_summary',
288 288 action='edit_perms_summary', conditions={'method': ['GET']})
289 289
290 290
291 291 # ADMIN USER GROUPS REST ROUTES
292 292 with rmap.submapper(path_prefix=ADMIN_PREFIX,
293 293 controller='admin/user_groups') as m:
294 294 m.connect('users_groups', '/user_groups',
295 295 action='create', conditions={'method': ['POST']})
296 296 m.connect('users_groups', '/user_groups',
297 297 action='index', conditions={'method': ['GET']})
298 298 m.connect('new_users_group', '/user_groups/new',
299 299 action='new', conditions={'method': ['GET']})
300 300 m.connect('update_users_group', '/user_groups/{user_group_id}',
301 301 action='update', conditions={'method': ['PUT']})
302 302 m.connect('delete_users_group', '/user_groups/{user_group_id}',
303 303 action='delete', conditions={'method': ['DELETE']})
304 304 m.connect('edit_users_group', '/user_groups/{user_group_id}/edit',
305 305 action='edit', conditions={'method': ['GET']},
306 306 function=check_user_group)
307 307
308 308 # EXTRAS USER GROUP ROUTES
309 309 m.connect('edit_user_group_global_perms',
310 310 '/user_groups/{user_group_id}/edit/global_permissions',
311 311 action='edit_global_perms', conditions={'method': ['GET']})
312 312 m.connect('edit_user_group_global_perms',
313 313 '/user_groups/{user_group_id}/edit/global_permissions',
314 314 action='update_global_perms', conditions={'method': ['PUT']})
315 315 m.connect('edit_user_group_perms_summary',
316 316 '/user_groups/{user_group_id}/edit/permissions_summary',
317 317 action='edit_perms_summary', conditions={'method': ['GET']})
318 318
319 319 m.connect('edit_user_group_perms',
320 320 '/user_groups/{user_group_id}/edit/permissions',
321 321 action='edit_perms', conditions={'method': ['GET']})
322 322 m.connect('edit_user_group_perms',
323 323 '/user_groups/{user_group_id}/edit/permissions',
324 324 action='update_perms', conditions={'method': ['PUT']})
325 325
326 326 m.connect('edit_user_group_advanced',
327 327 '/user_groups/{user_group_id}/edit/advanced',
328 328 action='edit_advanced', conditions={'method': ['GET']})
329 329
330 330 m.connect('edit_user_group_advanced_sync',
331 331 '/user_groups/{user_group_id}/edit/advanced/sync',
332 332 action='edit_advanced_set_synchronization', conditions={'method': ['POST']})
333 333
334 334 m.connect('edit_user_group_members',
335 335 '/user_groups/{user_group_id}/edit/members', jsroute=True,
336 336 action='user_group_members', conditions={'method': ['GET']})
337 337
338 338 # ADMIN PERMISSIONS ROUTES
339 339 with rmap.submapper(path_prefix=ADMIN_PREFIX,
340 340 controller='admin/permissions') as m:
341 341 m.connect('admin_permissions_application', '/permissions/application',
342 342 action='permission_application_update', conditions={'method': ['POST']})
343 343 m.connect('admin_permissions_application', '/permissions/application',
344 344 action='permission_application', conditions={'method': ['GET']})
345 345
346 346 m.connect('admin_permissions_global', '/permissions/global',
347 347 action='permission_global_update', conditions={'method': ['POST']})
348 348 m.connect('admin_permissions_global', '/permissions/global',
349 349 action='permission_global', conditions={'method': ['GET']})
350 350
351 351 m.connect('admin_permissions_object', '/permissions/object',
352 352 action='permission_objects_update', conditions={'method': ['POST']})
353 353 m.connect('admin_permissions_object', '/permissions/object',
354 354 action='permission_objects', conditions={'method': ['GET']})
355 355
356 356 m.connect('admin_permissions_ips', '/permissions/ips',
357 357 action='permission_ips', conditions={'method': ['POST']})
358 358 m.connect('admin_permissions_ips', '/permissions/ips',
359 359 action='permission_ips', conditions={'method': ['GET']})
360 360
361 361 m.connect('admin_permissions_overview', '/permissions/overview',
362 362 action='permission_perms', conditions={'method': ['GET']})
363 363
364 364 # ADMIN DEFAULTS REST ROUTES
365 365 with rmap.submapper(path_prefix=ADMIN_PREFIX,
366 366 controller='admin/defaults') as m:
367 367 m.connect('admin_defaults_repositories', '/defaults/repositories',
368 368 action='update_repository_defaults', conditions={'method': ['POST']})
369 369 m.connect('admin_defaults_repositories', '/defaults/repositories',
370 370 action='index', conditions={'method': ['GET']})
371 371
372 372 # ADMIN DEBUG STYLE ROUTES
373 373 if str2bool(config.get('debug_style')):
374 374 with rmap.submapper(path_prefix=ADMIN_PREFIX + '/debug_style',
375 375 controller='debug_style') as m:
376 376 m.connect('debug_style_home', '',
377 377 action='index', conditions={'method': ['GET']})
378 378 m.connect('debug_style_template', '/t/{t_path}',
379 379 action='template', conditions={'method': ['GET']})
380 380
381 381 # ADMIN SETTINGS ROUTES
382 382 with rmap.submapper(path_prefix=ADMIN_PREFIX,
383 383 controller='admin/settings') as m:
384 384
385 385 # default
386 386 m.connect('admin_settings', '/settings',
387 387 action='settings_global_update',
388 388 conditions={'method': ['POST']})
389 389 m.connect('admin_settings', '/settings',
390 390 action='settings_global', conditions={'method': ['GET']})
391 391
392 392 m.connect('admin_settings_vcs', '/settings/vcs',
393 393 action='settings_vcs_update',
394 394 conditions={'method': ['POST']})
395 395 m.connect('admin_settings_vcs', '/settings/vcs',
396 396 action='settings_vcs',
397 397 conditions={'method': ['GET']})
398 398 m.connect('admin_settings_vcs', '/settings/vcs',
399 399 action='delete_svn_pattern',
400 400 conditions={'method': ['DELETE']})
401 401
402 402 m.connect('admin_settings_mapping', '/settings/mapping',
403 403 action='settings_mapping_update',
404 404 conditions={'method': ['POST']})
405 405 m.connect('admin_settings_mapping', '/settings/mapping',
406 406 action='settings_mapping', conditions={'method': ['GET']})
407 407
408 408 m.connect('admin_settings_global', '/settings/global',
409 409 action='settings_global_update',
410 410 conditions={'method': ['POST']})
411 411 m.connect('admin_settings_global', '/settings/global',
412 412 action='settings_global', conditions={'method': ['GET']})
413 413
414 414 m.connect('admin_settings_visual', '/settings/visual',
415 415 action='settings_visual_update',
416 416 conditions={'method': ['POST']})
417 417 m.connect('admin_settings_visual', '/settings/visual',
418 418 action='settings_visual', conditions={'method': ['GET']})
419 419
420 420 m.connect('admin_settings_issuetracker',
421 421 '/settings/issue-tracker', action='settings_issuetracker',
422 422 conditions={'method': ['GET']})
423 423 m.connect('admin_settings_issuetracker_save',
424 424 '/settings/issue-tracker/save',
425 425 action='settings_issuetracker_save',
426 426 conditions={'method': ['POST']})
427 427 m.connect('admin_issuetracker_test', '/settings/issue-tracker/test',
428 428 action='settings_issuetracker_test',
429 429 conditions={'method': ['POST']})
430 430 m.connect('admin_issuetracker_delete',
431 431 '/settings/issue-tracker/delete',
432 432 action='settings_issuetracker_delete',
433 433 conditions={'method': ['DELETE']})
434 434
435 435 m.connect('admin_settings_email', '/settings/email',
436 436 action='settings_email_update',
437 437 conditions={'method': ['POST']})
438 438 m.connect('admin_settings_email', '/settings/email',
439 439 action='settings_email', conditions={'method': ['GET']})
440 440
441 441 m.connect('admin_settings_hooks', '/settings/hooks',
442 442 action='settings_hooks_update',
443 443 conditions={'method': ['POST', 'DELETE']})
444 444 m.connect('admin_settings_hooks', '/settings/hooks',
445 445 action='settings_hooks', conditions={'method': ['GET']})
446 446
447 447 m.connect('admin_settings_search', '/settings/search',
448 448 action='settings_search', conditions={'method': ['GET']})
449 449
450 450 m.connect('admin_settings_supervisor', '/settings/supervisor',
451 451 action='settings_supervisor', conditions={'method': ['GET']})
452 452 m.connect('admin_settings_supervisor_log', '/settings/supervisor/{procid}/log',
453 453 action='settings_supervisor_log', conditions={'method': ['GET']})
454 454
455 455 m.connect('admin_settings_labs', '/settings/labs',
456 456 action='settings_labs_update',
457 457 conditions={'method': ['POST']})
458 458 m.connect('admin_settings_labs', '/settings/labs',
459 459 action='settings_labs', conditions={'method': ['GET']})
460 460
461 461 # ADMIN MY ACCOUNT
462 462 with rmap.submapper(path_prefix=ADMIN_PREFIX,
463 463 controller='admin/my_account') as m:
464 464
465 465 # NOTE(marcink): this needs to be kept for password force flag to be
466 466 # handled in pylons controllers, remove after full migration to pyramid
467 467 m.connect('my_account_password', '/my_account/password',
468 468 action='my_account_password', conditions={'method': ['GET']})
469 469
470 470 # NOTIFICATION REST ROUTES
471 471 with rmap.submapper(path_prefix=ADMIN_PREFIX,
472 472 controller='admin/notifications') as m:
473 473 m.connect('notifications', '/notifications',
474 474 action='index', conditions={'method': ['GET']})
475 475 m.connect('notifications_mark_all_read', '/notifications/mark_all_read',
476 476 action='mark_all_read', conditions={'method': ['POST']})
477 477 m.connect('/notifications/{notification_id}',
478 478 action='update', conditions={'method': ['PUT']})
479 479 m.connect('/notifications/{notification_id}',
480 480 action='delete', conditions={'method': ['DELETE']})
481 481 m.connect('notification', '/notifications/{notification_id}',
482 482 action='show', conditions={'method': ['GET']})
483 483
484 484 # USER JOURNAL
485 485 rmap.connect('journal', '%s/journal' % (ADMIN_PREFIX,),
486 486 controller='journal', action='index')
487 487 rmap.connect('journal_rss', '%s/journal/rss' % (ADMIN_PREFIX,),
488 488 controller='journal', action='journal_rss')
489 489 rmap.connect('journal_atom', '%s/journal/atom' % (ADMIN_PREFIX,),
490 490 controller='journal', action='journal_atom')
491 491
492 492 rmap.connect('public_journal', '%s/public_journal' % (ADMIN_PREFIX,),
493 493 controller='journal', action='public_journal')
494 494
495 495 rmap.connect('public_journal_rss', '%s/public_journal/rss' % (ADMIN_PREFIX,),
496 496 controller='journal', action='public_journal_rss')
497 497
498 498 rmap.connect('public_journal_rss_old', '%s/public_journal_rss' % (ADMIN_PREFIX,),
499 499 controller='journal', action='public_journal_rss')
500 500
501 501 rmap.connect('public_journal_atom',
502 502 '%s/public_journal/atom' % (ADMIN_PREFIX,), controller='journal',
503 503 action='public_journal_atom')
504 504
505 505 rmap.connect('public_journal_atom_old',
506 506 '%s/public_journal_atom' % (ADMIN_PREFIX,), controller='journal',
507 507 action='public_journal_atom')
508 508
509 509 rmap.connect('toggle_following', '%s/toggle_following' % (ADMIN_PREFIX,),
510 510 controller='journal', action='toggle_following', jsroute=True,
511 511 conditions={'method': ['POST']})
512 512
513 # FEEDS
514 rmap.connect('rss_feed_home', '/{repo_name}/feed/rss',
515 controller='feed', action='rss',
516 conditions={'function': check_repo},
517 requirements=URL_NAME_REQUIREMENTS)
518
519 rmap.connect('atom_feed_home', '/{repo_name}/feed/atom',
520 controller='feed', action='atom',
521 conditions={'function': check_repo},
522 requirements=URL_NAME_REQUIREMENTS)
523
524 513 #==========================================================================
525 514 # REPOSITORY ROUTES
526 515 #==========================================================================
527 516
528 517 rmap.connect('repo_creating_home', '/{repo_name}/repo_creating',
529 518 controller='admin/repos', action='repo_creating',
530 519 requirements=URL_NAME_REQUIREMENTS)
531 520 rmap.connect('repo_check_home', '/{repo_name}/crepo_check',
532 521 controller='admin/repos', action='repo_check',
533 522 requirements=URL_NAME_REQUIREMENTS)
534 523
535 524 rmap.connect('changeset_home', '/{repo_name}/changeset/{revision}',
536 525 controller='changeset', revision='tip',
537 526 conditions={'function': check_repo},
538 527 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
539 528 rmap.connect('changeset_children', '/{repo_name}/changeset_children/{revision}',
540 529 controller='changeset', revision='tip', action='changeset_children',
541 530 conditions={'function': check_repo},
542 531 requirements=URL_NAME_REQUIREMENTS)
543 532 rmap.connect('changeset_parents', '/{repo_name}/changeset_parents/{revision}',
544 533 controller='changeset', revision='tip', action='changeset_parents',
545 534 conditions={'function': check_repo},
546 535 requirements=URL_NAME_REQUIREMENTS)
547 536
548 537 # repo edit options
549 538 rmap.connect('edit_repo_fields', '/{repo_name}/settings/fields',
550 539 controller='admin/repos', action='edit_fields',
551 540 conditions={'method': ['GET'], 'function': check_repo},
552 541 requirements=URL_NAME_REQUIREMENTS)
553 542 rmap.connect('create_repo_fields', '/{repo_name}/settings/fields/new',
554 543 controller='admin/repos', action='create_repo_field',
555 544 conditions={'method': ['PUT'], 'function': check_repo},
556 545 requirements=URL_NAME_REQUIREMENTS)
557 546 rmap.connect('delete_repo_fields', '/{repo_name}/settings/fields/{field_id}',
558 547 controller='admin/repos', action='delete_repo_field',
559 548 conditions={'method': ['DELETE'], 'function': check_repo},
560 549 requirements=URL_NAME_REQUIREMENTS)
561 550
562 551 rmap.connect('toggle_locking', '/{repo_name}/settings/advanced/locking_toggle',
563 552 controller='admin/repos', action='toggle_locking',
564 553 conditions={'method': ['GET'], 'function': check_repo},
565 554 requirements=URL_NAME_REQUIREMENTS)
566 555
567 556 rmap.connect('edit_repo_remote', '/{repo_name}/settings/remote',
568 557 controller='admin/repos', action='edit_remote_form',
569 558 conditions={'method': ['GET'], 'function': check_repo},
570 559 requirements=URL_NAME_REQUIREMENTS)
571 560 rmap.connect('edit_repo_remote', '/{repo_name}/settings/remote',
572 561 controller='admin/repos', action='edit_remote',
573 562 conditions={'method': ['PUT'], 'function': check_repo},
574 563 requirements=URL_NAME_REQUIREMENTS)
575 564
576 565 rmap.connect('edit_repo_statistics', '/{repo_name}/settings/statistics',
577 566 controller='admin/repos', action='edit_statistics_form',
578 567 conditions={'method': ['GET'], 'function': check_repo},
579 568 requirements=URL_NAME_REQUIREMENTS)
580 569 rmap.connect('edit_repo_statistics', '/{repo_name}/settings/statistics',
581 570 controller='admin/repos', action='edit_statistics',
582 571 conditions={'method': ['PUT'], 'function': check_repo},
583 572 requirements=URL_NAME_REQUIREMENTS)
584 573 rmap.connect('repo_settings_issuetracker',
585 574 '/{repo_name}/settings/issue-tracker',
586 575 controller='admin/repos', action='repo_issuetracker',
587 576 conditions={'method': ['GET'], 'function': check_repo},
588 577 requirements=URL_NAME_REQUIREMENTS)
589 578 rmap.connect('repo_issuetracker_test',
590 579 '/{repo_name}/settings/issue-tracker/test',
591 580 controller='admin/repos', action='repo_issuetracker_test',
592 581 conditions={'method': ['POST'], 'function': check_repo},
593 582 requirements=URL_NAME_REQUIREMENTS)
594 583 rmap.connect('repo_issuetracker_delete',
595 584 '/{repo_name}/settings/issue-tracker/delete',
596 585 controller='admin/repos', action='repo_issuetracker_delete',
597 586 conditions={'method': ['DELETE'], 'function': check_repo},
598 587 requirements=URL_NAME_REQUIREMENTS)
599 588 rmap.connect('repo_issuetracker_save',
600 589 '/{repo_name}/settings/issue-tracker/save',
601 590 controller='admin/repos', action='repo_issuetracker_save',
602 591 conditions={'method': ['POST'], 'function': check_repo},
603 592 requirements=URL_NAME_REQUIREMENTS)
604 593 rmap.connect('repo_vcs_settings', '/{repo_name}/settings/vcs',
605 594 controller='admin/repos', action='repo_settings_vcs_update',
606 595 conditions={'method': ['POST'], 'function': check_repo},
607 596 requirements=URL_NAME_REQUIREMENTS)
608 597 rmap.connect('repo_vcs_settings', '/{repo_name}/settings/vcs',
609 598 controller='admin/repos', action='repo_settings_vcs',
610 599 conditions={'method': ['GET'], 'function': check_repo},
611 600 requirements=URL_NAME_REQUIREMENTS)
612 601 rmap.connect('repo_vcs_settings', '/{repo_name}/settings/vcs',
613 602 controller='admin/repos', action='repo_delete_svn_pattern',
614 603 conditions={'method': ['DELETE'], 'function': check_repo},
615 604 requirements=URL_NAME_REQUIREMENTS)
616 605 rmap.connect('repo_pullrequest_settings', '/{repo_name}/settings/pullrequest',
617 606 controller='admin/repos', action='repo_settings_pullrequest',
618 607 conditions={'method': ['GET', 'POST'], 'function': check_repo},
619 608 requirements=URL_NAME_REQUIREMENTS)
620 609
621 610 # still working url for backward compat.
622 611 rmap.connect('raw_changeset_home_depraced',
623 612 '/{repo_name}/raw-changeset/{revision}',
624 613 controller='changeset', action='changeset_raw',
625 614 revision='tip', conditions={'function': check_repo},
626 615 requirements=URL_NAME_REQUIREMENTS)
627 616
628 617 # new URLs
629 618 rmap.connect('changeset_raw_home',
630 619 '/{repo_name}/changeset-diff/{revision}',
631 620 controller='changeset', action='changeset_raw',
632 621 revision='tip', conditions={'function': check_repo},
633 622 requirements=URL_NAME_REQUIREMENTS)
634 623
635 624 rmap.connect('changeset_patch_home',
636 625 '/{repo_name}/changeset-patch/{revision}',
637 626 controller='changeset', action='changeset_patch',
638 627 revision='tip', conditions={'function': check_repo},
639 628 requirements=URL_NAME_REQUIREMENTS)
640 629
641 630 rmap.connect('changeset_download_home',
642 631 '/{repo_name}/changeset-download/{revision}',
643 632 controller='changeset', action='changeset_download',
644 633 revision='tip', conditions={'function': check_repo},
645 634 requirements=URL_NAME_REQUIREMENTS)
646 635
647 636 rmap.connect('changeset_comment',
648 637 '/{repo_name}/changeset/{revision}/comment', jsroute=True,
649 638 controller='changeset', revision='tip', action='comment',
650 639 conditions={'function': check_repo},
651 640 requirements=URL_NAME_REQUIREMENTS)
652 641
653 642 rmap.connect('changeset_comment_preview',
654 643 '/{repo_name}/changeset/comment/preview', jsroute=True,
655 644 controller='changeset', action='preview_comment',
656 645 conditions={'function': check_repo, 'method': ['POST']},
657 646 requirements=URL_NAME_REQUIREMENTS)
658 647
659 648 rmap.connect('changeset_comment_delete',
660 649 '/{repo_name}/changeset/comment/{comment_id}/delete',
661 650 controller='changeset', action='delete_comment',
662 651 conditions={'function': check_repo, 'method': ['DELETE']},
663 652 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
664 653
665 654 rmap.connect('changeset_info', '/{repo_name}/changeset_info/{revision}',
666 655 controller='changeset', action='changeset_info',
667 656 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
668 657
669 658 rmap.connect('compare_home',
670 659 '/{repo_name}/compare',
671 660 controller='compare', action='index',
672 661 conditions={'function': check_repo},
673 662 requirements=URL_NAME_REQUIREMENTS)
674 663
675 664 rmap.connect('compare_url',
676 665 '/{repo_name}/compare/{source_ref_type}@{source_ref:.*?}...{target_ref_type}@{target_ref:.*?}',
677 666 controller='compare', action='compare',
678 667 conditions={'function': check_repo},
679 668 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
680 669
681 670 rmap.connect('pullrequest_home',
682 671 '/{repo_name}/pull-request/new', controller='pullrequests',
683 672 action='index', conditions={'function': check_repo,
684 673 'method': ['GET']},
685 674 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
686 675
687 676 rmap.connect('pullrequest',
688 677 '/{repo_name}/pull-request/new', controller='pullrequests',
689 678 action='create', conditions={'function': check_repo,
690 679 'method': ['POST']},
691 680 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
692 681
693 682 rmap.connect('pullrequest_repo_refs',
694 683 '/{repo_name}/pull-request/refs/{target_repo_name:.*?[^/]}',
695 684 controller='pullrequests',
696 685 action='get_repo_refs',
697 686 conditions={'function': check_repo, 'method': ['GET']},
698 687 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
699 688
700 689 rmap.connect('pullrequest_repo_destinations',
701 690 '/{repo_name}/pull-request/repo-destinations',
702 691 controller='pullrequests',
703 692 action='get_repo_destinations',
704 693 conditions={'function': check_repo, 'method': ['GET']},
705 694 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
706 695
707 696 rmap.connect('pullrequest_show',
708 697 '/{repo_name}/pull-request/{pull_request_id}',
709 698 controller='pullrequests',
710 699 action='show', conditions={'function': check_repo,
711 700 'method': ['GET']},
712 701 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
713 702
714 703 rmap.connect('pullrequest_update',
715 704 '/{repo_name}/pull-request/{pull_request_id}',
716 705 controller='pullrequests',
717 706 action='update', conditions={'function': check_repo,
718 707 'method': ['PUT']},
719 708 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
720 709
721 710 rmap.connect('pullrequest_merge',
722 711 '/{repo_name}/pull-request/{pull_request_id}',
723 712 controller='pullrequests',
724 713 action='merge', conditions={'function': check_repo,
725 714 'method': ['POST']},
726 715 requirements=URL_NAME_REQUIREMENTS)
727 716
728 717 rmap.connect('pullrequest_delete',
729 718 '/{repo_name}/pull-request/{pull_request_id}',
730 719 controller='pullrequests',
731 720 action='delete', conditions={'function': check_repo,
732 721 'method': ['DELETE']},
733 722 requirements=URL_NAME_REQUIREMENTS)
734 723
735 724 rmap.connect('pullrequest_comment',
736 725 '/{repo_name}/pull-request-comment/{pull_request_id}',
737 726 controller='pullrequests',
738 727 action='comment', conditions={'function': check_repo,
739 728 'method': ['POST']},
740 729 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
741 730
742 731 rmap.connect('pullrequest_comment_delete',
743 732 '/{repo_name}/pull-request-comment/{comment_id}/delete',
744 733 controller='pullrequests', action='delete_comment',
745 734 conditions={'function': check_repo, 'method': ['DELETE']},
746 735 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
747 736
748 737 rmap.connect('changelog_home', '/{repo_name}/changelog', jsroute=True,
749 738 controller='changelog', conditions={'function': check_repo},
750 739 requirements=URL_NAME_REQUIREMENTS)
751 740
752 741 rmap.connect('changelog_file_home',
753 742 '/{repo_name}/changelog/{revision}/{f_path}',
754 743 controller='changelog', f_path=None,
755 744 conditions={'function': check_repo},
756 745 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
757 746
758 747 rmap.connect('changelog_elements', '/{repo_name}/changelog_details',
759 748 controller='changelog', action='changelog_elements',
760 749 conditions={'function': check_repo},
761 750 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
762 751
763 752 rmap.connect('files_home', '/{repo_name}/files/{revision}/{f_path}',
764 753 controller='files', revision='tip', f_path='',
765 754 conditions={'function': check_repo},
766 755 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
767 756
768 757 rmap.connect('files_home_simple_catchrev',
769 758 '/{repo_name}/files/{revision}',
770 759 controller='files', revision='tip', f_path='',
771 760 conditions={'function': check_repo},
772 761 requirements=URL_NAME_REQUIREMENTS)
773 762
774 763 rmap.connect('files_home_simple_catchall',
775 764 '/{repo_name}/files',
776 765 controller='files', revision='tip', f_path='',
777 766 conditions={'function': check_repo},
778 767 requirements=URL_NAME_REQUIREMENTS)
779 768
780 769 rmap.connect('files_history_home',
781 770 '/{repo_name}/history/{revision}/{f_path}',
782 771 controller='files', action='history', revision='tip', f_path='',
783 772 conditions={'function': check_repo},
784 773 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
785 774
786 775 rmap.connect('files_authors_home',
787 776 '/{repo_name}/authors/{revision}/{f_path}',
788 777 controller='files', action='authors', revision='tip', f_path='',
789 778 conditions={'function': check_repo},
790 779 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
791 780
792 781 rmap.connect('files_diff_home', '/{repo_name}/diff/{f_path}',
793 782 controller='files', action='diff', f_path='',
794 783 conditions={'function': check_repo},
795 784 requirements=URL_NAME_REQUIREMENTS)
796 785
797 786 rmap.connect('files_diff_2way_home',
798 787 '/{repo_name}/diff-2way/{f_path}',
799 788 controller='files', action='diff_2way', f_path='',
800 789 conditions={'function': check_repo},
801 790 requirements=URL_NAME_REQUIREMENTS)
802 791
803 792 rmap.connect('files_rawfile_home',
804 793 '/{repo_name}/rawfile/{revision}/{f_path}',
805 794 controller='files', action='rawfile', revision='tip',
806 795 f_path='', conditions={'function': check_repo},
807 796 requirements=URL_NAME_REQUIREMENTS)
808 797
809 798 rmap.connect('files_raw_home',
810 799 '/{repo_name}/raw/{revision}/{f_path}',
811 800 controller='files', action='raw', revision='tip', f_path='',
812 801 conditions={'function': check_repo},
813 802 requirements=URL_NAME_REQUIREMENTS)
814 803
815 804 rmap.connect('files_render_home',
816 805 '/{repo_name}/render/{revision}/{f_path}',
817 806 controller='files', action='index', revision='tip', f_path='',
818 807 rendered=True, conditions={'function': check_repo},
819 808 requirements=URL_NAME_REQUIREMENTS)
820 809
821 810 rmap.connect('files_annotate_home',
822 811 '/{repo_name}/annotate/{revision}/{f_path}',
823 812 controller='files', action='index', revision='tip',
824 813 f_path='', annotate=True, conditions={'function': check_repo},
825 814 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
826 815
827 816 rmap.connect('files_annotate_previous',
828 817 '/{repo_name}/annotate-previous/{revision}/{f_path}',
829 818 controller='files', action='annotate_previous', revision='tip',
830 819 f_path='', annotate=True, conditions={'function': check_repo},
831 820 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
832 821
833 822 rmap.connect('files_edit',
834 823 '/{repo_name}/edit/{revision}/{f_path}',
835 824 controller='files', action='edit', revision='tip',
836 825 f_path='',
837 826 conditions={'function': check_repo, 'method': ['POST']},
838 827 requirements=URL_NAME_REQUIREMENTS)
839 828
840 829 rmap.connect('files_edit_home',
841 830 '/{repo_name}/edit/{revision}/{f_path}',
842 831 controller='files', action='edit_home', revision='tip',
843 832 f_path='', conditions={'function': check_repo},
844 833 requirements=URL_NAME_REQUIREMENTS)
845 834
846 835 rmap.connect('files_add',
847 836 '/{repo_name}/add/{revision}/{f_path}',
848 837 controller='files', action='add', revision='tip',
849 838 f_path='',
850 839 conditions={'function': check_repo, 'method': ['POST']},
851 840 requirements=URL_NAME_REQUIREMENTS)
852 841
853 842 rmap.connect('files_add_home',
854 843 '/{repo_name}/add/{revision}/{f_path}',
855 844 controller='files', action='add_home', revision='tip',
856 845 f_path='', conditions={'function': check_repo},
857 846 requirements=URL_NAME_REQUIREMENTS)
858 847
859 848 rmap.connect('files_delete',
860 849 '/{repo_name}/delete/{revision}/{f_path}',
861 850 controller='files', action='delete', revision='tip',
862 851 f_path='',
863 852 conditions={'function': check_repo, 'method': ['POST']},
864 853 requirements=URL_NAME_REQUIREMENTS)
865 854
866 855 rmap.connect('files_delete_home',
867 856 '/{repo_name}/delete/{revision}/{f_path}',
868 857 controller='files', action='delete_home', revision='tip',
869 858 f_path='', conditions={'function': check_repo},
870 859 requirements=URL_NAME_REQUIREMENTS)
871 860
872 861 rmap.connect('files_archive_home', '/{repo_name}/archive/{fname}',
873 862 controller='files', action='archivefile',
874 863 conditions={'function': check_repo},
875 864 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
876 865
877 866 rmap.connect('files_nodelist_home',
878 867 '/{repo_name}/nodelist/{revision}/{f_path}',
879 868 controller='files', action='nodelist',
880 869 conditions={'function': check_repo},
881 870 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
882 871
883 872 rmap.connect('files_nodetree_full',
884 873 '/{repo_name}/nodetree_full/{commit_id}/{f_path}',
885 874 controller='files', action='nodetree_full',
886 875 conditions={'function': check_repo},
887 876 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
888 877
889 878 rmap.connect('repo_fork_create_home', '/{repo_name}/fork',
890 879 controller='forks', action='fork_create',
891 880 conditions={'function': check_repo, 'method': ['POST']},
892 881 requirements=URL_NAME_REQUIREMENTS)
893 882
894 883 rmap.connect('repo_fork_home', '/{repo_name}/fork',
895 884 controller='forks', action='fork',
896 885 conditions={'function': check_repo},
897 886 requirements=URL_NAME_REQUIREMENTS)
898 887
899 888 rmap.connect('repo_forks_home', '/{repo_name}/forks',
900 889 controller='forks', action='forks',
901 890 conditions={'function': check_repo},
902 891 requirements=URL_NAME_REQUIREMENTS)
903 892
904 893 return rmap
@@ -1,169 +1,174 b''
1 1
2 2 /******************************************************************************
3 3 * *
4 4 * DO NOT CHANGE THIS FILE MANUALLY *
5 5 * *
6 6 * *
7 7 * This file is automatically generated when the app starts up with *
8 8 * generate_js_files = true *
9 9 * *
10 10 * To add a route here pass jsroute=True to the route definition in the app *
11 11 * *
12 12 ******************************************************************************/
13 13 function registerRCRoutes() {
14 14 // routes registration
15 15 pyroutes.register('new_repo', '/_admin/create_repository', []);
16 16 pyroutes.register('edit_user', '/_admin/users/%(user_id)s/edit', ['user_id']);
17 17 pyroutes.register('edit_user_group_members', '/_admin/user_groups/%(user_group_id)s/edit/members', ['user_group_id']);
18 18 pyroutes.register('toggle_following', '/_admin/toggle_following', []);
19 19 pyroutes.register('changeset_home', '/%(repo_name)s/changeset/%(revision)s', ['repo_name', 'revision']);
20 20 pyroutes.register('changeset_comment', '/%(repo_name)s/changeset/%(revision)s/comment', ['repo_name', 'revision']);
21 21 pyroutes.register('changeset_comment_preview', '/%(repo_name)s/changeset/comment/preview', ['repo_name']);
22 22 pyroutes.register('changeset_comment_delete', '/%(repo_name)s/changeset/comment/%(comment_id)s/delete', ['repo_name', 'comment_id']);
23 23 pyroutes.register('changeset_info', '/%(repo_name)s/changeset_info/%(revision)s', ['repo_name', 'revision']);
24 24 pyroutes.register('compare_url', '/%(repo_name)s/compare/%(source_ref_type)s@%(source_ref)s...%(target_ref_type)s@%(target_ref)s', ['repo_name', 'source_ref_type', 'source_ref', 'target_ref_type', 'target_ref']);
25 25 pyroutes.register('pullrequest_home', '/%(repo_name)s/pull-request/new', ['repo_name']);
26 26 pyroutes.register('pullrequest', '/%(repo_name)s/pull-request/new', ['repo_name']);
27 27 pyroutes.register('pullrequest_repo_refs', '/%(repo_name)s/pull-request/refs/%(target_repo_name)s', ['repo_name', 'target_repo_name']);
28 28 pyroutes.register('pullrequest_repo_destinations', '/%(repo_name)s/pull-request/repo-destinations', ['repo_name']);
29 29 pyroutes.register('pullrequest_show', '/%(repo_name)s/pull-request/%(pull_request_id)s', ['repo_name', 'pull_request_id']);
30 30 pyroutes.register('pullrequest_update', '/%(repo_name)s/pull-request/%(pull_request_id)s', ['repo_name', 'pull_request_id']);
31 31 pyroutes.register('pullrequest_comment', '/%(repo_name)s/pull-request-comment/%(pull_request_id)s', ['repo_name', 'pull_request_id']);
32 32 pyroutes.register('pullrequest_comment_delete', '/%(repo_name)s/pull-request-comment/%(comment_id)s/delete', ['repo_name', 'comment_id']);
33 33 pyroutes.register('changelog_home', '/%(repo_name)s/changelog', ['repo_name']);
34 34 pyroutes.register('changelog_file_home', '/%(repo_name)s/changelog/%(revision)s/%(f_path)s', ['repo_name', 'revision', 'f_path']);
35 35 pyroutes.register('changelog_elements', '/%(repo_name)s/changelog_details', ['repo_name']);
36 36 pyroutes.register('files_home', '/%(repo_name)s/files/%(revision)s/%(f_path)s', ['repo_name', 'revision', 'f_path']);
37 37 pyroutes.register('files_history_home', '/%(repo_name)s/history/%(revision)s/%(f_path)s', ['repo_name', 'revision', 'f_path']);
38 38 pyroutes.register('files_authors_home', '/%(repo_name)s/authors/%(revision)s/%(f_path)s', ['repo_name', 'revision', 'f_path']);
39 39 pyroutes.register('files_annotate_home', '/%(repo_name)s/annotate/%(revision)s/%(f_path)s', ['repo_name', 'revision', 'f_path']);
40 40 pyroutes.register('files_annotate_previous', '/%(repo_name)s/annotate-previous/%(revision)s/%(f_path)s', ['repo_name', 'revision', 'f_path']);
41 41 pyroutes.register('files_archive_home', '/%(repo_name)s/archive/%(fname)s', ['repo_name', 'fname']);
42 42 pyroutes.register('files_nodelist_home', '/%(repo_name)s/nodelist/%(revision)s/%(f_path)s', ['repo_name', 'revision', 'f_path']);
43 43 pyroutes.register('files_nodetree_full', '/%(repo_name)s/nodetree_full/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
44 44 pyroutes.register('favicon', '/favicon.ico', []);
45 45 pyroutes.register('robots', '/robots.txt', []);
46 46 pyroutes.register('auth_home', '/_admin/auth*traverse', []);
47 47 pyroutes.register('global_integrations_new', '/_admin/integrations/new', []);
48 48 pyroutes.register('global_integrations_home', '/_admin/integrations', []);
49 49 pyroutes.register('global_integrations_list', '/_admin/integrations/%(integration)s', ['integration']);
50 50 pyroutes.register('global_integrations_create', '/_admin/integrations/%(integration)s/new', ['integration']);
51 51 pyroutes.register('global_integrations_edit', '/_admin/integrations/%(integration)s/%(integration_id)s', ['integration', 'integration_id']);
52 52 pyroutes.register('repo_group_integrations_home', '/%(repo_group_name)s/settings/integrations', ['repo_group_name']);
53 53 pyroutes.register('repo_group_integrations_list', '/%(repo_group_name)s/settings/integrations/%(integration)s', ['repo_group_name', 'integration']);
54 54 pyroutes.register('repo_group_integrations_new', '/%(repo_group_name)s/settings/integrations/new', ['repo_group_name']);
55 55 pyroutes.register('repo_group_integrations_create', '/%(repo_group_name)s/settings/integrations/%(integration)s/new', ['repo_group_name', 'integration']);
56 56 pyroutes.register('repo_group_integrations_edit', '/%(repo_group_name)s/settings/integrations/%(integration)s/%(integration_id)s', ['repo_group_name', 'integration', 'integration_id']);
57 57 pyroutes.register('repo_integrations_home', '/%(repo_name)s/settings/integrations', ['repo_name']);
58 58 pyroutes.register('repo_integrations_list', '/%(repo_name)s/settings/integrations/%(integration)s', ['repo_name', 'integration']);
59 59 pyroutes.register('repo_integrations_new', '/%(repo_name)s/settings/integrations/new', ['repo_name']);
60 60 pyroutes.register('repo_integrations_create', '/%(repo_name)s/settings/integrations/%(integration)s/new', ['repo_name', 'integration']);
61 61 pyroutes.register('repo_integrations_edit', '/%(repo_name)s/settings/integrations/%(integration)s/%(integration_id)s', ['repo_name', 'integration', 'integration_id']);
62 62 pyroutes.register('ops_ping', '/_admin/ops/ping', []);
63 63 pyroutes.register('admin_home', '/_admin', []);
64 64 pyroutes.register('admin_audit_logs', '/_admin/audit_logs', []);
65 65 pyroutes.register('pull_requests_global_0', '/_admin/pull_requests/%(pull_request_id)s', ['pull_request_id']);
66 66 pyroutes.register('pull_requests_global_1', '/_admin/pull-requests/%(pull_request_id)s', ['pull_request_id']);
67 67 pyroutes.register('pull_requests_global', '/_admin/pull-request/%(pull_request_id)s', ['pull_request_id']);
68 68 pyroutes.register('admin_settings_open_source', '/_admin/settings/open_source', []);
69 69 pyroutes.register('admin_settings_vcs_svn_generate_cfg', '/_admin/settings/vcs/svn_generate_cfg', []);
70 70 pyroutes.register('admin_settings_system', '/_admin/settings/system', []);
71 71 pyroutes.register('admin_settings_system_update', '/_admin/settings/system/updates', []);
72 72 pyroutes.register('admin_settings_sessions', '/_admin/settings/sessions', []);
73 73 pyroutes.register('admin_settings_sessions_cleanup', '/_admin/settings/sessions/cleanup', []);
74 74 pyroutes.register('admin_settings_process_management', '/_admin/settings/process_management', []);
75 75 pyroutes.register('admin_settings_process_management_signal', '/_admin/settings/process_management/signal', []);
76 76 pyroutes.register('admin_permissions_ips', '/_admin/permissions/ips', []);
77 77 pyroutes.register('users', '/_admin/users', []);
78 78 pyroutes.register('users_data', '/_admin/users_data', []);
79 79 pyroutes.register('edit_user_auth_tokens', '/_admin/users/%(user_id)s/edit/auth_tokens', ['user_id']);
80 80 pyroutes.register('edit_user_auth_tokens_add', '/_admin/users/%(user_id)s/edit/auth_tokens/new', ['user_id']);
81 81 pyroutes.register('edit_user_auth_tokens_delete', '/_admin/users/%(user_id)s/edit/auth_tokens/delete', ['user_id']);
82 82 pyroutes.register('edit_user_emails', '/_admin/users/%(user_id)s/edit/emails', ['user_id']);
83 83 pyroutes.register('edit_user_emails_add', '/_admin/users/%(user_id)s/edit/emails/new', ['user_id']);
84 84 pyroutes.register('edit_user_emails_delete', '/_admin/users/%(user_id)s/edit/emails/delete', ['user_id']);
85 85 pyroutes.register('edit_user_ips', '/_admin/users/%(user_id)s/edit/ips', ['user_id']);
86 86 pyroutes.register('edit_user_ips_add', '/_admin/users/%(user_id)s/edit/ips/new', ['user_id']);
87 87 pyroutes.register('edit_user_ips_delete', '/_admin/users/%(user_id)s/edit/ips/delete', ['user_id']);
88 88 pyroutes.register('edit_user_groups_management', '/_admin/users/%(user_id)s/edit/groups_management', ['user_id']);
89 89 pyroutes.register('edit_user_groups_management_updates', '/_admin/users/%(user_id)s/edit/edit_user_groups_management/updates', ['user_id']);
90 90 pyroutes.register('edit_user_audit_logs', '/_admin/users/%(user_id)s/edit/audit', ['user_id']);
91 91 pyroutes.register('channelstream_connect', '/_admin/channelstream/connect', []);
92 92 pyroutes.register('channelstream_subscribe', '/_admin/channelstream/subscribe', []);
93 93 pyroutes.register('channelstream_proxy', '/_channelstream', []);
94 94 pyroutes.register('login', '/_admin/login', []);
95 95 pyroutes.register('logout', '/_admin/logout', []);
96 96 pyroutes.register('register', '/_admin/register', []);
97 97 pyroutes.register('reset_password', '/_admin/password_reset', []);
98 98 pyroutes.register('reset_password_confirmation', '/_admin/password_reset_confirmation', []);
99 99 pyroutes.register('home', '/', []);
100 100 pyroutes.register('user_autocomplete_data', '/_users', []);
101 101 pyroutes.register('user_group_autocomplete_data', '/_user_groups', []);
102 102 pyroutes.register('repo_list_data', '/_repos', []);
103 103 pyroutes.register('goto_switcher_data', '/_goto_data', []);
104 104 pyroutes.register('repo_summary_explicit', '/%(repo_name)s/summary', ['repo_name']);
105 105 pyroutes.register('repo_summary_commits', '/%(repo_name)s/summary-commits', ['repo_name']);
106 106 pyroutes.register('repo_commit', '/%(repo_name)s/changeset/%(commit_id)s', ['repo_name', 'commit_id']);
107 107 pyroutes.register('repo_refs_data', '/%(repo_name)s/refs-data', ['repo_name']);
108 108 pyroutes.register('repo_refs_changelog_data', '/%(repo_name)s/refs-data-changelog', ['repo_name']);
109 109 pyroutes.register('repo_stats', '/%(repo_name)s/repo_stats/%(commit_id)s', ['repo_name', 'commit_id']);
110 110 pyroutes.register('tags_home', '/%(repo_name)s/tags', ['repo_name']);
111 111 pyroutes.register('branches_home', '/%(repo_name)s/branches', ['repo_name']);
112 112 pyroutes.register('bookmarks_home', '/%(repo_name)s/bookmarks', ['repo_name']);
113 113 pyroutes.register('pullrequest_show', '/%(repo_name)s/pull-request/%(pull_request_id)s', ['repo_name', 'pull_request_id']);
114 114 pyroutes.register('pullrequest_show_all', '/%(repo_name)s/pull-request', ['repo_name']);
115 115 pyroutes.register('pullrequest_show_all_data', '/%(repo_name)s/pull-request-data', ['repo_name']);
116 pyroutes.register('changeset_home', '/%(repo_name)s/changeset/%(revision)s', ['repo_name', 'revision']);
117 pyroutes.register('changeset_children', '/%(repo_name)s/changeset_children/%(revision)s', ['repo_name', 'revision']);
118 pyroutes.register('changeset_parents', '/%(repo_name)s/changeset_parents/%(revision)s', ['repo_name', 'revision']);
116 119 pyroutes.register('edit_repo', '/%(repo_name)s/settings', ['repo_name']);
117 120 pyroutes.register('edit_repo_advanced', '/%(repo_name)s/settings/advanced', ['repo_name']);
118 121 pyroutes.register('edit_repo_advanced_delete', '/%(repo_name)s/settings/advanced/delete', ['repo_name']);
119 122 pyroutes.register('edit_repo_advanced_locking', '/%(repo_name)s/settings/advanced/locking', ['repo_name']);
120 123 pyroutes.register('edit_repo_advanced_journal', '/%(repo_name)s/settings/advanced/journal', ['repo_name']);
121 124 pyroutes.register('edit_repo_advanced_fork', '/%(repo_name)s/settings/advanced/fork', ['repo_name']);
122 125 pyroutes.register('edit_repo_caches', '/%(repo_name)s/settings/caches', ['repo_name']);
123 126 pyroutes.register('edit_repo_perms', '/%(repo_name)s/settings/permissions', ['repo_name']);
124 127 pyroutes.register('repo_reviewers', '/%(repo_name)s/settings/review/rules', ['repo_name']);
125 128 pyroutes.register('repo_default_reviewers_data', '/%(repo_name)s/settings/review/default-reviewers', ['repo_name']);
126 129 pyroutes.register('repo_maintenance', '/%(repo_name)s/settings/maintenance', ['repo_name']);
127 130 pyroutes.register('repo_maintenance_execute', '/%(repo_name)s/settings/maintenance/execute', ['repo_name']);
128 131 pyroutes.register('strip', '/%(repo_name)s/settings/strip', ['repo_name']);
129 132 pyroutes.register('strip_check', '/%(repo_name)s/settings/strip_check', ['repo_name']);
130 133 pyroutes.register('strip_execute', '/%(repo_name)s/settings/strip_execute', ['repo_name']);
134 pyroutes.register('rss_feed_home', '/%(repo_name)s/feed/rss', ['repo_name']);
135 pyroutes.register('atom_feed_home', '/%(repo_name)s/feed/atom', ['repo_name']);
131 136 pyroutes.register('repo_summary', '/%(repo_name)s', ['repo_name']);
132 137 pyroutes.register('repo_summary_slash', '/%(repo_name)s/', ['repo_name']);
133 138 pyroutes.register('repo_group_home', '/%(repo_group_name)s', ['repo_group_name']);
134 139 pyroutes.register('repo_group_home_slash', '/%(repo_group_name)s/', ['repo_group_name']);
135 140 pyroutes.register('search', '/_admin/search', []);
136 141 pyroutes.register('search_repo', '/%(repo_name)s/search', ['repo_name']);
137 142 pyroutes.register('user_profile', '/_profiles/%(username)s', ['username']);
138 143 pyroutes.register('my_account_profile', '/_admin/my_account/profile', []);
139 144 pyroutes.register('my_account_edit', '/_admin/my_account/edit', []);
140 145 pyroutes.register('my_account_update', '/_admin/my_account/update', []);
141 146 pyroutes.register('my_account_password', '/_admin/my_account/password', []);
142 147 pyroutes.register('my_account_password_update', '/_admin/my_account/password', []);
143 148 pyroutes.register('my_account_auth_tokens', '/_admin/my_account/auth_tokens', []);
144 149 pyroutes.register('my_account_auth_tokens_add', '/_admin/my_account/auth_tokens/new', []);
145 150 pyroutes.register('my_account_auth_tokens_delete', '/_admin/my_account/auth_tokens/delete', []);
146 151 pyroutes.register('my_account_emails', '/_admin/my_account/emails', []);
147 152 pyroutes.register('my_account_emails_add', '/_admin/my_account/emails/new', []);
148 153 pyroutes.register('my_account_emails_delete', '/_admin/my_account/emails/delete', []);
149 154 pyroutes.register('my_account_repos', '/_admin/my_account/repos', []);
150 155 pyroutes.register('my_account_watched', '/_admin/my_account/watched', []);
151 156 pyroutes.register('my_account_perms', '/_admin/my_account/perms', []);
152 157 pyroutes.register('my_account_notifications', '/_admin/my_account/notifications', []);
153 158 pyroutes.register('my_account_notifications_toggle_visibility', '/_admin/my_account/toggle_visibility', []);
154 159 pyroutes.register('my_account_pullrequests', '/_admin/my_account/pull_requests', []);
155 160 pyroutes.register('my_account_pullrequests_data', '/_admin/my_account/pull_requests/data', []);
156 161 pyroutes.register('my_account_notifications_test_channelstream', '/_admin/my_account/test_channelstream', []);
157 162 pyroutes.register('gists_show', '/_admin/gists', []);
158 163 pyroutes.register('gists_new', '/_admin/gists/new', []);
159 164 pyroutes.register('gists_create', '/_admin/gists/create', []);
160 165 pyroutes.register('gist_show', '/_admin/gists/%(gist_id)s', ['gist_id']);
161 166 pyroutes.register('gist_delete', '/_admin/gists/%(gist_id)s/delete', ['gist_id']);
162 167 pyroutes.register('gist_edit', '/_admin/gists/%(gist_id)s/edit', ['gist_id']);
163 168 pyroutes.register('gist_edit_check_revision', '/_admin/gists/%(gist_id)s/edit/check_revision', ['gist_id']);
164 169 pyroutes.register('gist_update', '/_admin/gists/%(gist_id)s/update', ['gist_id']);
165 170 pyroutes.register('gist_show_rev', '/_admin/gists/%(gist_id)s/%(revision)s', ['gist_id', 'revision']);
166 171 pyroutes.register('gist_show_formatted', '/_admin/gists/%(gist_id)s/%(revision)s/%(format)s', ['gist_id', 'revision', 'format']);
167 172 pyroutes.register('gist_show_formatted_path', '/_admin/gists/%(gist_id)s/%(revision)s/%(format)s/%(f_path)s', ['gist_id', 'revision', 'format', 'f_path']);
168 173 pyroutes.register('apiv2', '/_admin/api', []);
169 174 }
@@ -1,317 +1,317 b''
1 1 ## DATA TABLE RE USABLE ELEMENTS
2 2 ## usage:
3 3 ## <%namespace name="dt" file="/data_table/_dt_elements.mako"/>
4 4 <%namespace name="base" file="/base/base.mako"/>
5 5
6 6 ## REPOSITORY RENDERERS
7 7 <%def name="quick_menu(repo_name)">
8 8 <i class="pointer icon-more"></i>
9 9 <div class="menu_items_container hidden">
10 10 <ul class="menu_items">
11 11 <li>
12 12 <a title="${_('Summary')}" href="${h.route_path('repo_summary',repo_name=repo_name)}">
13 13 <span>${_('Summary')}</span>
14 14 </a>
15 15 </li>
16 16 <li>
17 17 <a title="${_('Changelog')}" href="${h.url('changelog_home',repo_name=repo_name)}">
18 18 <span>${_('Changelog')}</span>
19 19 </a>
20 20 </li>
21 21 <li>
22 22 <a title="${_('Files')}" href="${h.url('files_home',repo_name=repo_name)}">
23 23 <span>${_('Files')}</span>
24 24 </a>
25 25 </li>
26 26 <li>
27 27 <a title="${_('Fork')}" href="${h.url('repo_fork_home',repo_name=repo_name)}">
28 28 <span>${_('Fork')}</span>
29 29 </a>
30 30 </li>
31 31 </ul>
32 32 </div>
33 33 </%def>
34 34
35 35 <%def name="repo_name(name,rtype,rstate,private,fork_of,short_name=False,admin=False)">
36 36 <%
37 37 def get_name(name,short_name=short_name):
38 38 if short_name:
39 39 return name.split('/')[-1]
40 40 else:
41 41 return name
42 42 %>
43 43 <div class="${'repo_state_pending' if rstate == 'repo_state_pending' else ''} truncate">
44 44 ##NAME
45 45 <a href="${h.route_path('edit_repo',repo_name=name) if admin else h.route_path('repo_summary',repo_name=name)}">
46 46
47 47 ##TYPE OF REPO
48 48 %if h.is_hg(rtype):
49 49 <span title="${_('Mercurial repository')}"><i class="icon-hg"></i></span>
50 50 %elif h.is_git(rtype):
51 51 <span title="${_('Git repository')}"><i class="icon-git"></i></span>
52 52 %elif h.is_svn(rtype):
53 53 <span title="${_('Subversion repository')}"><i class="icon-svn"></i></span>
54 54 %endif
55 55
56 56 ##PRIVATE/PUBLIC
57 57 %if private and c.visual.show_private_icon:
58 58 <i class="icon-lock" title="${_('Private repository')}"></i>
59 59 %elif not private and c.visual.show_public_icon:
60 60 <i class="icon-unlock-alt" title="${_('Public repository')}"></i>
61 61 %else:
62 62 <span></span>
63 63 %endif
64 64 ${get_name(name)}
65 65 </a>
66 66 %if fork_of:
67 67 <a href="${h.route_path('repo_summary',repo_name=fork_of.repo_name)}"><i class="icon-code-fork"></i></a>
68 68 %endif
69 69 %if rstate == 'repo_state_pending':
70 70 <i class="icon-cogs" title="${_('Repository creating in progress...')}"></i>
71 71 %endif
72 72 </div>
73 73 </%def>
74 74
75 75 <%def name="repo_desc(description)">
76 76 <div class="truncate-wrap">${description}</div>
77 77 </%def>
78 78
79 79 <%def name="last_change(last_change)">
80 80 ${h.age_component(last_change)}
81 81 </%def>
82 82
83 83 <%def name="revision(name,rev,tip,author,last_msg)">
84 84 <div>
85 85 %if rev >= 0:
86 86 <code><a title="${h.tooltip('%s:\n\n%s' % (author,last_msg))}" class="tooltip" href="${h.url('changeset_home',repo_name=name,revision=tip)}">${'r%s:%s' % (rev,h.short_id(tip))}</a></code>
87 87 %else:
88 88 ${_('No commits yet')}
89 89 %endif
90 90 </div>
91 91 </%def>
92 92
93 93 <%def name="rss(name)">
94 94 %if c.rhodecode_user.username != h.DEFAULT_USER:
95 <a title="${h.tooltip(_('Subscribe to %s rss feed')% name)}" href="${h.url('rss_feed_home',repo_name=name,auth_token=c.rhodecode_user.feed_token)}"><i class="icon-rss-sign"></i></a>
95 <a title="${h.tooltip(_('Subscribe to %s rss feed')% name)}" href="${h.route_path('rss_feed_home', repo_name=name, _query=dict(auth_token=c.rhodecode_user.feed_token))}"><i class="icon-rss-sign"></i></a>
96 96 %else:
97 <a title="${h.tooltip(_('Subscribe to %s rss feed')% name)}" href="${h.url('rss_feed_home',repo_name=name)}"><i class="icon-rss-sign"></i></a>
97 <a title="${h.tooltip(_('Subscribe to %s rss feed')% name)}" href="${h.route_path('rss_feed_home', repo_name=name)}"><i class="icon-rss-sign"></i></a>
98 98 %endif
99 99 </%def>
100 100
101 101 <%def name="atom(name)">
102 102 %if c.rhodecode_user.username != h.DEFAULT_USER:
103 <a title="${h.tooltip(_('Subscribe to %s atom feed')% name)}" href="${h.url('atom_feed_home',repo_name=name,auth_token=c.rhodecode_user.feed_token)}"><i class="icon-rss-sign"></i></a>
103 <a title="${h.tooltip(_('Subscribe to %s atom feed')% name)}" href="${h.route_path('atom_feed_home', repo_name=name, _query=dict(auth_token=c.rhodecode_user.feed_token))}"><i class="icon-rss-sign"></i></a>
104 104 %else:
105 <a title="${h.tooltip(_('Subscribe to %s atom feed')% name)}" href="${h.url('atom_feed_home',repo_name=name)}"><i class="icon-rss-sign"></i></a>
105 <a title="${h.tooltip(_('Subscribe to %s atom feed')% name)}" href="${h.route_path('atom_feed_home', repo_name=name)}"><i class="icon-rss-sign"></i></a>
106 106 %endif
107 107 </%def>
108 108
109 109 <%def name="user_gravatar(email, size=16)">
110 110 <div class="rc-user tooltip" title="${h.tooltip(h.author_string(email))}">
111 111 ${base.gravatar(email, 16)}
112 112 </div>
113 113 </%def>
114 114
115 115 <%def name="repo_actions(repo_name, super_user=True)">
116 116 <div>
117 117 <div class="grid_edit">
118 118 <a href="${h.route_path('edit_repo',repo_name=repo_name)}" title="${_('Edit')}">
119 119 <i class="icon-pencil"></i>Edit</a>
120 120 </div>
121 121 <div class="grid_delete">
122 122 ${h.secure_form(h.route_path('edit_repo_advanced_delete', repo_name=repo_name), method='POST')}
123 123 ${h.submit('remove_%s' % repo_name,_('Delete'),class_="btn btn-link btn-danger",
124 124 onclick="return confirm('"+_('Confirm to delete this repository: %s') % repo_name+"');")}
125 125 ${h.end_form()}
126 126 </div>
127 127 </div>
128 128 </%def>
129 129
130 130 <%def name="repo_state(repo_state)">
131 131 <div>
132 132 %if repo_state == 'repo_state_pending':
133 133 <div class="tag tag4">${_('Creating')}</div>
134 134 %elif repo_state == 'repo_state_created':
135 135 <div class="tag tag1">${_('Created')}</div>
136 136 %else:
137 137 <div class="tag alert2" title="${h.tooltip(repo_state)}">invalid</div>
138 138 %endif
139 139 </div>
140 140 </%def>
141 141
142 142
143 143 ## REPO GROUP RENDERERS
144 144 <%def name="quick_repo_group_menu(repo_group_name)">
145 145 <i class="pointer icon-more"></i>
146 146 <div class="menu_items_container hidden">
147 147 <ul class="menu_items">
148 148 <li>
149 149 <a href="${h.route_path('repo_group_home', repo_group_name=repo_group_name)}">
150 150 <span class="icon">
151 151 <i class="icon-file-text"></i>
152 152 </span>
153 153 <span>${_('Summary')}</span>
154 154 </a>
155 155 </li>
156 156
157 157 </ul>
158 158 </div>
159 159 </%def>
160 160
161 161 <%def name="repo_group_name(repo_group_name, children_groups=None)">
162 162 <div>
163 163 <a href="${h.route_path('repo_group_home', repo_group_name=repo_group_name)}">
164 164 <i class="icon-folder-close" title="${_('Repository group')}"></i>
165 165 %if children_groups:
166 166 ${h.literal(' &raquo; '.join(children_groups))}
167 167 %else:
168 168 ${repo_group_name}
169 169 %endif
170 170 </a>
171 171 </div>
172 172 </%def>
173 173
174 174 <%def name="repo_group_desc(description)">
175 175 <div class="truncate-wrap">${description}</div>
176 176 </%def>
177 177
178 178 <%def name="repo_group_actions(repo_group_id, repo_group_name, gr_count)">
179 179 <div class="grid_edit">
180 180 <a href="${h.url('edit_repo_group',group_name=repo_group_name)}" title="${_('Edit')}">Edit</a>
181 181 </div>
182 182 <div class="grid_delete">
183 183 ${h.secure_form(h.url('delete_repo_group', group_name=repo_group_name),method='delete')}
184 184 ${h.submit('remove_%s' % repo_group_name,_('Delete'),class_="btn btn-link btn-danger",
185 185 onclick="return confirm('"+ungettext('Confirm to delete this group: %s with %s repository','Confirm to delete this group: %s with %s repositories',gr_count) % (repo_group_name, gr_count)+"');")}
186 186 ${h.end_form()}
187 187 </div>
188 188 </%def>
189 189
190 190
191 191 <%def name="user_actions(user_id, username)">
192 192 <div class="grid_edit">
193 193 <a href="${h.url('edit_user',user_id=user_id)}" title="${_('Edit')}">
194 194 <i class="icon-pencil"></i>Edit</a>
195 195 </div>
196 196 <div class="grid_delete">
197 197 ${h.secure_form(h.url('delete_user', user_id=user_id),method='delete')}
198 198 ${h.submit('remove_',_('Delete'),id="remove_user_%s" % user_id, class_="btn btn-link btn-danger",
199 199 onclick="return confirm('"+_('Confirm to delete this user: %s') % username+"');")}
200 200 ${h.end_form()}
201 201 </div>
202 202 </%def>
203 203
204 204 <%def name="user_group_actions(user_group_id, user_group_name)">
205 205 <div class="grid_edit">
206 206 <a href="${h.url('edit_users_group', user_group_id=user_group_id)}" title="${_('Edit')}">Edit</a>
207 207 </div>
208 208 <div class="grid_delete">
209 209 ${h.secure_form(h.url('delete_users_group', user_group_id=user_group_id),method='delete')}
210 210 ${h.submit('remove_',_('Delete'),id="remove_group_%s" % user_group_id, class_="btn btn-link btn-danger",
211 211 onclick="return confirm('"+_('Confirm to delete this user group: %s') % user_group_name+"');")}
212 212 ${h.end_form()}
213 213 </div>
214 214 </%def>
215 215
216 216
217 217 <%def name="user_name(user_id, username)">
218 218 ${h.link_to(h.person(username, 'username_or_name_or_email'), h.url('edit_user', user_id=user_id))}
219 219 </%def>
220 220
221 221 <%def name="user_profile(username)">
222 222 ${base.gravatar_with_user(username, 16)}
223 223 </%def>
224 224
225 225 <%def name="user_group_name(user_group_id, user_group_name)">
226 226 <div>
227 227 <a href="${h.url('edit_users_group', user_group_id=user_group_id)}">
228 228 <i class="icon-group" title="${_('User group')}"></i> ${user_group_name}</a>
229 229 </div>
230 230 </%def>
231 231
232 232
233 233 ## GISTS
234 234
235 235 <%def name="gist_gravatar(full_contact)">
236 236 <div class="gist_gravatar">
237 237 ${base.gravatar(full_contact, 30)}
238 238 </div>
239 239 </%def>
240 240
241 241 <%def name="gist_access_id(gist_access_id, full_contact)">
242 242 <div>
243 243 <b>
244 244 <a href="${h.route_path('gist_show', gist_id=gist_access_id)}">gist: ${gist_access_id}</a>
245 245 </b>
246 246 </div>
247 247 </%def>
248 248
249 249 <%def name="gist_author(full_contact, created_on, expires)">
250 250 ${base.gravatar_with_user(full_contact, 16)}
251 251 </%def>
252 252
253 253
254 254 <%def name="gist_created(created_on)">
255 255 <div class="created">
256 256 ${h.age_component(created_on, time_is_local=True)}
257 257 </div>
258 258 </%def>
259 259
260 260 <%def name="gist_expires(expires)">
261 261 <div class="created">
262 262 %if expires == -1:
263 263 ${_('never')}
264 264 %else:
265 265 ${h.age_component(h.time_to_utcdatetime(expires))}
266 266 %endif
267 267 </div>
268 268 </%def>
269 269
270 270 <%def name="gist_type(gist_type)">
271 271 %if gist_type != 'public':
272 272 <div class="tag">${_('Private')}</div>
273 273 %endif
274 274 </%def>
275 275
276 276 <%def name="gist_description(gist_description)">
277 277 ${gist_description}
278 278 </%def>
279 279
280 280
281 281 ## PULL REQUESTS GRID RENDERERS
282 282
283 283 <%def name="pullrequest_target_repo(repo_name)">
284 284 <div class="truncate">
285 285 ${h.link_to(repo_name,h.route_path('repo_summary',repo_name=repo_name))}
286 286 </div>
287 287 </%def>
288 288 <%def name="pullrequest_status(status)">
289 289 <div class="${'flag_status %s' % status} pull-left"></div>
290 290 </%def>
291 291
292 292 <%def name="pullrequest_title(title, description)">
293 293 ${title} <br/>
294 294 ${h.shorter(description, 40)}
295 295 </%def>
296 296
297 297 <%def name="pullrequest_comments(comments_nr)">
298 298 <i class="icon-comment"></i> ${comments_nr}
299 299 </%def>
300 300
301 301 <%def name="pullrequest_name(pull_request_id, target_repo_name, short=False)">
302 302 <a href="${h.route_path('pullrequest_show',repo_name=target_repo_name,pull_request_id=pull_request_id)}">
303 303 % if short:
304 304 #${pull_request_id}
305 305 % else:
306 306 ${_('Pull request #%(pr_number)s') % {'pr_number': pull_request_id,}}
307 307 % endif
308 308 </a>
309 309 </%def>
310 310
311 311 <%def name="pullrequest_updated_on(updated_on)">
312 312 ${h.age_component(h.time_to_utcdatetime(updated_on))}
313 313 </%def>
314 314
315 315 <%def name="pullrequest_author(full_contact)">
316 316 ${base.gravatar_with_user(full_contact, 16)}
317 317 </%def>
@@ -1,29 +1,29 b''
1 1 <%inherit file="/base/base.mako"/>
2 2
3 3 <%def name="title()">
4 4 ## represents page title
5 5 ${_('%s Summary') % c.repo_name}
6 6 %if c.rhodecode_name:
7 7 &middot; ${h.branding(c.rhodecode_name)}
8 8 %endif
9 9 </%def>
10 10
11 11
12 12 <%def name="head_extra()">
13 <link href="${h.url('atom_feed_home',repo_name=c.rhodecode_db_repo.repo_name,auth_token=c.rhodecode_user.feed_token)}" rel="alternate" title="${h.tooltip(_('%s ATOM feed') % c.repo_name)}" type="application/atom+xml" />
14 <link href="${h.url('rss_feed_home',repo_name=c.rhodecode_db_repo.repo_name,auth_token=c.rhodecode_user.feed_token)}" rel="alternate" title="${h.tooltip(_('%s RSS feed') % c.repo_name)}" type="application/rss+xml" />
13 <link href="${h.route_path('atom_feed_home', repo_name=c.rhodecode_db_repo.repo_name, _query=dict(auth_token=c.rhodecode_user.feed_token))}" rel="alternate" title="${h.tooltip(_('%s ATOM feed') % c.repo_name)}" type="application/atom+xml" />
14 <link href="${h.route_path('rss_feed_home', repo_name=c.rhodecode_db_repo.repo_name, _query=dict(auth_token=c.rhodecode_user.feed_token))}" rel="alternate" title="${h.tooltip(_('%s RSS feed') % c.repo_name)}" type="application/rss+xml" />
15 15 </%def>
16 16
17 17
18 18 <%def name="menu_bar_nav()">
19 19 ${self.menu_items(active='repositories')}
20 20 </%def>
21 21
22 22
23 23 <%def name="breadcrumbs_links()">
24 24 </%def>
25 25
26 26
27 27 <%def name="main()">
28 28 ${next.main()}
29 29 </%def>
@@ -1,128 +1,128 b''
1 1 <%inherit file="/summary/base.mako"/>
2 2
3 3 <%namespace name="components" file="/summary/components.mako"/>
4 4
5 5
6 6 <%def name="menu_bar_subnav()">
7 7 ${self.repo_menu(active='summary')}
8 8 </%def>
9 9
10 10 <%def name="main()">
11 11
12 12 <div class="title">
13 13 ${self.repo_page_title(c.rhodecode_db_repo)}
14 14 <ul class="links icon-only-links block-right">
15 15 <li>
16 16 %if c.rhodecode_user.username != h.DEFAULT_USER:
17 <a href="${h.url('atom_feed_home',repo_name=c.rhodecode_db_repo.repo_name,auth_token=c.rhodecode_user.feed_token)}" title="${_('RSS Feed')}"><i class="icon-rss-sign"></i></a>
17 <a href="${h.route_path('atom_feed_home', repo_name=c.rhodecode_db_repo.repo_name, _query=dict(auth_token=c.rhodecode_user.feed_token))}" title="${_('RSS Feed')}"><i class="icon-rss-sign"></i></a>
18 18 %else:
19 <a href="${h.url('atom_feed_home',repo_name=c.rhodecode_db_repo.repo_name)}" title="${_('RSS Feed')}"><i class="icon-rss-sign"></i></a>
19 <a href="${h.route_path('atom_feed_home', repo_name=c.rhodecode_db_repo.repo_name)}" title="${_('RSS Feed')}"><i class="icon-rss-sign"></i></a>
20 20 %endif
21 21 </li>
22 22 </ul>
23 23 </div>
24 24
25 25 <div id="repo-summary" class="summary">
26 26 ${components.summary_detail(breadcrumbs_links=self.breadcrumbs_links(), show_downloads=True)}
27 27 ${components.summary_stats(gravatar_function=self.gravatar_with_user)}
28 28 </div><!--end repo-summary-->
29 29
30 30
31 31 <div class="box" >
32 32 %if not c.repo_commits:
33 33 <div class="title">
34 34 <h3>${_('Quick start')}</h3>
35 35 </div>
36 36 %endif
37 37 <div class="table">
38 38 <div id="shortlog_data">
39 39 <%include file='summary_commits.mako'/>
40 40 </div>
41 41 </div>
42 42 </div>
43 43
44 44 %if c.readme_data:
45 45 <div id="readme" class="anchor">
46 46 <div class="box" >
47 47 <div class="title" title="${h.tooltip(_('Readme file from commit %s:%s') % (c.rhodecode_db_repo.landing_rev[0], c.rhodecode_db_repo.landing_rev[1]))}">
48 48 <h3 class="breadcrumbs">
49 49 <a href="${h.url('files_home',repo_name=c.repo_name,revision='tip',f_path=c.readme_file)}">${c.readme_file}</a>
50 50 </h3>
51 51 </div>
52 52 <div class="readme codeblock">
53 53 <div class="readme_box">
54 54 ${c.readme_data|n}
55 55 </div>
56 56 </div>
57 57 </div>
58 58 </div>
59 59 %endif
60 60
61 61 <script type="text/javascript">
62 62 $(document).ready(function(){
63 63 $('#clone_by_name').on('click',function(e){
64 64 // show url by name and hide name button
65 65 $('#clone_url').show();
66 66 $('#clone_by_name').hide();
67 67
68 68 // hide url by id and show name button
69 69 $('#clone_by_id').show();
70 70 $('#clone_url_id').hide();
71 71
72 72 });
73 73 $('#clone_by_id').on('click',function(e){
74 74
75 75 // show url by id and hide id button
76 76 $('#clone_by_id').hide();
77 77 $('#clone_url_id').show();
78 78
79 79 // hide url by name and show id button
80 80 $('#clone_by_name').show();
81 81 $('#clone_url').hide();
82 82 });
83 83
84 84 var initialCommitData = {
85 85 id: null,
86 86 text: 'tip',
87 87 type: 'tag',
88 88 raw_id: null,
89 89 files_url: null
90 90 };
91 91
92 92 select2RefSwitcher('#download_options', initialCommitData);
93 93
94 94 // on change of download options
95 95 $('#download_options').on('change', function(e) {
96 96 // format of Object {text: "v0.0.3", type: "tag", id: "rev"}
97 97 var selected_cs = e.added;
98 98 var fname= e.added.raw_id + ".zip";
99 99 var href = pyroutes.url('files_archive_home', {'repo_name': templateContext.repo_name, 'fname':fname});
100 100 // set new label
101 101 $('#archive_link').html('<i class="icon-archive"></i> '+ e.added.text+".zip");
102 102
103 103 // set new url to button,
104 104 $('#archive_link').attr('href', href)
105 105 });
106 106
107 107
108 108 // load details on summary page expand
109 109 $('#summary_details_expand').on('click', function() {
110 110
111 111 var callback = function (data) {
112 112 % if c.show_stats:
113 113 showRepoStats('lang_stats', data);
114 114 % endif
115 115 };
116 116
117 117 showRepoSize(
118 118 'repo_size_container',
119 119 templateContext.repo_name,
120 120 templateContext.repo_landing_commit,
121 121 callback);
122 122
123 123 })
124 124
125 125 })
126 126 </script>
127 127
128 128 </%def>
1 NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now