##// END OF EJS Templates
core: moved channelstream test into pyramid.
marcink -
r1756:278bcf2a default
parent child Browse files
Show More
@@ -1,52 +1,55 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2016-2017 RhodeCode GmbH
3 # Copyright (C) 2016-2017 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
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
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
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/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21
21
22 from rhodecode.apps._base import ADMIN_PREFIX
22 from rhodecode.apps._base import ADMIN_PREFIX
23
23
24
24
25 def includeme(config):
25 def includeme(config):
26
26
27 config.add_route(
27 config.add_route(
28 name='my_account_profile',
28 name='my_account_profile',
29 pattern=ADMIN_PREFIX + '/my_account/profile')
29 pattern=ADMIN_PREFIX + '/my_account/profile')
30
30
31 config.add_route(
31 config.add_route(
32 name='my_account_password',
32 name='my_account_password',
33 pattern=ADMIN_PREFIX + '/my_account/password')
33 pattern=ADMIN_PREFIX + '/my_account/password')
34
34
35 config.add_route(
35 config.add_route(
36 name='my_account_password_update',
36 name='my_account_password_update',
37 pattern=ADMIN_PREFIX + '/my_account/password')
37 pattern=ADMIN_PREFIX + '/my_account/password')
38
38
39 config.add_route(
39 config.add_route(
40 name='my_account_auth_tokens',
40 name='my_account_auth_tokens',
41 pattern=ADMIN_PREFIX + '/my_account/auth_tokens')
41 pattern=ADMIN_PREFIX + '/my_account/auth_tokens')
42 config.add_route(
42 config.add_route(
43 name='my_account_auth_tokens_add',
43 name='my_account_auth_tokens_add',
44 pattern=ADMIN_PREFIX + '/my_account/auth_tokens/new',
44 pattern=ADMIN_PREFIX + '/my_account/auth_tokens/new')
45 )
46 config.add_route(
45 config.add_route(
47 name='my_account_auth_tokens_delete',
46 name='my_account_auth_tokens_delete',
48 pattern=ADMIN_PREFIX + '/my_account/auth_tokens/delete',
47 pattern=ADMIN_PREFIX + '/my_account/auth_tokens/delete')
49 )
48
49 # channelstream test
50 config.add_route(
51 name='my_account_notifications_test_channelstream',
52 pattern=ADMIN_PREFIX + '/my_account/test_channelstream')
50
53
51 # Scan module for configuration decorators.
54 # Scan module for configuration decorators.
52 config.scan()
55 config.scan()
@@ -1,194 +1,231 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2016-2017 RhodeCode GmbH
3 # Copyright (C) 2016-2017 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
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
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
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/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import logging
21 import logging
22 import datetime
22
23
23 from pyramid.httpexceptions import HTTPFound
24 from pyramid.httpexceptions import HTTPFound
24 from pyramid.view import view_config
25 from pyramid.view import view_config
25
26
26 from rhodecode.apps._base import BaseAppView
27 from rhodecode.apps._base import BaseAppView
27 from rhodecode import forms
28 from rhodecode import forms
29 from rhodecode.lib import helpers as h
28 from rhodecode.lib.auth import LoginRequired, NotAnonymous, CSRFRequired
30 from rhodecode.lib.auth import LoginRequired, NotAnonymous, CSRFRequired
29 from rhodecode.lib import helpers as h
31 from rhodecode.lib.channelstream import channelstream_request, \
32 ChannelstreamException
30 from rhodecode.lib.utils2 import safe_int, md5
33 from rhodecode.lib.utils2 import safe_int, md5
31 from rhodecode.model.auth_token import AuthTokenModel
34 from rhodecode.model.auth_token import AuthTokenModel
32 from rhodecode.model.meta import Session
35 from rhodecode.model.meta import Session
33 from rhodecode.model.user import UserModel
36 from rhodecode.model.user import UserModel
34 from rhodecode.model.validation_schema.schemas import user_schema
37 from rhodecode.model.validation_schema.schemas import user_schema
35
38
36 log = logging.getLogger(__name__)
39 log = logging.getLogger(__name__)
37
40
38
41
39 class MyAccountView(BaseAppView):
42 class MyAccountView(BaseAppView):
40 ALLOW_SCOPED_TOKENS = False
43 ALLOW_SCOPED_TOKENS = False
41 """
44 """
42 This view has alternative version inside EE, if modified please take a look
45 This view has alternative version inside EE, if modified please take a look
43 in there as well.
46 in there as well.
44 """
47 """
45
48
46 def load_default_context(self):
49 def load_default_context(self):
47 c = self._get_local_tmpl_context()
50 c = self._get_local_tmpl_context()
48 c.user = c.auth_user.get_instance()
51 c.user = c.auth_user.get_instance()
49 c.allow_scoped_tokens = self.ALLOW_SCOPED_TOKENS
52 c.allow_scoped_tokens = self.ALLOW_SCOPED_TOKENS
50 self._register_global_c(c)
53 self._register_global_c(c)
51 return c
54 return c
52
55
53 @LoginRequired()
56 @LoginRequired()
54 @NotAnonymous()
57 @NotAnonymous()
55 @view_config(
58 @view_config(
56 route_name='my_account_profile', request_method='GET',
59 route_name='my_account_profile', request_method='GET',
57 renderer='rhodecode:templates/admin/my_account/my_account.mako')
60 renderer='rhodecode:templates/admin/my_account/my_account.mako')
58 def my_account_profile(self):
61 def my_account_profile(self):
59 c = self.load_default_context()
62 c = self.load_default_context()
60 c.active = 'profile'
63 c.active = 'profile'
61 return self._get_template_context(c)
64 return self._get_template_context(c)
62
65
63 @LoginRequired()
66 @LoginRequired()
64 @NotAnonymous()
67 @NotAnonymous()
65 @view_config(
68 @view_config(
66 route_name='my_account_password', request_method='GET',
69 route_name='my_account_password', request_method='GET',
67 renderer='rhodecode:templates/admin/my_account/my_account.mako')
70 renderer='rhodecode:templates/admin/my_account/my_account.mako')
68 def my_account_password(self):
71 def my_account_password(self):
69 c = self.load_default_context()
72 c = self.load_default_context()
70 c.active = 'password'
73 c.active = 'password'
71 c.extern_type = c.user.extern_type
74 c.extern_type = c.user.extern_type
72
75
73 schema = user_schema.ChangePasswordSchema().bind(
76 schema = user_schema.ChangePasswordSchema().bind(
74 username=c.user.username)
77 username=c.user.username)
75
78
76 form = forms.Form(
79 form = forms.Form(
77 schema, buttons=(forms.buttons.save, forms.buttons.reset))
80 schema, buttons=(forms.buttons.save, forms.buttons.reset))
78
81
79 c.form = form
82 c.form = form
80 return self._get_template_context(c)
83 return self._get_template_context(c)
81
84
82 @LoginRequired()
85 @LoginRequired()
83 @NotAnonymous()
86 @NotAnonymous()
84 @CSRFRequired()
87 @CSRFRequired()
85 @view_config(
88 @view_config(
86 route_name='my_account_password', request_method='POST',
89 route_name='my_account_password', request_method='POST',
87 renderer='rhodecode:templates/admin/my_account/my_account.mako')
90 renderer='rhodecode:templates/admin/my_account/my_account.mako')
88 def my_account_password_update(self):
91 def my_account_password_update(self):
89 _ = self.request.translate
92 _ = self.request.translate
90 c = self.load_default_context()
93 c = self.load_default_context()
91 c.active = 'password'
94 c.active = 'password'
92 c.extern_type = c.user.extern_type
95 c.extern_type = c.user.extern_type
93
96
94 schema = user_schema.ChangePasswordSchema().bind(
97 schema = user_schema.ChangePasswordSchema().bind(
95 username=c.user.username)
98 username=c.user.username)
96
99
97 form = forms.Form(
100 form = forms.Form(
98 schema, buttons=(forms.buttons.save, forms.buttons.reset))
101 schema, buttons=(forms.buttons.save, forms.buttons.reset))
99
102
100 if c.extern_type != 'rhodecode':
103 if c.extern_type != 'rhodecode':
101 raise HTTPFound(self.request.route_path('my_account_password'))
104 raise HTTPFound(self.request.route_path('my_account_password'))
102
105
103 controls = self.request.POST.items()
106 controls = self.request.POST.items()
104 try:
107 try:
105 valid_data = form.validate(controls)
108 valid_data = form.validate(controls)
106 UserModel().update_user(c.user.user_id, **valid_data)
109 UserModel().update_user(c.user.user_id, **valid_data)
107 c.user.update_userdata(force_password_change=False)
110 c.user.update_userdata(force_password_change=False)
108 Session().commit()
111 Session().commit()
109 except forms.ValidationFailure as e:
112 except forms.ValidationFailure as e:
110 c.form = e
113 c.form = e
111 return self._get_template_context(c)
114 return self._get_template_context(c)
112
115
113 except Exception:
116 except Exception:
114 log.exception("Exception updating password")
117 log.exception("Exception updating password")
115 h.flash(_('Error occurred during update of user password'),
118 h.flash(_('Error occurred during update of user password'),
116 category='error')
119 category='error')
117 else:
120 else:
118 instance = c.auth_user.get_instance()
121 instance = c.auth_user.get_instance()
119 self.session.setdefault('rhodecode_user', {}).update(
122 self.session.setdefault('rhodecode_user', {}).update(
120 {'password': md5(instance.password)})
123 {'password': md5(instance.password)})
121 self.session.save()
124 self.session.save()
122 h.flash(_("Successfully updated password"), category='success')
125 h.flash(_("Successfully updated password"), category='success')
123
126
124 raise HTTPFound(self.request.route_path('my_account_password'))
127 raise HTTPFound(self.request.route_path('my_account_password'))
125
128
126 @LoginRequired()
129 @LoginRequired()
127 @NotAnonymous()
130 @NotAnonymous()
128 @view_config(
131 @view_config(
129 route_name='my_account_auth_tokens', request_method='GET',
132 route_name='my_account_auth_tokens', request_method='GET',
130 renderer='rhodecode:templates/admin/my_account/my_account.mako')
133 renderer='rhodecode:templates/admin/my_account/my_account.mako')
131 def my_account_auth_tokens(self):
134 def my_account_auth_tokens(self):
132 _ = self.request.translate
135 _ = self.request.translate
133
136
134 c = self.load_default_context()
137 c = self.load_default_context()
135 c.active = 'auth_tokens'
138 c.active = 'auth_tokens'
136
139
137 c.lifetime_values = [
140 c.lifetime_values = [
138 (str(-1), _('forever')),
141 (str(-1), _('forever')),
139 (str(5), _('5 minutes')),
142 (str(5), _('5 minutes')),
140 (str(60), _('1 hour')),
143 (str(60), _('1 hour')),
141 (str(60 * 24), _('1 day')),
144 (str(60 * 24), _('1 day')),
142 (str(60 * 24 * 30), _('1 month')),
145 (str(60 * 24 * 30), _('1 month')),
143 ]
146 ]
144 c.lifetime_options = [(c.lifetime_values, _("Lifetime"))]
147 c.lifetime_options = [(c.lifetime_values, _("Lifetime"))]
145 c.role_values = [
148 c.role_values = [
146 (x, AuthTokenModel.cls._get_role_name(x))
149 (x, AuthTokenModel.cls._get_role_name(x))
147 for x in AuthTokenModel.cls.ROLES]
150 for x in AuthTokenModel.cls.ROLES]
148 c.role_options = [(c.role_values, _("Role"))]
151 c.role_options = [(c.role_values, _("Role"))]
149 c.user_auth_tokens = AuthTokenModel().get_auth_tokens(
152 c.user_auth_tokens = AuthTokenModel().get_auth_tokens(
150 c.user.user_id, show_expired=True)
153 c.user.user_id, show_expired=True)
151 return self._get_template_context(c)
154 return self._get_template_context(c)
152
155
153 def maybe_attach_token_scope(self, token):
156 def maybe_attach_token_scope(self, token):
154 # implemented in EE edition
157 # implemented in EE edition
155 pass
158 pass
156
159
157 @LoginRequired()
160 @LoginRequired()
158 @NotAnonymous()
161 @NotAnonymous()
159 @CSRFRequired()
162 @CSRFRequired()
160 @view_config(
163 @view_config(
161 route_name='my_account_auth_tokens_add', request_method='POST')
164 route_name='my_account_auth_tokens_add', request_method='POST')
162 def my_account_auth_tokens_add(self):
165 def my_account_auth_tokens_add(self):
163 _ = self.request.translate
166 _ = self.request.translate
164 c = self.load_default_context()
167 c = self.load_default_context()
165
168
166 lifetime = safe_int(self.request.POST.get('lifetime'), -1)
169 lifetime = safe_int(self.request.POST.get('lifetime'), -1)
167 description = self.request.POST.get('description')
170 description = self.request.POST.get('description')
168 role = self.request.POST.get('role')
171 role = self.request.POST.get('role')
169
172
170 token = AuthTokenModel().create(
173 token = AuthTokenModel().create(
171 c.user.user_id, description, lifetime, role)
174 c.user.user_id, description, lifetime, role)
172 self.maybe_attach_token_scope(token)
175 self.maybe_attach_token_scope(token)
173 Session().commit()
176 Session().commit()
174
177
175 h.flash(_("Auth token successfully created"), category='success')
178 h.flash(_("Auth token successfully created"), category='success')
176 return HTTPFound(h.route_path('my_account_auth_tokens'))
179 return HTTPFound(h.route_path('my_account_auth_tokens'))
177
180
178 @LoginRequired()
181 @LoginRequired()
179 @NotAnonymous()
182 @NotAnonymous()
180 @CSRFRequired()
183 @CSRFRequired()
181 @view_config(
184 @view_config(
182 route_name='my_account_auth_tokens_delete', request_method='POST')
185 route_name='my_account_auth_tokens_delete', request_method='POST')
183 def my_account_auth_tokens_delete(self):
186 def my_account_auth_tokens_delete(self):
184 _ = self.request.translate
187 _ = self.request.translate
185 c = self.load_default_context()
188 c = self.load_default_context()
186
189
187 del_auth_token = self.request.POST.get('del_auth_token')
190 del_auth_token = self.request.POST.get('del_auth_token')
188
191
189 if del_auth_token:
192 if del_auth_token:
190 AuthTokenModel().delete(del_auth_token, c.user.user_id)
193 AuthTokenModel().delete(del_auth_token, c.user.user_id)
191 Session().commit()
194 Session().commit()
192 h.flash(_("Auth token successfully deleted"), category='success')
195 h.flash(_("Auth token successfully deleted"), category='success')
193
196
194 return HTTPFound(h.route_path('my_account_auth_tokens'))
197 return HTTPFound(h.route_path('my_account_auth_tokens'))
198
199 @LoginRequired()
200 @NotAnonymous()
201 @CSRFRequired()
202 @view_config(
203 route_name='my_account_notifications_test_channelstream',
204 request_method='POST', renderer='json_ext')
205 def my_account_notifications_test_channelstream(self):
206 message = 'Test message sent via Channelstream by user: {}, on {}'.format(
207 self._rhodecode_user.username, datetime.datetime.now())
208 payload = {
209 # 'channel': 'broadcast',
210 'type': 'message',
211 'timestamp': datetime.datetime.utcnow(),
212 'user': 'system',
213 'pm_users': [self._rhodecode_user.username],
214 'message': {
215 'message': message,
216 'level': 'info',
217 'topic': '/notifications'
218 }
219 }
220
221 registry = self.request.registry
222 rhodecode_plugins = getattr(registry, 'rhodecode_plugins', {})
223 channelstream_config = rhodecode_plugins.get('channelstream', {})
224
225 try:
226 channelstream_request(channelstream_config, [payload], '/message')
227 except ChannelstreamException as e:
228 log.exception('Failed to send channelstream data')
229 return {"response": 'ERROR: {}'.format(e.__class__.__name__)}
230 return {"response": 'Channelstream data sent. '
231 'You should see a new live message now.'}
@@ -1,1057 +1,1053 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2017 RhodeCode GmbH
3 # Copyright (C) 2010-2017 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
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
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
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/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 """
21 """
22 Routes configuration
22 Routes configuration
23
23
24 The more specific and detailed routes should be defined first so they
24 The more specific and detailed routes should be defined first so they
25 may take precedent over the more generic routes. For more information
25 may take precedent over the more generic routes. For more information
26 refer to the routes manual at http://routes.groovie.org/docs/
26 refer to the routes manual at http://routes.groovie.org/docs/
27
27
28 IMPORTANT: if you change any routing here, make sure to take a look at lib/base.py
28 IMPORTANT: if you change any routing here, make sure to take a look at lib/base.py
29 and _route_name variable which uses some of stored naming here to do redirects.
29 and _route_name variable which uses some of stored naming here to do redirects.
30 """
30 """
31 import os
31 import os
32 import re
32 import re
33 from routes import Mapper
33 from routes import Mapper
34
34
35 # prefix for non repository related links needs to be prefixed with `/`
35 # prefix for non repository related links needs to be prefixed with `/`
36 ADMIN_PREFIX = '/_admin'
36 ADMIN_PREFIX = '/_admin'
37 STATIC_FILE_PREFIX = '/_static'
37 STATIC_FILE_PREFIX = '/_static'
38
38
39 # Default requirements for URL parts
39 # Default requirements for URL parts
40 URL_NAME_REQUIREMENTS = {
40 URL_NAME_REQUIREMENTS = {
41 # group name can have a slash in them, but they must not end with a slash
41 # group name can have a slash in them, but they must not end with a slash
42 'group_name': r'.*?[^/]',
42 'group_name': r'.*?[^/]',
43 'repo_group_name': r'.*?[^/]',
43 'repo_group_name': r'.*?[^/]',
44 # repo names can have a slash in them, but they must not end with a slash
44 # repo names can have a slash in them, but they must not end with a slash
45 'repo_name': r'.*?[^/]',
45 'repo_name': r'.*?[^/]',
46 # file path eats up everything at the end
46 # file path eats up everything at the end
47 'f_path': r'.*',
47 'f_path': r'.*',
48 # reference types
48 # reference types
49 'source_ref_type': '(branch|book|tag|rev|\%\(source_ref_type\)s)',
49 'source_ref_type': '(branch|book|tag|rev|\%\(source_ref_type\)s)',
50 'target_ref_type': '(branch|book|tag|rev|\%\(target_ref_type\)s)',
50 'target_ref_type': '(branch|book|tag|rev|\%\(target_ref_type\)s)',
51 }
51 }
52
52
53
53
54 def add_route_requirements(route_path, requirements):
54 def add_route_requirements(route_path, requirements):
55 """
55 """
56 Adds regex requirements to pyramid routes using a mapping dict
56 Adds regex requirements to pyramid routes using a mapping dict
57
57
58 >>> add_route_requirements('/{action}/{id}', {'id': r'\d+'})
58 >>> add_route_requirements('/{action}/{id}', {'id': r'\d+'})
59 '/{action}/{id:\d+}'
59 '/{action}/{id:\d+}'
60
60
61 """
61 """
62 for key, regex in requirements.items():
62 for key, regex in requirements.items():
63 route_path = route_path.replace('{%s}' % key, '{%s:%s}' % (key, regex))
63 route_path = route_path.replace('{%s}' % key, '{%s:%s}' % (key, regex))
64 return route_path
64 return route_path
65
65
66
66
67 class JSRoutesMapper(Mapper):
67 class JSRoutesMapper(Mapper):
68 """
68 """
69 Wrapper for routes.Mapper to make pyroutes compatible url definitions
69 Wrapper for routes.Mapper to make pyroutes compatible url definitions
70 """
70 """
71 _named_route_regex = re.compile(r'^[a-z-_0-9A-Z]+$')
71 _named_route_regex = re.compile(r'^[a-z-_0-9A-Z]+$')
72 _argument_prog = re.compile('\{(.*?)\}|:\((.*)\)')
72 _argument_prog = re.compile('\{(.*?)\}|:\((.*)\)')
73 def __init__(self, *args, **kw):
73 def __init__(self, *args, **kw):
74 super(JSRoutesMapper, self).__init__(*args, **kw)
74 super(JSRoutesMapper, self).__init__(*args, **kw)
75 self._jsroutes = []
75 self._jsroutes = []
76
76
77 def connect(self, *args, **kw):
77 def connect(self, *args, **kw):
78 """
78 """
79 Wrapper for connect to take an extra argument jsroute=True
79 Wrapper for connect to take an extra argument jsroute=True
80
80
81 :param jsroute: boolean, if True will add the route to the pyroutes list
81 :param jsroute: boolean, if True will add the route to the pyroutes list
82 """
82 """
83 if kw.pop('jsroute', False):
83 if kw.pop('jsroute', False):
84 if not self._named_route_regex.match(args[0]):
84 if not self._named_route_regex.match(args[0]):
85 raise Exception('only named routes can be added to pyroutes')
85 raise Exception('only named routes can be added to pyroutes')
86 self._jsroutes.append(args[0])
86 self._jsroutes.append(args[0])
87
87
88 super(JSRoutesMapper, self).connect(*args, **kw)
88 super(JSRoutesMapper, self).connect(*args, **kw)
89
89
90 def _extract_route_information(self, route):
90 def _extract_route_information(self, route):
91 """
91 """
92 Convert a route into tuple(name, path, args), eg:
92 Convert a route into tuple(name, path, args), eg:
93 ('show_user', '/profile/%(username)s', ['username'])
93 ('show_user', '/profile/%(username)s', ['username'])
94 """
94 """
95 routepath = route.routepath
95 routepath = route.routepath
96 def replace(matchobj):
96 def replace(matchobj):
97 if matchobj.group(1):
97 if matchobj.group(1):
98 return "%%(%s)s" % matchobj.group(1).split(':')[0]
98 return "%%(%s)s" % matchobj.group(1).split(':')[0]
99 else:
99 else:
100 return "%%(%s)s" % matchobj.group(2)
100 return "%%(%s)s" % matchobj.group(2)
101
101
102 routepath = self._argument_prog.sub(replace, routepath)
102 routepath = self._argument_prog.sub(replace, routepath)
103 return (
103 return (
104 route.name,
104 route.name,
105 routepath,
105 routepath,
106 [(arg[0].split(':')[0] if arg[0] != '' else arg[1])
106 [(arg[0].split(':')[0] if arg[0] != '' else arg[1])
107 for arg in self._argument_prog.findall(route.routepath)]
107 for arg in self._argument_prog.findall(route.routepath)]
108 )
108 )
109
109
110 def jsroutes(self):
110 def jsroutes(self):
111 """
111 """
112 Return a list of pyroutes.js compatible routes
112 Return a list of pyroutes.js compatible routes
113 """
113 """
114 for route_name in self._jsroutes:
114 for route_name in self._jsroutes:
115 yield self._extract_route_information(self._routenames[route_name])
115 yield self._extract_route_information(self._routenames[route_name])
116
116
117
117
118 def make_map(config):
118 def make_map(config):
119 """Create, configure and return the routes Mapper"""
119 """Create, configure and return the routes Mapper"""
120 rmap = JSRoutesMapper(directory=config['pylons.paths']['controllers'],
120 rmap = JSRoutesMapper(directory=config['pylons.paths']['controllers'],
121 always_scan=config['debug'])
121 always_scan=config['debug'])
122 rmap.minimization = False
122 rmap.minimization = False
123 rmap.explicit = False
123 rmap.explicit = False
124
124
125 from rhodecode.lib.utils2 import str2bool
125 from rhodecode.lib.utils2 import str2bool
126 from rhodecode.model import repo, repo_group
126 from rhodecode.model import repo, repo_group
127
127
128 def check_repo(environ, match_dict):
128 def check_repo(environ, match_dict):
129 """
129 """
130 check for valid repository for proper 404 handling
130 check for valid repository for proper 404 handling
131
131
132 :param environ:
132 :param environ:
133 :param match_dict:
133 :param match_dict:
134 """
134 """
135 repo_name = match_dict.get('repo_name')
135 repo_name = match_dict.get('repo_name')
136
136
137 if match_dict.get('f_path'):
137 if match_dict.get('f_path'):
138 # fix for multiple initial slashes that causes errors
138 # fix for multiple initial slashes that causes errors
139 match_dict['f_path'] = match_dict['f_path'].lstrip('/')
139 match_dict['f_path'] = match_dict['f_path'].lstrip('/')
140 repo_model = repo.RepoModel()
140 repo_model = repo.RepoModel()
141 by_name_match = repo_model.get_by_repo_name(repo_name)
141 by_name_match = repo_model.get_by_repo_name(repo_name)
142 # if we match quickly from database, short circuit the operation,
142 # if we match quickly from database, short circuit the operation,
143 # and validate repo based on the type.
143 # and validate repo based on the type.
144 if by_name_match:
144 if by_name_match:
145 return True
145 return True
146
146
147 by_id_match = repo_model.get_repo_by_id(repo_name)
147 by_id_match = repo_model.get_repo_by_id(repo_name)
148 if by_id_match:
148 if by_id_match:
149 repo_name = by_id_match.repo_name
149 repo_name = by_id_match.repo_name
150 match_dict['repo_name'] = repo_name
150 match_dict['repo_name'] = repo_name
151 return True
151 return True
152
152
153 return False
153 return False
154
154
155 def check_group(environ, match_dict):
155 def check_group(environ, match_dict):
156 """
156 """
157 check for valid repository group path for proper 404 handling
157 check for valid repository group path for proper 404 handling
158
158
159 :param environ:
159 :param environ:
160 :param match_dict:
160 :param match_dict:
161 """
161 """
162 repo_group_name = match_dict.get('group_name')
162 repo_group_name = match_dict.get('group_name')
163 repo_group_model = repo_group.RepoGroupModel()
163 repo_group_model = repo_group.RepoGroupModel()
164 by_name_match = repo_group_model.get_by_group_name(repo_group_name)
164 by_name_match = repo_group_model.get_by_group_name(repo_group_name)
165 if by_name_match:
165 if by_name_match:
166 return True
166 return True
167
167
168 return False
168 return False
169
169
170 def check_user_group(environ, match_dict):
170 def check_user_group(environ, match_dict):
171 """
171 """
172 check for valid user group for proper 404 handling
172 check for valid user group for proper 404 handling
173
173
174 :param environ:
174 :param environ:
175 :param match_dict:
175 :param match_dict:
176 """
176 """
177 return True
177 return True
178
178
179 def check_int(environ, match_dict):
179 def check_int(environ, match_dict):
180 return match_dict.get('id').isdigit()
180 return match_dict.get('id').isdigit()
181
181
182
182
183 #==========================================================================
183 #==========================================================================
184 # CUSTOM ROUTES HERE
184 # CUSTOM ROUTES HERE
185 #==========================================================================
185 #==========================================================================
186
186
187 # MAIN PAGE
187 # MAIN PAGE
188 rmap.connect('home', '/', controller='home', action='index')
188 rmap.connect('home', '/', controller='home', action='index')
189
189
190 # ping and pylons error test
190 # ping and pylons error test
191 rmap.connect('ping', '%s/ping' % (ADMIN_PREFIX,), controller='home', action='ping')
191 rmap.connect('ping', '%s/ping' % (ADMIN_PREFIX,), controller='home', action='ping')
192 rmap.connect('error_test', '%s/error_test' % (ADMIN_PREFIX,), controller='home', action='error_test')
192 rmap.connect('error_test', '%s/error_test' % (ADMIN_PREFIX,), controller='home', action='error_test')
193
193
194 # ADMIN REPOSITORY ROUTES
194 # ADMIN REPOSITORY ROUTES
195 with rmap.submapper(path_prefix=ADMIN_PREFIX,
195 with rmap.submapper(path_prefix=ADMIN_PREFIX,
196 controller='admin/repos') as m:
196 controller='admin/repos') as m:
197 m.connect('repos', '/repos',
197 m.connect('repos', '/repos',
198 action='create', conditions={'method': ['POST']})
198 action='create', conditions={'method': ['POST']})
199 m.connect('repos', '/repos',
199 m.connect('repos', '/repos',
200 action='index', conditions={'method': ['GET']})
200 action='index', conditions={'method': ['GET']})
201 m.connect('new_repo', '/create_repository', jsroute=True,
201 m.connect('new_repo', '/create_repository', jsroute=True,
202 action='create_repository', conditions={'method': ['GET']})
202 action='create_repository', conditions={'method': ['GET']})
203 m.connect('delete_repo', '/repos/{repo_name}',
203 m.connect('delete_repo', '/repos/{repo_name}',
204 action='delete', conditions={'method': ['DELETE']},
204 action='delete', conditions={'method': ['DELETE']},
205 requirements=URL_NAME_REQUIREMENTS)
205 requirements=URL_NAME_REQUIREMENTS)
206 m.connect('repo', '/repos/{repo_name}',
206 m.connect('repo', '/repos/{repo_name}',
207 action='show', conditions={'method': ['GET'],
207 action='show', conditions={'method': ['GET'],
208 'function': check_repo},
208 'function': check_repo},
209 requirements=URL_NAME_REQUIREMENTS)
209 requirements=URL_NAME_REQUIREMENTS)
210
210
211 # ADMIN REPOSITORY GROUPS ROUTES
211 # ADMIN REPOSITORY GROUPS ROUTES
212 with rmap.submapper(path_prefix=ADMIN_PREFIX,
212 with rmap.submapper(path_prefix=ADMIN_PREFIX,
213 controller='admin/repo_groups') as m:
213 controller='admin/repo_groups') as m:
214 m.connect('repo_groups', '/repo_groups',
214 m.connect('repo_groups', '/repo_groups',
215 action='create', conditions={'method': ['POST']})
215 action='create', conditions={'method': ['POST']})
216 m.connect('repo_groups', '/repo_groups',
216 m.connect('repo_groups', '/repo_groups',
217 action='index', conditions={'method': ['GET']})
217 action='index', conditions={'method': ['GET']})
218 m.connect('new_repo_group', '/repo_groups/new',
218 m.connect('new_repo_group', '/repo_groups/new',
219 action='new', conditions={'method': ['GET']})
219 action='new', conditions={'method': ['GET']})
220 m.connect('update_repo_group', '/repo_groups/{group_name}',
220 m.connect('update_repo_group', '/repo_groups/{group_name}',
221 action='update', conditions={'method': ['PUT'],
221 action='update', conditions={'method': ['PUT'],
222 'function': check_group},
222 'function': check_group},
223 requirements=URL_NAME_REQUIREMENTS)
223 requirements=URL_NAME_REQUIREMENTS)
224
224
225 # EXTRAS REPO GROUP ROUTES
225 # EXTRAS REPO GROUP ROUTES
226 m.connect('edit_repo_group', '/repo_groups/{group_name}/edit',
226 m.connect('edit_repo_group', '/repo_groups/{group_name}/edit',
227 action='edit',
227 action='edit',
228 conditions={'method': ['GET'], 'function': check_group},
228 conditions={'method': ['GET'], 'function': check_group},
229 requirements=URL_NAME_REQUIREMENTS)
229 requirements=URL_NAME_REQUIREMENTS)
230 m.connect('edit_repo_group', '/repo_groups/{group_name}/edit',
230 m.connect('edit_repo_group', '/repo_groups/{group_name}/edit',
231 action='edit',
231 action='edit',
232 conditions={'method': ['PUT'], 'function': check_group},
232 conditions={'method': ['PUT'], 'function': check_group},
233 requirements=URL_NAME_REQUIREMENTS)
233 requirements=URL_NAME_REQUIREMENTS)
234
234
235 m.connect('edit_repo_group_advanced', '/repo_groups/{group_name}/edit/advanced',
235 m.connect('edit_repo_group_advanced', '/repo_groups/{group_name}/edit/advanced',
236 action='edit_repo_group_advanced',
236 action='edit_repo_group_advanced',
237 conditions={'method': ['GET'], 'function': check_group},
237 conditions={'method': ['GET'], 'function': check_group},
238 requirements=URL_NAME_REQUIREMENTS)
238 requirements=URL_NAME_REQUIREMENTS)
239 m.connect('edit_repo_group_advanced', '/repo_groups/{group_name}/edit/advanced',
239 m.connect('edit_repo_group_advanced', '/repo_groups/{group_name}/edit/advanced',
240 action='edit_repo_group_advanced',
240 action='edit_repo_group_advanced',
241 conditions={'method': ['PUT'], 'function': check_group},
241 conditions={'method': ['PUT'], 'function': check_group},
242 requirements=URL_NAME_REQUIREMENTS)
242 requirements=URL_NAME_REQUIREMENTS)
243
243
244 m.connect('edit_repo_group_perms', '/repo_groups/{group_name}/edit/permissions',
244 m.connect('edit_repo_group_perms', '/repo_groups/{group_name}/edit/permissions',
245 action='edit_repo_group_perms',
245 action='edit_repo_group_perms',
246 conditions={'method': ['GET'], 'function': check_group},
246 conditions={'method': ['GET'], 'function': check_group},
247 requirements=URL_NAME_REQUIREMENTS)
247 requirements=URL_NAME_REQUIREMENTS)
248 m.connect('edit_repo_group_perms', '/repo_groups/{group_name}/edit/permissions',
248 m.connect('edit_repo_group_perms', '/repo_groups/{group_name}/edit/permissions',
249 action='update_perms',
249 action='update_perms',
250 conditions={'method': ['PUT'], 'function': check_group},
250 conditions={'method': ['PUT'], 'function': check_group},
251 requirements=URL_NAME_REQUIREMENTS)
251 requirements=URL_NAME_REQUIREMENTS)
252
252
253 m.connect('delete_repo_group', '/repo_groups/{group_name}',
253 m.connect('delete_repo_group', '/repo_groups/{group_name}',
254 action='delete', conditions={'method': ['DELETE'],
254 action='delete', conditions={'method': ['DELETE'],
255 'function': check_group},
255 'function': check_group},
256 requirements=URL_NAME_REQUIREMENTS)
256 requirements=URL_NAME_REQUIREMENTS)
257
257
258 # ADMIN USER ROUTES
258 # ADMIN USER ROUTES
259 with rmap.submapper(path_prefix=ADMIN_PREFIX,
259 with rmap.submapper(path_prefix=ADMIN_PREFIX,
260 controller='admin/users') as m:
260 controller='admin/users') as m:
261 m.connect('users', '/users',
261 m.connect('users', '/users',
262 action='create', conditions={'method': ['POST']})
262 action='create', conditions={'method': ['POST']})
263 m.connect('new_user', '/users/new',
263 m.connect('new_user', '/users/new',
264 action='new', conditions={'method': ['GET']})
264 action='new', conditions={'method': ['GET']})
265 m.connect('update_user', '/users/{user_id}',
265 m.connect('update_user', '/users/{user_id}',
266 action='update', conditions={'method': ['PUT']})
266 action='update', conditions={'method': ['PUT']})
267 m.connect('delete_user', '/users/{user_id}',
267 m.connect('delete_user', '/users/{user_id}',
268 action='delete', conditions={'method': ['DELETE']})
268 action='delete', conditions={'method': ['DELETE']})
269 m.connect('edit_user', '/users/{user_id}/edit',
269 m.connect('edit_user', '/users/{user_id}/edit',
270 action='edit', conditions={'method': ['GET']}, jsroute=True)
270 action='edit', conditions={'method': ['GET']}, jsroute=True)
271 m.connect('user', '/users/{user_id}',
271 m.connect('user', '/users/{user_id}',
272 action='show', conditions={'method': ['GET']})
272 action='show', conditions={'method': ['GET']})
273 m.connect('force_password_reset_user', '/users/{user_id}/password_reset',
273 m.connect('force_password_reset_user', '/users/{user_id}/password_reset',
274 action='reset_password', conditions={'method': ['POST']})
274 action='reset_password', conditions={'method': ['POST']})
275 m.connect('create_personal_repo_group', '/users/{user_id}/create_repo_group',
275 m.connect('create_personal_repo_group', '/users/{user_id}/create_repo_group',
276 action='create_personal_repo_group', conditions={'method': ['POST']})
276 action='create_personal_repo_group', conditions={'method': ['POST']})
277
277
278 # EXTRAS USER ROUTES
278 # EXTRAS USER ROUTES
279 m.connect('edit_user_advanced', '/users/{user_id}/edit/advanced',
279 m.connect('edit_user_advanced', '/users/{user_id}/edit/advanced',
280 action='edit_advanced', conditions={'method': ['GET']})
280 action='edit_advanced', conditions={'method': ['GET']})
281 m.connect('edit_user_advanced', '/users/{user_id}/edit/advanced',
281 m.connect('edit_user_advanced', '/users/{user_id}/edit/advanced',
282 action='update_advanced', conditions={'method': ['PUT']})
282 action='update_advanced', conditions={'method': ['PUT']})
283
283
284 m.connect('edit_user_global_perms', '/users/{user_id}/edit/global_permissions',
284 m.connect('edit_user_global_perms', '/users/{user_id}/edit/global_permissions',
285 action='edit_global_perms', conditions={'method': ['GET']})
285 action='edit_global_perms', conditions={'method': ['GET']})
286 m.connect('edit_user_global_perms', '/users/{user_id}/edit/global_permissions',
286 m.connect('edit_user_global_perms', '/users/{user_id}/edit/global_permissions',
287 action='update_global_perms', conditions={'method': ['PUT']})
287 action='update_global_perms', conditions={'method': ['PUT']})
288
288
289 m.connect('edit_user_perms_summary', '/users/{user_id}/edit/permissions_summary',
289 m.connect('edit_user_perms_summary', '/users/{user_id}/edit/permissions_summary',
290 action='edit_perms_summary', conditions={'method': ['GET']})
290 action='edit_perms_summary', conditions={'method': ['GET']})
291
291
292 m.connect('edit_user_emails', '/users/{user_id}/edit/emails',
292 m.connect('edit_user_emails', '/users/{user_id}/edit/emails',
293 action='edit_emails', conditions={'method': ['GET']})
293 action='edit_emails', conditions={'method': ['GET']})
294 m.connect('edit_user_emails', '/users/{user_id}/edit/emails',
294 m.connect('edit_user_emails', '/users/{user_id}/edit/emails',
295 action='add_email', conditions={'method': ['PUT']})
295 action='add_email', conditions={'method': ['PUT']})
296 m.connect('edit_user_emails', '/users/{user_id}/edit/emails',
296 m.connect('edit_user_emails', '/users/{user_id}/edit/emails',
297 action='delete_email', conditions={'method': ['DELETE']})
297 action='delete_email', conditions={'method': ['DELETE']})
298
298
299 m.connect('edit_user_ips', '/users/{user_id}/edit/ips',
299 m.connect('edit_user_ips', '/users/{user_id}/edit/ips',
300 action='edit_ips', conditions={'method': ['GET']})
300 action='edit_ips', conditions={'method': ['GET']})
301 m.connect('edit_user_ips', '/users/{user_id}/edit/ips',
301 m.connect('edit_user_ips', '/users/{user_id}/edit/ips',
302 action='add_ip', conditions={'method': ['PUT']})
302 action='add_ip', conditions={'method': ['PUT']})
303 m.connect('edit_user_ips', '/users/{user_id}/edit/ips',
303 m.connect('edit_user_ips', '/users/{user_id}/edit/ips',
304 action='delete_ip', conditions={'method': ['DELETE']})
304 action='delete_ip', conditions={'method': ['DELETE']})
305
305
306 # ADMIN USER GROUPS REST ROUTES
306 # ADMIN USER GROUPS REST ROUTES
307 with rmap.submapper(path_prefix=ADMIN_PREFIX,
307 with rmap.submapper(path_prefix=ADMIN_PREFIX,
308 controller='admin/user_groups') as m:
308 controller='admin/user_groups') as m:
309 m.connect('users_groups', '/user_groups',
309 m.connect('users_groups', '/user_groups',
310 action='create', conditions={'method': ['POST']})
310 action='create', conditions={'method': ['POST']})
311 m.connect('users_groups', '/user_groups',
311 m.connect('users_groups', '/user_groups',
312 action='index', conditions={'method': ['GET']})
312 action='index', conditions={'method': ['GET']})
313 m.connect('new_users_group', '/user_groups/new',
313 m.connect('new_users_group', '/user_groups/new',
314 action='new', conditions={'method': ['GET']})
314 action='new', conditions={'method': ['GET']})
315 m.connect('update_users_group', '/user_groups/{user_group_id}',
315 m.connect('update_users_group', '/user_groups/{user_group_id}',
316 action='update', conditions={'method': ['PUT']})
316 action='update', conditions={'method': ['PUT']})
317 m.connect('delete_users_group', '/user_groups/{user_group_id}',
317 m.connect('delete_users_group', '/user_groups/{user_group_id}',
318 action='delete', conditions={'method': ['DELETE']})
318 action='delete', conditions={'method': ['DELETE']})
319 m.connect('edit_users_group', '/user_groups/{user_group_id}/edit',
319 m.connect('edit_users_group', '/user_groups/{user_group_id}/edit',
320 action='edit', conditions={'method': ['GET']},
320 action='edit', conditions={'method': ['GET']},
321 function=check_user_group)
321 function=check_user_group)
322
322
323 # EXTRAS USER GROUP ROUTES
323 # EXTRAS USER GROUP ROUTES
324 m.connect('edit_user_group_global_perms',
324 m.connect('edit_user_group_global_perms',
325 '/user_groups/{user_group_id}/edit/global_permissions',
325 '/user_groups/{user_group_id}/edit/global_permissions',
326 action='edit_global_perms', conditions={'method': ['GET']})
326 action='edit_global_perms', conditions={'method': ['GET']})
327 m.connect('edit_user_group_global_perms',
327 m.connect('edit_user_group_global_perms',
328 '/user_groups/{user_group_id}/edit/global_permissions',
328 '/user_groups/{user_group_id}/edit/global_permissions',
329 action='update_global_perms', conditions={'method': ['PUT']})
329 action='update_global_perms', conditions={'method': ['PUT']})
330 m.connect('edit_user_group_perms_summary',
330 m.connect('edit_user_group_perms_summary',
331 '/user_groups/{user_group_id}/edit/permissions_summary',
331 '/user_groups/{user_group_id}/edit/permissions_summary',
332 action='edit_perms_summary', conditions={'method': ['GET']})
332 action='edit_perms_summary', conditions={'method': ['GET']})
333
333
334 m.connect('edit_user_group_perms',
334 m.connect('edit_user_group_perms',
335 '/user_groups/{user_group_id}/edit/permissions',
335 '/user_groups/{user_group_id}/edit/permissions',
336 action='edit_perms', conditions={'method': ['GET']})
336 action='edit_perms', conditions={'method': ['GET']})
337 m.connect('edit_user_group_perms',
337 m.connect('edit_user_group_perms',
338 '/user_groups/{user_group_id}/edit/permissions',
338 '/user_groups/{user_group_id}/edit/permissions',
339 action='update_perms', conditions={'method': ['PUT']})
339 action='update_perms', conditions={'method': ['PUT']})
340
340
341 m.connect('edit_user_group_advanced',
341 m.connect('edit_user_group_advanced',
342 '/user_groups/{user_group_id}/edit/advanced',
342 '/user_groups/{user_group_id}/edit/advanced',
343 action='edit_advanced', conditions={'method': ['GET']})
343 action='edit_advanced', conditions={'method': ['GET']})
344
344
345 m.connect('edit_user_group_advanced_sync',
345 m.connect('edit_user_group_advanced_sync',
346 '/user_groups/{user_group_id}/edit/advanced/sync',
346 '/user_groups/{user_group_id}/edit/advanced/sync',
347 action='edit_advanced_set_synchronization', conditions={'method': ['POST']})
347 action='edit_advanced_set_synchronization', conditions={'method': ['POST']})
348
348
349 m.connect('edit_user_group_members',
349 m.connect('edit_user_group_members',
350 '/user_groups/{user_group_id}/edit/members', jsroute=True,
350 '/user_groups/{user_group_id}/edit/members', jsroute=True,
351 action='user_group_members', conditions={'method': ['GET']})
351 action='user_group_members', conditions={'method': ['GET']})
352
352
353 # ADMIN PERMISSIONS ROUTES
353 # ADMIN PERMISSIONS ROUTES
354 with rmap.submapper(path_prefix=ADMIN_PREFIX,
354 with rmap.submapper(path_prefix=ADMIN_PREFIX,
355 controller='admin/permissions') as m:
355 controller='admin/permissions') as m:
356 m.connect('admin_permissions_application', '/permissions/application',
356 m.connect('admin_permissions_application', '/permissions/application',
357 action='permission_application_update', conditions={'method': ['POST']})
357 action='permission_application_update', conditions={'method': ['POST']})
358 m.connect('admin_permissions_application', '/permissions/application',
358 m.connect('admin_permissions_application', '/permissions/application',
359 action='permission_application', conditions={'method': ['GET']})
359 action='permission_application', conditions={'method': ['GET']})
360
360
361 m.connect('admin_permissions_global', '/permissions/global',
361 m.connect('admin_permissions_global', '/permissions/global',
362 action='permission_global_update', conditions={'method': ['POST']})
362 action='permission_global_update', conditions={'method': ['POST']})
363 m.connect('admin_permissions_global', '/permissions/global',
363 m.connect('admin_permissions_global', '/permissions/global',
364 action='permission_global', conditions={'method': ['GET']})
364 action='permission_global', conditions={'method': ['GET']})
365
365
366 m.connect('admin_permissions_object', '/permissions/object',
366 m.connect('admin_permissions_object', '/permissions/object',
367 action='permission_objects_update', conditions={'method': ['POST']})
367 action='permission_objects_update', conditions={'method': ['POST']})
368 m.connect('admin_permissions_object', '/permissions/object',
368 m.connect('admin_permissions_object', '/permissions/object',
369 action='permission_objects', conditions={'method': ['GET']})
369 action='permission_objects', conditions={'method': ['GET']})
370
370
371 m.connect('admin_permissions_ips', '/permissions/ips',
371 m.connect('admin_permissions_ips', '/permissions/ips',
372 action='permission_ips', conditions={'method': ['POST']})
372 action='permission_ips', conditions={'method': ['POST']})
373 m.connect('admin_permissions_ips', '/permissions/ips',
373 m.connect('admin_permissions_ips', '/permissions/ips',
374 action='permission_ips', conditions={'method': ['GET']})
374 action='permission_ips', conditions={'method': ['GET']})
375
375
376 m.connect('admin_permissions_overview', '/permissions/overview',
376 m.connect('admin_permissions_overview', '/permissions/overview',
377 action='permission_perms', conditions={'method': ['GET']})
377 action='permission_perms', conditions={'method': ['GET']})
378
378
379 # ADMIN DEFAULTS REST ROUTES
379 # ADMIN DEFAULTS REST ROUTES
380 with rmap.submapper(path_prefix=ADMIN_PREFIX,
380 with rmap.submapper(path_prefix=ADMIN_PREFIX,
381 controller='admin/defaults') as m:
381 controller='admin/defaults') as m:
382 m.connect('admin_defaults_repositories', '/defaults/repositories',
382 m.connect('admin_defaults_repositories', '/defaults/repositories',
383 action='update_repository_defaults', conditions={'method': ['POST']})
383 action='update_repository_defaults', conditions={'method': ['POST']})
384 m.connect('admin_defaults_repositories', '/defaults/repositories',
384 m.connect('admin_defaults_repositories', '/defaults/repositories',
385 action='index', conditions={'method': ['GET']})
385 action='index', conditions={'method': ['GET']})
386
386
387 # ADMIN DEBUG STYLE ROUTES
387 # ADMIN DEBUG STYLE ROUTES
388 if str2bool(config.get('debug_style')):
388 if str2bool(config.get('debug_style')):
389 with rmap.submapper(path_prefix=ADMIN_PREFIX + '/debug_style',
389 with rmap.submapper(path_prefix=ADMIN_PREFIX + '/debug_style',
390 controller='debug_style') as m:
390 controller='debug_style') as m:
391 m.connect('debug_style_home', '',
391 m.connect('debug_style_home', '',
392 action='index', conditions={'method': ['GET']})
392 action='index', conditions={'method': ['GET']})
393 m.connect('debug_style_template', '/t/{t_path}',
393 m.connect('debug_style_template', '/t/{t_path}',
394 action='template', conditions={'method': ['GET']})
394 action='template', conditions={'method': ['GET']})
395
395
396 # ADMIN SETTINGS ROUTES
396 # ADMIN SETTINGS ROUTES
397 with rmap.submapper(path_prefix=ADMIN_PREFIX,
397 with rmap.submapper(path_prefix=ADMIN_PREFIX,
398 controller='admin/settings') as m:
398 controller='admin/settings') as m:
399
399
400 # default
400 # default
401 m.connect('admin_settings', '/settings',
401 m.connect('admin_settings', '/settings',
402 action='settings_global_update',
402 action='settings_global_update',
403 conditions={'method': ['POST']})
403 conditions={'method': ['POST']})
404 m.connect('admin_settings', '/settings',
404 m.connect('admin_settings', '/settings',
405 action='settings_global', conditions={'method': ['GET']})
405 action='settings_global', conditions={'method': ['GET']})
406
406
407 m.connect('admin_settings_vcs', '/settings/vcs',
407 m.connect('admin_settings_vcs', '/settings/vcs',
408 action='settings_vcs_update',
408 action='settings_vcs_update',
409 conditions={'method': ['POST']})
409 conditions={'method': ['POST']})
410 m.connect('admin_settings_vcs', '/settings/vcs',
410 m.connect('admin_settings_vcs', '/settings/vcs',
411 action='settings_vcs',
411 action='settings_vcs',
412 conditions={'method': ['GET']})
412 conditions={'method': ['GET']})
413 m.connect('admin_settings_vcs', '/settings/vcs',
413 m.connect('admin_settings_vcs', '/settings/vcs',
414 action='delete_svn_pattern',
414 action='delete_svn_pattern',
415 conditions={'method': ['DELETE']})
415 conditions={'method': ['DELETE']})
416
416
417 m.connect('admin_settings_mapping', '/settings/mapping',
417 m.connect('admin_settings_mapping', '/settings/mapping',
418 action='settings_mapping_update',
418 action='settings_mapping_update',
419 conditions={'method': ['POST']})
419 conditions={'method': ['POST']})
420 m.connect('admin_settings_mapping', '/settings/mapping',
420 m.connect('admin_settings_mapping', '/settings/mapping',
421 action='settings_mapping', conditions={'method': ['GET']})
421 action='settings_mapping', conditions={'method': ['GET']})
422
422
423 m.connect('admin_settings_global', '/settings/global',
423 m.connect('admin_settings_global', '/settings/global',
424 action='settings_global_update',
424 action='settings_global_update',
425 conditions={'method': ['POST']})
425 conditions={'method': ['POST']})
426 m.connect('admin_settings_global', '/settings/global',
426 m.connect('admin_settings_global', '/settings/global',
427 action='settings_global', conditions={'method': ['GET']})
427 action='settings_global', conditions={'method': ['GET']})
428
428
429 m.connect('admin_settings_visual', '/settings/visual',
429 m.connect('admin_settings_visual', '/settings/visual',
430 action='settings_visual_update',
430 action='settings_visual_update',
431 conditions={'method': ['POST']})
431 conditions={'method': ['POST']})
432 m.connect('admin_settings_visual', '/settings/visual',
432 m.connect('admin_settings_visual', '/settings/visual',
433 action='settings_visual', conditions={'method': ['GET']})
433 action='settings_visual', conditions={'method': ['GET']})
434
434
435 m.connect('admin_settings_issuetracker',
435 m.connect('admin_settings_issuetracker',
436 '/settings/issue-tracker', action='settings_issuetracker',
436 '/settings/issue-tracker', action='settings_issuetracker',
437 conditions={'method': ['GET']})
437 conditions={'method': ['GET']})
438 m.connect('admin_settings_issuetracker_save',
438 m.connect('admin_settings_issuetracker_save',
439 '/settings/issue-tracker/save',
439 '/settings/issue-tracker/save',
440 action='settings_issuetracker_save',
440 action='settings_issuetracker_save',
441 conditions={'method': ['POST']})
441 conditions={'method': ['POST']})
442 m.connect('admin_issuetracker_test', '/settings/issue-tracker/test',
442 m.connect('admin_issuetracker_test', '/settings/issue-tracker/test',
443 action='settings_issuetracker_test',
443 action='settings_issuetracker_test',
444 conditions={'method': ['POST']})
444 conditions={'method': ['POST']})
445 m.connect('admin_issuetracker_delete',
445 m.connect('admin_issuetracker_delete',
446 '/settings/issue-tracker/delete',
446 '/settings/issue-tracker/delete',
447 action='settings_issuetracker_delete',
447 action='settings_issuetracker_delete',
448 conditions={'method': ['DELETE']})
448 conditions={'method': ['DELETE']})
449
449
450 m.connect('admin_settings_email', '/settings/email',
450 m.connect('admin_settings_email', '/settings/email',
451 action='settings_email_update',
451 action='settings_email_update',
452 conditions={'method': ['POST']})
452 conditions={'method': ['POST']})
453 m.connect('admin_settings_email', '/settings/email',
453 m.connect('admin_settings_email', '/settings/email',
454 action='settings_email', conditions={'method': ['GET']})
454 action='settings_email', conditions={'method': ['GET']})
455
455
456 m.connect('admin_settings_hooks', '/settings/hooks',
456 m.connect('admin_settings_hooks', '/settings/hooks',
457 action='settings_hooks_update',
457 action='settings_hooks_update',
458 conditions={'method': ['POST', 'DELETE']})
458 conditions={'method': ['POST', 'DELETE']})
459 m.connect('admin_settings_hooks', '/settings/hooks',
459 m.connect('admin_settings_hooks', '/settings/hooks',
460 action='settings_hooks', conditions={'method': ['GET']})
460 action='settings_hooks', conditions={'method': ['GET']})
461
461
462 m.connect('admin_settings_search', '/settings/search',
462 m.connect('admin_settings_search', '/settings/search',
463 action='settings_search', conditions={'method': ['GET']})
463 action='settings_search', conditions={'method': ['GET']})
464
464
465 m.connect('admin_settings_supervisor', '/settings/supervisor',
465 m.connect('admin_settings_supervisor', '/settings/supervisor',
466 action='settings_supervisor', conditions={'method': ['GET']})
466 action='settings_supervisor', conditions={'method': ['GET']})
467 m.connect('admin_settings_supervisor_log', '/settings/supervisor/{procid}/log',
467 m.connect('admin_settings_supervisor_log', '/settings/supervisor/{procid}/log',
468 action='settings_supervisor_log', conditions={'method': ['GET']})
468 action='settings_supervisor_log', conditions={'method': ['GET']})
469
469
470 m.connect('admin_settings_labs', '/settings/labs',
470 m.connect('admin_settings_labs', '/settings/labs',
471 action='settings_labs_update',
471 action='settings_labs_update',
472 conditions={'method': ['POST']})
472 conditions={'method': ['POST']})
473 m.connect('admin_settings_labs', '/settings/labs',
473 m.connect('admin_settings_labs', '/settings/labs',
474 action='settings_labs', conditions={'method': ['GET']})
474 action='settings_labs', conditions={'method': ['GET']})
475
475
476 # ADMIN MY ACCOUNT
476 # ADMIN MY ACCOUNT
477 with rmap.submapper(path_prefix=ADMIN_PREFIX,
477 with rmap.submapper(path_prefix=ADMIN_PREFIX,
478 controller='admin/my_account') as m:
478 controller='admin/my_account') as m:
479
479
480 m.connect('my_account_edit', '/my_account/edit',
480 m.connect('my_account_edit', '/my_account/edit',
481 action='my_account_edit', conditions={'method': ['GET']})
481 action='my_account_edit', conditions={'method': ['GET']})
482 m.connect('my_account', '/my_account/update',
482 m.connect('my_account', '/my_account/update',
483 action='my_account_update', conditions={'method': ['POST']})
483 action='my_account_update', conditions={'method': ['POST']})
484
484
485 # NOTE(marcink): this needs to be kept for password force flag to be
485 # NOTE(marcink): this needs to be kept for password force flag to be
486 # handler, remove after migration to pyramid
486 # handler, remove after migration to pyramid
487 m.connect('my_account_password', '/my_account/password',
487 m.connect('my_account_password', '/my_account/password',
488 action='my_account_password', conditions={'method': ['GET']})
488 action='my_account_password', conditions={'method': ['GET']})
489
489
490 m.connect('my_account_repos', '/my_account/repos',
490 m.connect('my_account_repos', '/my_account/repos',
491 action='my_account_repos', conditions={'method': ['GET']})
491 action='my_account_repos', conditions={'method': ['GET']})
492
492
493 m.connect('my_account_watched', '/my_account/watched',
493 m.connect('my_account_watched', '/my_account/watched',
494 action='my_account_watched', conditions={'method': ['GET']})
494 action='my_account_watched', conditions={'method': ['GET']})
495
495
496 m.connect('my_account_pullrequests', '/my_account/pull_requests',
496 m.connect('my_account_pullrequests', '/my_account/pull_requests',
497 action='my_account_pullrequests', conditions={'method': ['GET']})
497 action='my_account_pullrequests', conditions={'method': ['GET']})
498
498
499 m.connect('my_account_perms', '/my_account/perms',
499 m.connect('my_account_perms', '/my_account/perms',
500 action='my_account_perms', conditions={'method': ['GET']})
500 action='my_account_perms', conditions={'method': ['GET']})
501
501
502 m.connect('my_account_emails', '/my_account/emails',
502 m.connect('my_account_emails', '/my_account/emails',
503 action='my_account_emails', conditions={'method': ['GET']})
503 action='my_account_emails', conditions={'method': ['GET']})
504 m.connect('my_account_emails', '/my_account/emails',
504 m.connect('my_account_emails', '/my_account/emails',
505 action='my_account_emails_add', conditions={'method': ['POST']})
505 action='my_account_emails_add', conditions={'method': ['POST']})
506 m.connect('my_account_emails', '/my_account/emails',
506 m.connect('my_account_emails', '/my_account/emails',
507 action='my_account_emails_delete', conditions={'method': ['DELETE']})
507 action='my_account_emails_delete', conditions={'method': ['DELETE']})
508
508
509 m.connect('my_account_notifications', '/my_account/notifications',
509 m.connect('my_account_notifications', '/my_account/notifications',
510 action='my_notifications',
510 action='my_notifications',
511 conditions={'method': ['GET']})
511 conditions={'method': ['GET']})
512 m.connect('my_account_notifications_toggle_visibility',
512 m.connect('my_account_notifications_toggle_visibility',
513 '/my_account/toggle_visibility',
513 '/my_account/toggle_visibility',
514 action='my_notifications_toggle_visibility',
514 action='my_notifications_toggle_visibility',
515 conditions={'method': ['POST']})
515 conditions={'method': ['POST']})
516 m.connect('my_account_notifications_test_channelstream',
517 '/my_account/test_channelstream',
518 action='my_account_notifications_test_channelstream',
519 conditions={'method': ['POST']})
520
516
521 # NOTIFICATION REST ROUTES
517 # NOTIFICATION REST ROUTES
522 with rmap.submapper(path_prefix=ADMIN_PREFIX,
518 with rmap.submapper(path_prefix=ADMIN_PREFIX,
523 controller='admin/notifications') as m:
519 controller='admin/notifications') as m:
524 m.connect('notifications', '/notifications',
520 m.connect('notifications', '/notifications',
525 action='index', conditions={'method': ['GET']})
521 action='index', conditions={'method': ['GET']})
526 m.connect('notifications_mark_all_read', '/notifications/mark_all_read',
522 m.connect('notifications_mark_all_read', '/notifications/mark_all_read',
527 action='mark_all_read', conditions={'method': ['POST']})
523 action='mark_all_read', conditions={'method': ['POST']})
528 m.connect('/notifications/{notification_id}',
524 m.connect('/notifications/{notification_id}',
529 action='update', conditions={'method': ['PUT']})
525 action='update', conditions={'method': ['PUT']})
530 m.connect('/notifications/{notification_id}',
526 m.connect('/notifications/{notification_id}',
531 action='delete', conditions={'method': ['DELETE']})
527 action='delete', conditions={'method': ['DELETE']})
532 m.connect('notification', '/notifications/{notification_id}',
528 m.connect('notification', '/notifications/{notification_id}',
533 action='show', conditions={'method': ['GET']})
529 action='show', conditions={'method': ['GET']})
534
530
535 # ADMIN GIST
531 # ADMIN GIST
536 with rmap.submapper(path_prefix=ADMIN_PREFIX,
532 with rmap.submapper(path_prefix=ADMIN_PREFIX,
537 controller='admin/gists') as m:
533 controller='admin/gists') as m:
538 m.connect('gists', '/gists',
534 m.connect('gists', '/gists',
539 action='create', conditions={'method': ['POST']})
535 action='create', conditions={'method': ['POST']})
540 m.connect('gists', '/gists', jsroute=True,
536 m.connect('gists', '/gists', jsroute=True,
541 action='index', conditions={'method': ['GET']})
537 action='index', conditions={'method': ['GET']})
542 m.connect('new_gist', '/gists/new', jsroute=True,
538 m.connect('new_gist', '/gists/new', jsroute=True,
543 action='new', conditions={'method': ['GET']})
539 action='new', conditions={'method': ['GET']})
544
540
545 m.connect('/gists/{gist_id}',
541 m.connect('/gists/{gist_id}',
546 action='delete', conditions={'method': ['DELETE']})
542 action='delete', conditions={'method': ['DELETE']})
547 m.connect('edit_gist', '/gists/{gist_id}/edit',
543 m.connect('edit_gist', '/gists/{gist_id}/edit',
548 action='edit_form', conditions={'method': ['GET']})
544 action='edit_form', conditions={'method': ['GET']})
549 m.connect('edit_gist', '/gists/{gist_id}/edit',
545 m.connect('edit_gist', '/gists/{gist_id}/edit',
550 action='edit', conditions={'method': ['POST']})
546 action='edit', conditions={'method': ['POST']})
551 m.connect(
547 m.connect(
552 'edit_gist_check_revision', '/gists/{gist_id}/edit/check_revision',
548 'edit_gist_check_revision', '/gists/{gist_id}/edit/check_revision',
553 action='check_revision', conditions={'method': ['GET']})
549 action='check_revision', conditions={'method': ['GET']})
554
550
555 m.connect('gist', '/gists/{gist_id}',
551 m.connect('gist', '/gists/{gist_id}',
556 action='show', conditions={'method': ['GET']})
552 action='show', conditions={'method': ['GET']})
557 m.connect('gist_rev', '/gists/{gist_id}/{revision}',
553 m.connect('gist_rev', '/gists/{gist_id}/{revision}',
558 revision='tip',
554 revision='tip',
559 action='show', conditions={'method': ['GET']})
555 action='show', conditions={'method': ['GET']})
560 m.connect('formatted_gist', '/gists/{gist_id}/{revision}/{format}',
556 m.connect('formatted_gist', '/gists/{gist_id}/{revision}/{format}',
561 revision='tip',
557 revision='tip',
562 action='show', conditions={'method': ['GET']})
558 action='show', conditions={'method': ['GET']})
563 m.connect('formatted_gist_file', '/gists/{gist_id}/{revision}/{format}/{f_path}',
559 m.connect('formatted_gist_file', '/gists/{gist_id}/{revision}/{format}/{f_path}',
564 revision='tip',
560 revision='tip',
565 action='show', conditions={'method': ['GET']},
561 action='show', conditions={'method': ['GET']},
566 requirements=URL_NAME_REQUIREMENTS)
562 requirements=URL_NAME_REQUIREMENTS)
567
563
568 # ADMIN MAIN PAGES
564 # ADMIN MAIN PAGES
569 with rmap.submapper(path_prefix=ADMIN_PREFIX,
565 with rmap.submapper(path_prefix=ADMIN_PREFIX,
570 controller='admin/admin') as m:
566 controller='admin/admin') as m:
571 m.connect('admin_home', '', action='index')
567 m.connect('admin_home', '', action='index')
572 m.connect('admin_add_repo', '/add_repo/{new_repo:[a-z0-9\. _-]*}',
568 m.connect('admin_add_repo', '/add_repo/{new_repo:[a-z0-9\. _-]*}',
573 action='add_repo')
569 action='add_repo')
574 m.connect(
570 m.connect(
575 'pull_requests_global_0', '/pull_requests/{pull_request_id:[0-9]+}',
571 'pull_requests_global_0', '/pull_requests/{pull_request_id:[0-9]+}',
576 action='pull_requests')
572 action='pull_requests')
577 m.connect(
573 m.connect(
578 'pull_requests_global_1', '/pull-requests/{pull_request_id:[0-9]+}',
574 'pull_requests_global_1', '/pull-requests/{pull_request_id:[0-9]+}',
579 action='pull_requests')
575 action='pull_requests')
580 m.connect(
576 m.connect(
581 'pull_requests_global', '/pull-request/{pull_request_id:[0-9]+}',
577 'pull_requests_global', '/pull-request/{pull_request_id:[0-9]+}',
582 action='pull_requests')
578 action='pull_requests')
583
579
584 # USER JOURNAL
580 # USER JOURNAL
585 rmap.connect('journal', '%s/journal' % (ADMIN_PREFIX,),
581 rmap.connect('journal', '%s/journal' % (ADMIN_PREFIX,),
586 controller='journal', action='index')
582 controller='journal', action='index')
587 rmap.connect('journal_rss', '%s/journal/rss' % (ADMIN_PREFIX,),
583 rmap.connect('journal_rss', '%s/journal/rss' % (ADMIN_PREFIX,),
588 controller='journal', action='journal_rss')
584 controller='journal', action='journal_rss')
589 rmap.connect('journal_atom', '%s/journal/atom' % (ADMIN_PREFIX,),
585 rmap.connect('journal_atom', '%s/journal/atom' % (ADMIN_PREFIX,),
590 controller='journal', action='journal_atom')
586 controller='journal', action='journal_atom')
591
587
592 rmap.connect('public_journal', '%s/public_journal' % (ADMIN_PREFIX,),
588 rmap.connect('public_journal', '%s/public_journal' % (ADMIN_PREFIX,),
593 controller='journal', action='public_journal')
589 controller='journal', action='public_journal')
594
590
595 rmap.connect('public_journal_rss', '%s/public_journal/rss' % (ADMIN_PREFIX,),
591 rmap.connect('public_journal_rss', '%s/public_journal/rss' % (ADMIN_PREFIX,),
596 controller='journal', action='public_journal_rss')
592 controller='journal', action='public_journal_rss')
597
593
598 rmap.connect('public_journal_rss_old', '%s/public_journal_rss' % (ADMIN_PREFIX,),
594 rmap.connect('public_journal_rss_old', '%s/public_journal_rss' % (ADMIN_PREFIX,),
599 controller='journal', action='public_journal_rss')
595 controller='journal', action='public_journal_rss')
600
596
601 rmap.connect('public_journal_atom',
597 rmap.connect('public_journal_atom',
602 '%s/public_journal/atom' % (ADMIN_PREFIX,), controller='journal',
598 '%s/public_journal/atom' % (ADMIN_PREFIX,), controller='journal',
603 action='public_journal_atom')
599 action='public_journal_atom')
604
600
605 rmap.connect('public_journal_atom_old',
601 rmap.connect('public_journal_atom_old',
606 '%s/public_journal_atom' % (ADMIN_PREFIX,), controller='journal',
602 '%s/public_journal_atom' % (ADMIN_PREFIX,), controller='journal',
607 action='public_journal_atom')
603 action='public_journal_atom')
608
604
609 rmap.connect('toggle_following', '%s/toggle_following' % (ADMIN_PREFIX,),
605 rmap.connect('toggle_following', '%s/toggle_following' % (ADMIN_PREFIX,),
610 controller='journal', action='toggle_following', jsroute=True,
606 controller='journal', action='toggle_following', jsroute=True,
611 conditions={'method': ['POST']})
607 conditions={'method': ['POST']})
612
608
613 # FEEDS
609 # FEEDS
614 rmap.connect('rss_feed_home', '/{repo_name}/feed/rss',
610 rmap.connect('rss_feed_home', '/{repo_name}/feed/rss',
615 controller='feed', action='rss',
611 controller='feed', action='rss',
616 conditions={'function': check_repo},
612 conditions={'function': check_repo},
617 requirements=URL_NAME_REQUIREMENTS)
613 requirements=URL_NAME_REQUIREMENTS)
618
614
619 rmap.connect('atom_feed_home', '/{repo_name}/feed/atom',
615 rmap.connect('atom_feed_home', '/{repo_name}/feed/atom',
620 controller='feed', action='atom',
616 controller='feed', action='atom',
621 conditions={'function': check_repo},
617 conditions={'function': check_repo},
622 requirements=URL_NAME_REQUIREMENTS)
618 requirements=URL_NAME_REQUIREMENTS)
623
619
624 #==========================================================================
620 #==========================================================================
625 # REPOSITORY ROUTES
621 # REPOSITORY ROUTES
626 #==========================================================================
622 #==========================================================================
627
623
628 rmap.connect('repo_creating_home', '/{repo_name}/repo_creating',
624 rmap.connect('repo_creating_home', '/{repo_name}/repo_creating',
629 controller='admin/repos', action='repo_creating',
625 controller='admin/repos', action='repo_creating',
630 requirements=URL_NAME_REQUIREMENTS)
626 requirements=URL_NAME_REQUIREMENTS)
631 rmap.connect('repo_check_home', '/{repo_name}/crepo_check',
627 rmap.connect('repo_check_home', '/{repo_name}/crepo_check',
632 controller='admin/repos', action='repo_check',
628 controller='admin/repos', action='repo_check',
633 requirements=URL_NAME_REQUIREMENTS)
629 requirements=URL_NAME_REQUIREMENTS)
634
630
635 rmap.connect('repo_stats', '/{repo_name}/repo_stats/{commit_id}',
631 rmap.connect('repo_stats', '/{repo_name}/repo_stats/{commit_id}',
636 controller='summary', action='repo_stats',
632 controller='summary', action='repo_stats',
637 conditions={'function': check_repo},
633 conditions={'function': check_repo},
638 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
634 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
639
635
640 rmap.connect('repo_refs_data', '/{repo_name}/refs-data',
636 rmap.connect('repo_refs_data', '/{repo_name}/refs-data',
641 controller='summary', action='repo_refs_data',
637 controller='summary', action='repo_refs_data',
642 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
638 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
643 rmap.connect('repo_refs_changelog_data', '/{repo_name}/refs-data-changelog',
639 rmap.connect('repo_refs_changelog_data', '/{repo_name}/refs-data-changelog',
644 controller='summary', action='repo_refs_changelog_data',
640 controller='summary', action='repo_refs_changelog_data',
645 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
641 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
646 rmap.connect('repo_default_reviewers_data', '/{repo_name}/default-reviewers',
642 rmap.connect('repo_default_reviewers_data', '/{repo_name}/default-reviewers',
647 controller='summary', action='repo_default_reviewers_data',
643 controller='summary', action='repo_default_reviewers_data',
648 jsroute=True, requirements=URL_NAME_REQUIREMENTS)
644 jsroute=True, requirements=URL_NAME_REQUIREMENTS)
649
645
650 rmap.connect('changeset_home', '/{repo_name}/changeset/{revision}',
646 rmap.connect('changeset_home', '/{repo_name}/changeset/{revision}',
651 controller='changeset', revision='tip',
647 controller='changeset', revision='tip',
652 conditions={'function': check_repo},
648 conditions={'function': check_repo},
653 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
649 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
654 rmap.connect('changeset_children', '/{repo_name}/changeset_children/{revision}',
650 rmap.connect('changeset_children', '/{repo_name}/changeset_children/{revision}',
655 controller='changeset', revision='tip', action='changeset_children',
651 controller='changeset', revision='tip', action='changeset_children',
656 conditions={'function': check_repo},
652 conditions={'function': check_repo},
657 requirements=URL_NAME_REQUIREMENTS)
653 requirements=URL_NAME_REQUIREMENTS)
658 rmap.connect('changeset_parents', '/{repo_name}/changeset_parents/{revision}',
654 rmap.connect('changeset_parents', '/{repo_name}/changeset_parents/{revision}',
659 controller='changeset', revision='tip', action='changeset_parents',
655 controller='changeset', revision='tip', action='changeset_parents',
660 conditions={'function': check_repo},
656 conditions={'function': check_repo},
661 requirements=URL_NAME_REQUIREMENTS)
657 requirements=URL_NAME_REQUIREMENTS)
662
658
663 # repo edit options
659 # repo edit options
664 rmap.connect('edit_repo_fields', '/{repo_name}/settings/fields',
660 rmap.connect('edit_repo_fields', '/{repo_name}/settings/fields',
665 controller='admin/repos', action='edit_fields',
661 controller='admin/repos', action='edit_fields',
666 conditions={'method': ['GET'], 'function': check_repo},
662 conditions={'method': ['GET'], 'function': check_repo},
667 requirements=URL_NAME_REQUIREMENTS)
663 requirements=URL_NAME_REQUIREMENTS)
668 rmap.connect('create_repo_fields', '/{repo_name}/settings/fields/new',
664 rmap.connect('create_repo_fields', '/{repo_name}/settings/fields/new',
669 controller='admin/repos', action='create_repo_field',
665 controller='admin/repos', action='create_repo_field',
670 conditions={'method': ['PUT'], 'function': check_repo},
666 conditions={'method': ['PUT'], 'function': check_repo},
671 requirements=URL_NAME_REQUIREMENTS)
667 requirements=URL_NAME_REQUIREMENTS)
672 rmap.connect('delete_repo_fields', '/{repo_name}/settings/fields/{field_id}',
668 rmap.connect('delete_repo_fields', '/{repo_name}/settings/fields/{field_id}',
673 controller='admin/repos', action='delete_repo_field',
669 controller='admin/repos', action='delete_repo_field',
674 conditions={'method': ['DELETE'], 'function': check_repo},
670 conditions={'method': ['DELETE'], 'function': check_repo},
675 requirements=URL_NAME_REQUIREMENTS)
671 requirements=URL_NAME_REQUIREMENTS)
676
672
677 rmap.connect('toggle_locking', '/{repo_name}/settings/advanced/locking_toggle',
673 rmap.connect('toggle_locking', '/{repo_name}/settings/advanced/locking_toggle',
678 controller='admin/repos', action='toggle_locking',
674 controller='admin/repos', action='toggle_locking',
679 conditions={'method': ['GET'], 'function': check_repo},
675 conditions={'method': ['GET'], 'function': check_repo},
680 requirements=URL_NAME_REQUIREMENTS)
676 requirements=URL_NAME_REQUIREMENTS)
681
677
682 rmap.connect('edit_repo_remote', '/{repo_name}/settings/remote',
678 rmap.connect('edit_repo_remote', '/{repo_name}/settings/remote',
683 controller='admin/repos', action='edit_remote_form',
679 controller='admin/repos', action='edit_remote_form',
684 conditions={'method': ['GET'], 'function': check_repo},
680 conditions={'method': ['GET'], 'function': check_repo},
685 requirements=URL_NAME_REQUIREMENTS)
681 requirements=URL_NAME_REQUIREMENTS)
686 rmap.connect('edit_repo_remote', '/{repo_name}/settings/remote',
682 rmap.connect('edit_repo_remote', '/{repo_name}/settings/remote',
687 controller='admin/repos', action='edit_remote',
683 controller='admin/repos', action='edit_remote',
688 conditions={'method': ['PUT'], 'function': check_repo},
684 conditions={'method': ['PUT'], 'function': check_repo},
689 requirements=URL_NAME_REQUIREMENTS)
685 requirements=URL_NAME_REQUIREMENTS)
690
686
691 rmap.connect('edit_repo_statistics', '/{repo_name}/settings/statistics',
687 rmap.connect('edit_repo_statistics', '/{repo_name}/settings/statistics',
692 controller='admin/repos', action='edit_statistics_form',
688 controller='admin/repos', action='edit_statistics_form',
693 conditions={'method': ['GET'], 'function': check_repo},
689 conditions={'method': ['GET'], 'function': check_repo},
694 requirements=URL_NAME_REQUIREMENTS)
690 requirements=URL_NAME_REQUIREMENTS)
695 rmap.connect('edit_repo_statistics', '/{repo_name}/settings/statistics',
691 rmap.connect('edit_repo_statistics', '/{repo_name}/settings/statistics',
696 controller='admin/repos', action='edit_statistics',
692 controller='admin/repos', action='edit_statistics',
697 conditions={'method': ['PUT'], 'function': check_repo},
693 conditions={'method': ['PUT'], 'function': check_repo},
698 requirements=URL_NAME_REQUIREMENTS)
694 requirements=URL_NAME_REQUIREMENTS)
699 rmap.connect('repo_settings_issuetracker',
695 rmap.connect('repo_settings_issuetracker',
700 '/{repo_name}/settings/issue-tracker',
696 '/{repo_name}/settings/issue-tracker',
701 controller='admin/repos', action='repo_issuetracker',
697 controller='admin/repos', action='repo_issuetracker',
702 conditions={'method': ['GET'], 'function': check_repo},
698 conditions={'method': ['GET'], 'function': check_repo},
703 requirements=URL_NAME_REQUIREMENTS)
699 requirements=URL_NAME_REQUIREMENTS)
704 rmap.connect('repo_issuetracker_test',
700 rmap.connect('repo_issuetracker_test',
705 '/{repo_name}/settings/issue-tracker/test',
701 '/{repo_name}/settings/issue-tracker/test',
706 controller='admin/repos', action='repo_issuetracker_test',
702 controller='admin/repos', action='repo_issuetracker_test',
707 conditions={'method': ['POST'], 'function': check_repo},
703 conditions={'method': ['POST'], 'function': check_repo},
708 requirements=URL_NAME_REQUIREMENTS)
704 requirements=URL_NAME_REQUIREMENTS)
709 rmap.connect('repo_issuetracker_delete',
705 rmap.connect('repo_issuetracker_delete',
710 '/{repo_name}/settings/issue-tracker/delete',
706 '/{repo_name}/settings/issue-tracker/delete',
711 controller='admin/repos', action='repo_issuetracker_delete',
707 controller='admin/repos', action='repo_issuetracker_delete',
712 conditions={'method': ['DELETE'], 'function': check_repo},
708 conditions={'method': ['DELETE'], 'function': check_repo},
713 requirements=URL_NAME_REQUIREMENTS)
709 requirements=URL_NAME_REQUIREMENTS)
714 rmap.connect('repo_issuetracker_save',
710 rmap.connect('repo_issuetracker_save',
715 '/{repo_name}/settings/issue-tracker/save',
711 '/{repo_name}/settings/issue-tracker/save',
716 controller='admin/repos', action='repo_issuetracker_save',
712 controller='admin/repos', action='repo_issuetracker_save',
717 conditions={'method': ['POST'], 'function': check_repo},
713 conditions={'method': ['POST'], 'function': check_repo},
718 requirements=URL_NAME_REQUIREMENTS)
714 requirements=URL_NAME_REQUIREMENTS)
719 rmap.connect('repo_vcs_settings', '/{repo_name}/settings/vcs',
715 rmap.connect('repo_vcs_settings', '/{repo_name}/settings/vcs',
720 controller='admin/repos', action='repo_settings_vcs_update',
716 controller='admin/repos', action='repo_settings_vcs_update',
721 conditions={'method': ['POST'], 'function': check_repo},
717 conditions={'method': ['POST'], 'function': check_repo},
722 requirements=URL_NAME_REQUIREMENTS)
718 requirements=URL_NAME_REQUIREMENTS)
723 rmap.connect('repo_vcs_settings', '/{repo_name}/settings/vcs',
719 rmap.connect('repo_vcs_settings', '/{repo_name}/settings/vcs',
724 controller='admin/repos', action='repo_settings_vcs',
720 controller='admin/repos', action='repo_settings_vcs',
725 conditions={'method': ['GET'], 'function': check_repo},
721 conditions={'method': ['GET'], 'function': check_repo},
726 requirements=URL_NAME_REQUIREMENTS)
722 requirements=URL_NAME_REQUIREMENTS)
727 rmap.connect('repo_vcs_settings', '/{repo_name}/settings/vcs',
723 rmap.connect('repo_vcs_settings', '/{repo_name}/settings/vcs',
728 controller='admin/repos', action='repo_delete_svn_pattern',
724 controller='admin/repos', action='repo_delete_svn_pattern',
729 conditions={'method': ['DELETE'], 'function': check_repo},
725 conditions={'method': ['DELETE'], 'function': check_repo},
730 requirements=URL_NAME_REQUIREMENTS)
726 requirements=URL_NAME_REQUIREMENTS)
731 rmap.connect('repo_pullrequest_settings', '/{repo_name}/settings/pullrequest',
727 rmap.connect('repo_pullrequest_settings', '/{repo_name}/settings/pullrequest',
732 controller='admin/repos', action='repo_settings_pullrequest',
728 controller='admin/repos', action='repo_settings_pullrequest',
733 conditions={'method': ['GET', 'POST'], 'function': check_repo},
729 conditions={'method': ['GET', 'POST'], 'function': check_repo},
734 requirements=URL_NAME_REQUIREMENTS)
730 requirements=URL_NAME_REQUIREMENTS)
735
731
736 # still working url for backward compat.
732 # still working url for backward compat.
737 rmap.connect('raw_changeset_home_depraced',
733 rmap.connect('raw_changeset_home_depraced',
738 '/{repo_name}/raw-changeset/{revision}',
734 '/{repo_name}/raw-changeset/{revision}',
739 controller='changeset', action='changeset_raw',
735 controller='changeset', action='changeset_raw',
740 revision='tip', conditions={'function': check_repo},
736 revision='tip', conditions={'function': check_repo},
741 requirements=URL_NAME_REQUIREMENTS)
737 requirements=URL_NAME_REQUIREMENTS)
742
738
743 # new URLs
739 # new URLs
744 rmap.connect('changeset_raw_home',
740 rmap.connect('changeset_raw_home',
745 '/{repo_name}/changeset-diff/{revision}',
741 '/{repo_name}/changeset-diff/{revision}',
746 controller='changeset', action='changeset_raw',
742 controller='changeset', action='changeset_raw',
747 revision='tip', conditions={'function': check_repo},
743 revision='tip', conditions={'function': check_repo},
748 requirements=URL_NAME_REQUIREMENTS)
744 requirements=URL_NAME_REQUIREMENTS)
749
745
750 rmap.connect('changeset_patch_home',
746 rmap.connect('changeset_patch_home',
751 '/{repo_name}/changeset-patch/{revision}',
747 '/{repo_name}/changeset-patch/{revision}',
752 controller='changeset', action='changeset_patch',
748 controller='changeset', action='changeset_patch',
753 revision='tip', conditions={'function': check_repo},
749 revision='tip', conditions={'function': check_repo},
754 requirements=URL_NAME_REQUIREMENTS)
750 requirements=URL_NAME_REQUIREMENTS)
755
751
756 rmap.connect('changeset_download_home',
752 rmap.connect('changeset_download_home',
757 '/{repo_name}/changeset-download/{revision}',
753 '/{repo_name}/changeset-download/{revision}',
758 controller='changeset', action='changeset_download',
754 controller='changeset', action='changeset_download',
759 revision='tip', conditions={'function': check_repo},
755 revision='tip', conditions={'function': check_repo},
760 requirements=URL_NAME_REQUIREMENTS)
756 requirements=URL_NAME_REQUIREMENTS)
761
757
762 rmap.connect('changeset_comment',
758 rmap.connect('changeset_comment',
763 '/{repo_name}/changeset/{revision}/comment', jsroute=True,
759 '/{repo_name}/changeset/{revision}/comment', jsroute=True,
764 controller='changeset', revision='tip', action='comment',
760 controller='changeset', revision='tip', action='comment',
765 conditions={'function': check_repo},
761 conditions={'function': check_repo},
766 requirements=URL_NAME_REQUIREMENTS)
762 requirements=URL_NAME_REQUIREMENTS)
767
763
768 rmap.connect('changeset_comment_preview',
764 rmap.connect('changeset_comment_preview',
769 '/{repo_name}/changeset/comment/preview', jsroute=True,
765 '/{repo_name}/changeset/comment/preview', jsroute=True,
770 controller='changeset', action='preview_comment',
766 controller='changeset', action='preview_comment',
771 conditions={'function': check_repo, 'method': ['POST']},
767 conditions={'function': check_repo, 'method': ['POST']},
772 requirements=URL_NAME_REQUIREMENTS)
768 requirements=URL_NAME_REQUIREMENTS)
773
769
774 rmap.connect('changeset_comment_delete',
770 rmap.connect('changeset_comment_delete',
775 '/{repo_name}/changeset/comment/{comment_id}/delete',
771 '/{repo_name}/changeset/comment/{comment_id}/delete',
776 controller='changeset', action='delete_comment',
772 controller='changeset', action='delete_comment',
777 conditions={'function': check_repo, 'method': ['DELETE']},
773 conditions={'function': check_repo, 'method': ['DELETE']},
778 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
774 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
779
775
780 rmap.connect('changeset_info', '/{repo_name}/changeset_info/{revision}',
776 rmap.connect('changeset_info', '/{repo_name}/changeset_info/{revision}',
781 controller='changeset', action='changeset_info',
777 controller='changeset', action='changeset_info',
782 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
778 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
783
779
784 rmap.connect('compare_home',
780 rmap.connect('compare_home',
785 '/{repo_name}/compare',
781 '/{repo_name}/compare',
786 controller='compare', action='index',
782 controller='compare', action='index',
787 conditions={'function': check_repo},
783 conditions={'function': check_repo},
788 requirements=URL_NAME_REQUIREMENTS)
784 requirements=URL_NAME_REQUIREMENTS)
789
785
790 rmap.connect('compare_url',
786 rmap.connect('compare_url',
791 '/{repo_name}/compare/{source_ref_type}@{source_ref:.*?}...{target_ref_type}@{target_ref:.*?}',
787 '/{repo_name}/compare/{source_ref_type}@{source_ref:.*?}...{target_ref_type}@{target_ref:.*?}',
792 controller='compare', action='compare',
788 controller='compare', action='compare',
793 conditions={'function': check_repo},
789 conditions={'function': check_repo},
794 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
790 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
795
791
796 rmap.connect('pullrequest_home',
792 rmap.connect('pullrequest_home',
797 '/{repo_name}/pull-request/new', controller='pullrequests',
793 '/{repo_name}/pull-request/new', controller='pullrequests',
798 action='index', conditions={'function': check_repo,
794 action='index', conditions={'function': check_repo,
799 'method': ['GET']},
795 'method': ['GET']},
800 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
796 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
801
797
802 rmap.connect('pullrequest',
798 rmap.connect('pullrequest',
803 '/{repo_name}/pull-request/new', controller='pullrequests',
799 '/{repo_name}/pull-request/new', controller='pullrequests',
804 action='create', conditions={'function': check_repo,
800 action='create', conditions={'function': check_repo,
805 'method': ['POST']},
801 'method': ['POST']},
806 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
802 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
807
803
808 rmap.connect('pullrequest_repo_refs',
804 rmap.connect('pullrequest_repo_refs',
809 '/{repo_name}/pull-request/refs/{target_repo_name:.*?[^/]}',
805 '/{repo_name}/pull-request/refs/{target_repo_name:.*?[^/]}',
810 controller='pullrequests',
806 controller='pullrequests',
811 action='get_repo_refs',
807 action='get_repo_refs',
812 conditions={'function': check_repo, 'method': ['GET']},
808 conditions={'function': check_repo, 'method': ['GET']},
813 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
809 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
814
810
815 rmap.connect('pullrequest_repo_destinations',
811 rmap.connect('pullrequest_repo_destinations',
816 '/{repo_name}/pull-request/repo-destinations',
812 '/{repo_name}/pull-request/repo-destinations',
817 controller='pullrequests',
813 controller='pullrequests',
818 action='get_repo_destinations',
814 action='get_repo_destinations',
819 conditions={'function': check_repo, 'method': ['GET']},
815 conditions={'function': check_repo, 'method': ['GET']},
820 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
816 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
821
817
822 rmap.connect('pullrequest_show',
818 rmap.connect('pullrequest_show',
823 '/{repo_name}/pull-request/{pull_request_id}',
819 '/{repo_name}/pull-request/{pull_request_id}',
824 controller='pullrequests',
820 controller='pullrequests',
825 action='show', conditions={'function': check_repo,
821 action='show', conditions={'function': check_repo,
826 'method': ['GET']},
822 'method': ['GET']},
827 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
823 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
828
824
829 rmap.connect('pullrequest_update',
825 rmap.connect('pullrequest_update',
830 '/{repo_name}/pull-request/{pull_request_id}',
826 '/{repo_name}/pull-request/{pull_request_id}',
831 controller='pullrequests',
827 controller='pullrequests',
832 action='update', conditions={'function': check_repo,
828 action='update', conditions={'function': check_repo,
833 'method': ['PUT']},
829 'method': ['PUT']},
834 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
830 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
835
831
836 rmap.connect('pullrequest_merge',
832 rmap.connect('pullrequest_merge',
837 '/{repo_name}/pull-request/{pull_request_id}',
833 '/{repo_name}/pull-request/{pull_request_id}',
838 controller='pullrequests',
834 controller='pullrequests',
839 action='merge', conditions={'function': check_repo,
835 action='merge', conditions={'function': check_repo,
840 'method': ['POST']},
836 'method': ['POST']},
841 requirements=URL_NAME_REQUIREMENTS)
837 requirements=URL_NAME_REQUIREMENTS)
842
838
843 rmap.connect('pullrequest_delete',
839 rmap.connect('pullrequest_delete',
844 '/{repo_name}/pull-request/{pull_request_id}',
840 '/{repo_name}/pull-request/{pull_request_id}',
845 controller='pullrequests',
841 controller='pullrequests',
846 action='delete', conditions={'function': check_repo,
842 action='delete', conditions={'function': check_repo,
847 'method': ['DELETE']},
843 'method': ['DELETE']},
848 requirements=URL_NAME_REQUIREMENTS)
844 requirements=URL_NAME_REQUIREMENTS)
849
845
850 rmap.connect('pullrequest_show_all',
846 rmap.connect('pullrequest_show_all',
851 '/{repo_name}/pull-request',
847 '/{repo_name}/pull-request',
852 controller='pullrequests',
848 controller='pullrequests',
853 action='show_all', conditions={'function': check_repo,
849 action='show_all', conditions={'function': check_repo,
854 'method': ['GET']},
850 'method': ['GET']},
855 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
851 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
856
852
857 rmap.connect('pullrequest_comment',
853 rmap.connect('pullrequest_comment',
858 '/{repo_name}/pull-request-comment/{pull_request_id}',
854 '/{repo_name}/pull-request-comment/{pull_request_id}',
859 controller='pullrequests',
855 controller='pullrequests',
860 action='comment', conditions={'function': check_repo,
856 action='comment', conditions={'function': check_repo,
861 'method': ['POST']},
857 'method': ['POST']},
862 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
858 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
863
859
864 rmap.connect('pullrequest_comment_delete',
860 rmap.connect('pullrequest_comment_delete',
865 '/{repo_name}/pull-request-comment/{comment_id}/delete',
861 '/{repo_name}/pull-request-comment/{comment_id}/delete',
866 controller='pullrequests', action='delete_comment',
862 controller='pullrequests', action='delete_comment',
867 conditions={'function': check_repo, 'method': ['DELETE']},
863 conditions={'function': check_repo, 'method': ['DELETE']},
868 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
864 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
869
865
870 rmap.connect('summary_home_explicit', '/{repo_name}/summary',
866 rmap.connect('summary_home_explicit', '/{repo_name}/summary',
871 controller='summary', conditions={'function': check_repo},
867 controller='summary', conditions={'function': check_repo},
872 requirements=URL_NAME_REQUIREMENTS)
868 requirements=URL_NAME_REQUIREMENTS)
873
869
874 rmap.connect('changelog_home', '/{repo_name}/changelog', jsroute=True,
870 rmap.connect('changelog_home', '/{repo_name}/changelog', jsroute=True,
875 controller='changelog', conditions={'function': check_repo},
871 controller='changelog', conditions={'function': check_repo},
876 requirements=URL_NAME_REQUIREMENTS)
872 requirements=URL_NAME_REQUIREMENTS)
877
873
878 rmap.connect('changelog_summary_home', '/{repo_name}/changelog_summary',
874 rmap.connect('changelog_summary_home', '/{repo_name}/changelog_summary',
879 controller='changelog', action='changelog_summary',
875 controller='changelog', action='changelog_summary',
880 conditions={'function': check_repo},
876 conditions={'function': check_repo},
881 requirements=URL_NAME_REQUIREMENTS)
877 requirements=URL_NAME_REQUIREMENTS)
882
878
883 rmap.connect('changelog_file_home',
879 rmap.connect('changelog_file_home',
884 '/{repo_name}/changelog/{revision}/{f_path}',
880 '/{repo_name}/changelog/{revision}/{f_path}',
885 controller='changelog', f_path=None,
881 controller='changelog', f_path=None,
886 conditions={'function': check_repo},
882 conditions={'function': check_repo},
887 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
883 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
888
884
889 rmap.connect('changelog_elements', '/{repo_name}/changelog_details',
885 rmap.connect('changelog_elements', '/{repo_name}/changelog_details',
890 controller='changelog', action='changelog_elements',
886 controller='changelog', action='changelog_elements',
891 conditions={'function': check_repo},
887 conditions={'function': check_repo},
892 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
888 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
893
889
894 rmap.connect('files_home', '/{repo_name}/files/{revision}/{f_path}',
890 rmap.connect('files_home', '/{repo_name}/files/{revision}/{f_path}',
895 controller='files', revision='tip', f_path='',
891 controller='files', revision='tip', f_path='',
896 conditions={'function': check_repo},
892 conditions={'function': check_repo},
897 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
893 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
898
894
899 rmap.connect('files_home_simple_catchrev',
895 rmap.connect('files_home_simple_catchrev',
900 '/{repo_name}/files/{revision}',
896 '/{repo_name}/files/{revision}',
901 controller='files', revision='tip', f_path='',
897 controller='files', revision='tip', f_path='',
902 conditions={'function': check_repo},
898 conditions={'function': check_repo},
903 requirements=URL_NAME_REQUIREMENTS)
899 requirements=URL_NAME_REQUIREMENTS)
904
900
905 rmap.connect('files_home_simple_catchall',
901 rmap.connect('files_home_simple_catchall',
906 '/{repo_name}/files',
902 '/{repo_name}/files',
907 controller='files', revision='tip', f_path='',
903 controller='files', revision='tip', f_path='',
908 conditions={'function': check_repo},
904 conditions={'function': check_repo},
909 requirements=URL_NAME_REQUIREMENTS)
905 requirements=URL_NAME_REQUIREMENTS)
910
906
911 rmap.connect('files_history_home',
907 rmap.connect('files_history_home',
912 '/{repo_name}/history/{revision}/{f_path}',
908 '/{repo_name}/history/{revision}/{f_path}',
913 controller='files', action='history', revision='tip', f_path='',
909 controller='files', action='history', revision='tip', f_path='',
914 conditions={'function': check_repo},
910 conditions={'function': check_repo},
915 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
911 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
916
912
917 rmap.connect('files_authors_home',
913 rmap.connect('files_authors_home',
918 '/{repo_name}/authors/{revision}/{f_path}',
914 '/{repo_name}/authors/{revision}/{f_path}',
919 controller='files', action='authors', revision='tip', f_path='',
915 controller='files', action='authors', revision='tip', f_path='',
920 conditions={'function': check_repo},
916 conditions={'function': check_repo},
921 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
917 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
922
918
923 rmap.connect('files_diff_home', '/{repo_name}/diff/{f_path}',
919 rmap.connect('files_diff_home', '/{repo_name}/diff/{f_path}',
924 controller='files', action='diff', f_path='',
920 controller='files', action='diff', f_path='',
925 conditions={'function': check_repo},
921 conditions={'function': check_repo},
926 requirements=URL_NAME_REQUIREMENTS)
922 requirements=URL_NAME_REQUIREMENTS)
927
923
928 rmap.connect('files_diff_2way_home',
924 rmap.connect('files_diff_2way_home',
929 '/{repo_name}/diff-2way/{f_path}',
925 '/{repo_name}/diff-2way/{f_path}',
930 controller='files', action='diff_2way', f_path='',
926 controller='files', action='diff_2way', f_path='',
931 conditions={'function': check_repo},
927 conditions={'function': check_repo},
932 requirements=URL_NAME_REQUIREMENTS)
928 requirements=URL_NAME_REQUIREMENTS)
933
929
934 rmap.connect('files_rawfile_home',
930 rmap.connect('files_rawfile_home',
935 '/{repo_name}/rawfile/{revision}/{f_path}',
931 '/{repo_name}/rawfile/{revision}/{f_path}',
936 controller='files', action='rawfile', revision='tip',
932 controller='files', action='rawfile', revision='tip',
937 f_path='', conditions={'function': check_repo},
933 f_path='', conditions={'function': check_repo},
938 requirements=URL_NAME_REQUIREMENTS)
934 requirements=URL_NAME_REQUIREMENTS)
939
935
940 rmap.connect('files_raw_home',
936 rmap.connect('files_raw_home',
941 '/{repo_name}/raw/{revision}/{f_path}',
937 '/{repo_name}/raw/{revision}/{f_path}',
942 controller='files', action='raw', revision='tip', f_path='',
938 controller='files', action='raw', revision='tip', f_path='',
943 conditions={'function': check_repo},
939 conditions={'function': check_repo},
944 requirements=URL_NAME_REQUIREMENTS)
940 requirements=URL_NAME_REQUIREMENTS)
945
941
946 rmap.connect('files_render_home',
942 rmap.connect('files_render_home',
947 '/{repo_name}/render/{revision}/{f_path}',
943 '/{repo_name}/render/{revision}/{f_path}',
948 controller='files', action='index', revision='tip', f_path='',
944 controller='files', action='index', revision='tip', f_path='',
949 rendered=True, conditions={'function': check_repo},
945 rendered=True, conditions={'function': check_repo},
950 requirements=URL_NAME_REQUIREMENTS)
946 requirements=URL_NAME_REQUIREMENTS)
951
947
952 rmap.connect('files_annotate_home',
948 rmap.connect('files_annotate_home',
953 '/{repo_name}/annotate/{revision}/{f_path}',
949 '/{repo_name}/annotate/{revision}/{f_path}',
954 controller='files', action='index', revision='tip',
950 controller='files', action='index', revision='tip',
955 f_path='', annotate=True, conditions={'function': check_repo},
951 f_path='', annotate=True, conditions={'function': check_repo},
956 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
952 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
957
953
958 rmap.connect('files_annotate_previous',
954 rmap.connect('files_annotate_previous',
959 '/{repo_name}/annotate-previous/{revision}/{f_path}',
955 '/{repo_name}/annotate-previous/{revision}/{f_path}',
960 controller='files', action='annotate_previous', revision='tip',
956 controller='files', action='annotate_previous', revision='tip',
961 f_path='', annotate=True, conditions={'function': check_repo},
957 f_path='', annotate=True, conditions={'function': check_repo},
962 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
958 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
963
959
964 rmap.connect('files_edit',
960 rmap.connect('files_edit',
965 '/{repo_name}/edit/{revision}/{f_path}',
961 '/{repo_name}/edit/{revision}/{f_path}',
966 controller='files', action='edit', revision='tip',
962 controller='files', action='edit', revision='tip',
967 f_path='',
963 f_path='',
968 conditions={'function': check_repo, 'method': ['POST']},
964 conditions={'function': check_repo, 'method': ['POST']},
969 requirements=URL_NAME_REQUIREMENTS)
965 requirements=URL_NAME_REQUIREMENTS)
970
966
971 rmap.connect('files_edit_home',
967 rmap.connect('files_edit_home',
972 '/{repo_name}/edit/{revision}/{f_path}',
968 '/{repo_name}/edit/{revision}/{f_path}',
973 controller='files', action='edit_home', revision='tip',
969 controller='files', action='edit_home', revision='tip',
974 f_path='', conditions={'function': check_repo},
970 f_path='', conditions={'function': check_repo},
975 requirements=URL_NAME_REQUIREMENTS)
971 requirements=URL_NAME_REQUIREMENTS)
976
972
977 rmap.connect('files_add',
973 rmap.connect('files_add',
978 '/{repo_name}/add/{revision}/{f_path}',
974 '/{repo_name}/add/{revision}/{f_path}',
979 controller='files', action='add', revision='tip',
975 controller='files', action='add', revision='tip',
980 f_path='',
976 f_path='',
981 conditions={'function': check_repo, 'method': ['POST']},
977 conditions={'function': check_repo, 'method': ['POST']},
982 requirements=URL_NAME_REQUIREMENTS)
978 requirements=URL_NAME_REQUIREMENTS)
983
979
984 rmap.connect('files_add_home',
980 rmap.connect('files_add_home',
985 '/{repo_name}/add/{revision}/{f_path}',
981 '/{repo_name}/add/{revision}/{f_path}',
986 controller='files', action='add_home', revision='tip',
982 controller='files', action='add_home', revision='tip',
987 f_path='', conditions={'function': check_repo},
983 f_path='', conditions={'function': check_repo},
988 requirements=URL_NAME_REQUIREMENTS)
984 requirements=URL_NAME_REQUIREMENTS)
989
985
990 rmap.connect('files_delete',
986 rmap.connect('files_delete',
991 '/{repo_name}/delete/{revision}/{f_path}',
987 '/{repo_name}/delete/{revision}/{f_path}',
992 controller='files', action='delete', revision='tip',
988 controller='files', action='delete', revision='tip',
993 f_path='',
989 f_path='',
994 conditions={'function': check_repo, 'method': ['POST']},
990 conditions={'function': check_repo, 'method': ['POST']},
995 requirements=URL_NAME_REQUIREMENTS)
991 requirements=URL_NAME_REQUIREMENTS)
996
992
997 rmap.connect('files_delete_home',
993 rmap.connect('files_delete_home',
998 '/{repo_name}/delete/{revision}/{f_path}',
994 '/{repo_name}/delete/{revision}/{f_path}',
999 controller='files', action='delete_home', revision='tip',
995 controller='files', action='delete_home', revision='tip',
1000 f_path='', conditions={'function': check_repo},
996 f_path='', conditions={'function': check_repo},
1001 requirements=URL_NAME_REQUIREMENTS)
997 requirements=URL_NAME_REQUIREMENTS)
1002
998
1003 rmap.connect('files_archive_home', '/{repo_name}/archive/{fname}',
999 rmap.connect('files_archive_home', '/{repo_name}/archive/{fname}',
1004 controller='files', action='archivefile',
1000 controller='files', action='archivefile',
1005 conditions={'function': check_repo},
1001 conditions={'function': check_repo},
1006 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
1002 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
1007
1003
1008 rmap.connect('files_nodelist_home',
1004 rmap.connect('files_nodelist_home',
1009 '/{repo_name}/nodelist/{revision}/{f_path}',
1005 '/{repo_name}/nodelist/{revision}/{f_path}',
1010 controller='files', action='nodelist',
1006 controller='files', action='nodelist',
1011 conditions={'function': check_repo},
1007 conditions={'function': check_repo},
1012 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
1008 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
1013
1009
1014 rmap.connect('files_nodetree_full',
1010 rmap.connect('files_nodetree_full',
1015 '/{repo_name}/nodetree_full/{commit_id}/{f_path}',
1011 '/{repo_name}/nodetree_full/{commit_id}/{f_path}',
1016 controller='files', action='nodetree_full',
1012 controller='files', action='nodetree_full',
1017 conditions={'function': check_repo},
1013 conditions={'function': check_repo},
1018 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
1014 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
1019
1015
1020 rmap.connect('repo_fork_create_home', '/{repo_name}/fork',
1016 rmap.connect('repo_fork_create_home', '/{repo_name}/fork',
1021 controller='forks', action='fork_create',
1017 controller='forks', action='fork_create',
1022 conditions={'function': check_repo, 'method': ['POST']},
1018 conditions={'function': check_repo, 'method': ['POST']},
1023 requirements=URL_NAME_REQUIREMENTS)
1019 requirements=URL_NAME_REQUIREMENTS)
1024
1020
1025 rmap.connect('repo_fork_home', '/{repo_name}/fork',
1021 rmap.connect('repo_fork_home', '/{repo_name}/fork',
1026 controller='forks', action='fork',
1022 controller='forks', action='fork',
1027 conditions={'function': check_repo},
1023 conditions={'function': check_repo},
1028 requirements=URL_NAME_REQUIREMENTS)
1024 requirements=URL_NAME_REQUIREMENTS)
1029
1025
1030 rmap.connect('repo_forks_home', '/{repo_name}/forks',
1026 rmap.connect('repo_forks_home', '/{repo_name}/forks',
1031 controller='forks', action='forks',
1027 controller='forks', action='forks',
1032 conditions={'function': check_repo},
1028 conditions={'function': check_repo},
1033 requirements=URL_NAME_REQUIREMENTS)
1029 requirements=URL_NAME_REQUIREMENTS)
1034
1030
1035 # must be here for proper group/repo catching pattern
1031 # must be here for proper group/repo catching pattern
1036 _connect_with_slash(
1032 _connect_with_slash(
1037 rmap, 'repo_group_home', '/{group_name}',
1033 rmap, 'repo_group_home', '/{group_name}',
1038 controller='home', action='index_repo_group',
1034 controller='home', action='index_repo_group',
1039 conditions={'function': check_group},
1035 conditions={'function': check_group},
1040 requirements=URL_NAME_REQUIREMENTS)
1036 requirements=URL_NAME_REQUIREMENTS)
1041
1037
1042 # catch all, at the end
1038 # catch all, at the end
1043 _connect_with_slash(
1039 _connect_with_slash(
1044 rmap, 'summary_home', '/{repo_name}', jsroute=True,
1040 rmap, 'summary_home', '/{repo_name}', jsroute=True,
1045 controller='summary', action='index',
1041 controller='summary', action='index',
1046 conditions={'function': check_repo},
1042 conditions={'function': check_repo},
1047 requirements=URL_NAME_REQUIREMENTS)
1043 requirements=URL_NAME_REQUIREMENTS)
1048
1044
1049 return rmap
1045 return rmap
1050
1046
1051
1047
1052 def _connect_with_slash(mapper, name, path, *args, **kwargs):
1048 def _connect_with_slash(mapper, name, path, *args, **kwargs):
1053 """
1049 """
1054 Connect a route with an optional trailing slash in `path`.
1050 Connect a route with an optional trailing slash in `path`.
1055 """
1051 """
1056 mapper.connect(name + '_slash', path + '/', *args, **kwargs)
1052 mapper.connect(name + '_slash', path + '/', *args, **kwargs)
1057 mapper.connect(name, path, *args, **kwargs)
1053 mapper.connect(name, path, *args, **kwargs)
@@ -1,364 +1,330 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2013-2017 RhodeCode GmbH
3 # Copyright (C) 2013-2017 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
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
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
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/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21
21
22 """
22 """
23 my account controller for RhodeCode admin
23 my account controller for RhodeCode admin
24 """
24 """
25
25
26 import logging
26 import logging
27 import datetime
28
27
29 import formencode
28 import formencode
30 from formencode import htmlfill
29 from formencode import htmlfill
31 from pyramid.threadlocal import get_current_registry
32 from pyramid.httpexceptions import HTTPFound
30 from pyramid.httpexceptions import HTTPFound
33
31
34 from pylons import request, tmpl_context as c, url
32 from pylons import request, tmpl_context as c, url
35 from pylons.controllers.util import redirect
33 from pylons.controllers.util import redirect
36 from pylons.i18n.translation import _
34 from pylons.i18n.translation import _
37 from sqlalchemy.orm import joinedload
35 from sqlalchemy.orm import joinedload
38
36
39 from rhodecode.lib import helpers as h
37 from rhodecode.lib import helpers as h
40 from rhodecode.lib import auth
38 from rhodecode.lib import auth
41 from rhodecode.lib.auth import (
39 from rhodecode.lib.auth import (
42 LoginRequired, NotAnonymous, AuthUser)
40 LoginRequired, NotAnonymous, AuthUser)
43 from rhodecode.lib.base import BaseController, render
41 from rhodecode.lib.base import BaseController, render
44 from rhodecode.lib.utils import jsonify
42 from rhodecode.lib.utils import jsonify
45 from rhodecode.lib.utils2 import safe_int, str2bool
43 from rhodecode.lib.utils2 import safe_int, str2bool
46 from rhodecode.lib.ext_json import json
44 from rhodecode.lib.ext_json import json
47 from rhodecode.lib.channelstream import channelstream_request, \
48 ChannelstreamException
49
45
50 from rhodecode.model.db import (
46 from rhodecode.model.db import (
51 Repository, PullRequest, UserEmailMap, User, UserFollowing)
47 Repository, PullRequest, UserEmailMap, User, UserFollowing)
52 from rhodecode.model.forms import UserForm
48 from rhodecode.model.forms import UserForm
53 from rhodecode.model.scm import RepoList
49 from rhodecode.model.scm import RepoList
54 from rhodecode.model.user import UserModel
50 from rhodecode.model.user import UserModel
55 from rhodecode.model.repo import RepoModel
51 from rhodecode.model.repo import RepoModel
56 from rhodecode.model.meta import Session
52 from rhodecode.model.meta import Session
57 from rhodecode.model.pull_request import PullRequestModel
53 from rhodecode.model.pull_request import PullRequestModel
58 from rhodecode.model.comment import CommentsModel
54 from rhodecode.model.comment import CommentsModel
59
55
60 log = logging.getLogger(__name__)
56 log = logging.getLogger(__name__)
61
57
62
58
63 class MyAccountController(BaseController):
59 class MyAccountController(BaseController):
64 """REST Controller styled on the Atom Publishing Protocol"""
60 """REST Controller styled on the Atom Publishing Protocol"""
65 # To properly map this controller, ensure your config/routing.py
61 # To properly map this controller, ensure your config/routing.py
66 # file has a resource setup:
62 # file has a resource setup:
67 # map.resource('setting', 'settings', controller='admin/settings',
63 # map.resource('setting', 'settings', controller='admin/settings',
68 # path_prefix='/admin', name_prefix='admin_')
64 # path_prefix='/admin', name_prefix='admin_')
69
65
70 @LoginRequired()
66 @LoginRequired()
71 @NotAnonymous()
67 @NotAnonymous()
72 def __before__(self):
68 def __before__(self):
73 super(MyAccountController, self).__before__()
69 super(MyAccountController, self).__before__()
74
70
75 def __load_data(self):
71 def __load_data(self):
76 c.user = User.get(c.rhodecode_user.user_id)
72 c.user = User.get(c.rhodecode_user.user_id)
77 if c.user.username == User.DEFAULT_USER:
73 if c.user.username == User.DEFAULT_USER:
78 h.flash(_("You can't edit this user since it's"
74 h.flash(_("You can't edit this user since it's"
79 " crucial for entire application"), category='warning')
75 " crucial for entire application"), category='warning')
80 return redirect(h.route_path('users'))
76 return redirect(h.route_path('users'))
81
77
82 c.auth_user = AuthUser(
78 c.auth_user = AuthUser(
83 user_id=c.rhodecode_user.user_id, ip_addr=self.ip_addr)
79 user_id=c.rhodecode_user.user_id, ip_addr=self.ip_addr)
84
80
85 def _load_my_repos_data(self, watched=False):
81 def _load_my_repos_data(self, watched=False):
86 if watched:
82 if watched:
87 admin = False
83 admin = False
88 follows_repos = Session().query(UserFollowing)\
84 follows_repos = Session().query(UserFollowing)\
89 .filter(UserFollowing.user_id == c.rhodecode_user.user_id)\
85 .filter(UserFollowing.user_id == c.rhodecode_user.user_id)\
90 .options(joinedload(UserFollowing.follows_repository))\
86 .options(joinedload(UserFollowing.follows_repository))\
91 .all()
87 .all()
92 repo_list = [x.follows_repository for x in follows_repos]
88 repo_list = [x.follows_repository for x in follows_repos]
93 else:
89 else:
94 admin = True
90 admin = True
95 repo_list = Repository.get_all_repos(
91 repo_list = Repository.get_all_repos(
96 user_id=c.rhodecode_user.user_id)
92 user_id=c.rhodecode_user.user_id)
97 repo_list = RepoList(repo_list, perm_set=[
93 repo_list = RepoList(repo_list, perm_set=[
98 'repository.read', 'repository.write', 'repository.admin'])
94 'repository.read', 'repository.write', 'repository.admin'])
99
95
100 repos_data = RepoModel().get_repos_as_dict(
96 repos_data = RepoModel().get_repos_as_dict(
101 repo_list=repo_list, admin=admin)
97 repo_list=repo_list, admin=admin)
102 # json used to render the grid
98 # json used to render the grid
103 return json.dumps(repos_data)
99 return json.dumps(repos_data)
104
100
105 @auth.CSRFRequired()
101 @auth.CSRFRequired()
106 def my_account_update(self):
102 def my_account_update(self):
107 """
103 """
108 POST /_admin/my_account Updates info of my account
104 POST /_admin/my_account Updates info of my account
109 """
105 """
110 # url('my_account')
106 # url('my_account')
111 c.active = 'profile_edit'
107 c.active = 'profile_edit'
112 self.__load_data()
108 self.__load_data()
113 c.perm_user = c.auth_user
109 c.perm_user = c.auth_user
114 c.extern_type = c.user.extern_type
110 c.extern_type = c.user.extern_type
115 c.extern_name = c.user.extern_name
111 c.extern_name = c.user.extern_name
116
112
117 defaults = c.user.get_dict()
113 defaults = c.user.get_dict()
118 update = False
114 update = False
119 _form = UserForm(edit=True,
115 _form = UserForm(edit=True,
120 old_data={'user_id': c.rhodecode_user.user_id,
116 old_data={'user_id': c.rhodecode_user.user_id,
121 'email': c.rhodecode_user.email})()
117 'email': c.rhodecode_user.email})()
122 form_result = {}
118 form_result = {}
123 try:
119 try:
124 post_data = dict(request.POST)
120 post_data = dict(request.POST)
125 post_data['new_password'] = ''
121 post_data['new_password'] = ''
126 post_data['password_confirmation'] = ''
122 post_data['password_confirmation'] = ''
127 form_result = _form.to_python(post_data)
123 form_result = _form.to_python(post_data)
128 # skip updating those attrs for my account
124 # skip updating those attrs for my account
129 skip_attrs = ['admin', 'active', 'extern_type', 'extern_name',
125 skip_attrs = ['admin', 'active', 'extern_type', 'extern_name',
130 'new_password', 'password_confirmation']
126 'new_password', 'password_confirmation']
131 # TODO: plugin should define if username can be updated
127 # TODO: plugin should define if username can be updated
132 if c.extern_type != "rhodecode":
128 if c.extern_type != "rhodecode":
133 # forbid updating username for external accounts
129 # forbid updating username for external accounts
134 skip_attrs.append('username')
130 skip_attrs.append('username')
135
131
136 UserModel().update_user(
132 UserModel().update_user(
137 c.rhodecode_user.user_id, skip_attrs=skip_attrs, **form_result)
133 c.rhodecode_user.user_id, skip_attrs=skip_attrs, **form_result)
138 h.flash(_('Your account was updated successfully'),
134 h.flash(_('Your account was updated successfully'),
139 category='success')
135 category='success')
140 Session().commit()
136 Session().commit()
141 update = True
137 update = True
142
138
143 except formencode.Invalid as errors:
139 except formencode.Invalid as errors:
144 return htmlfill.render(
140 return htmlfill.render(
145 render('admin/my_account/my_account.mako'),
141 render('admin/my_account/my_account.mako'),
146 defaults=errors.value,
142 defaults=errors.value,
147 errors=errors.error_dict or {},
143 errors=errors.error_dict or {},
148 prefix_error=False,
144 prefix_error=False,
149 encoding="UTF-8",
145 encoding="UTF-8",
150 force_defaults=False)
146 force_defaults=False)
151 except Exception:
147 except Exception:
152 log.exception("Exception updating user")
148 log.exception("Exception updating user")
153 h.flash(_('Error occurred during update of user %s')
149 h.flash(_('Error occurred during update of user %s')
154 % form_result.get('username'), category='error')
150 % form_result.get('username'), category='error')
155
151
156 if update:
152 if update:
157 raise HTTPFound(h.route_path('my_account_profile'))
153 raise HTTPFound(h.route_path('my_account_profile'))
158
154
159 return htmlfill.render(
155 return htmlfill.render(
160 render('admin/my_account/my_account.mako'),
156 render('admin/my_account/my_account.mako'),
161 defaults=defaults,
157 defaults=defaults,
162 encoding="UTF-8",
158 encoding="UTF-8",
163 force_defaults=False
159 force_defaults=False
164 )
160 )
165
161
166 def my_account_edit(self):
162 def my_account_edit(self):
167 """
163 """
168 GET /_admin/my_account/edit Displays edit form of my account
164 GET /_admin/my_account/edit Displays edit form of my account
169 """
165 """
170 c.active = 'profile_edit'
166 c.active = 'profile_edit'
171 self.__load_data()
167 self.__load_data()
172 c.perm_user = c.auth_user
168 c.perm_user = c.auth_user
173 c.extern_type = c.user.extern_type
169 c.extern_type = c.user.extern_type
174 c.extern_name = c.user.extern_name
170 c.extern_name = c.user.extern_name
175
171
176 defaults = c.user.get_dict()
172 defaults = c.user.get_dict()
177 return htmlfill.render(
173 return htmlfill.render(
178 render('admin/my_account/my_account.mako'),
174 render('admin/my_account/my_account.mako'),
179 defaults=defaults,
175 defaults=defaults,
180 encoding="UTF-8",
176 encoding="UTF-8",
181 force_defaults=False
177 force_defaults=False
182 )
178 )
183
179
184 def my_account_repos(self):
180 def my_account_repos(self):
185 c.active = 'repos'
181 c.active = 'repos'
186 self.__load_data()
182 self.__load_data()
187
183
188 # json used to render the grid
184 # json used to render the grid
189 c.data = self._load_my_repos_data()
185 c.data = self._load_my_repos_data()
190 return render('admin/my_account/my_account.mako')
186 return render('admin/my_account/my_account.mako')
191
187
192 def my_account_watched(self):
188 def my_account_watched(self):
193 c.active = 'watched'
189 c.active = 'watched'
194 self.__load_data()
190 self.__load_data()
195
191
196 # json used to render the grid
192 # json used to render the grid
197 c.data = self._load_my_repos_data(watched=True)
193 c.data = self._load_my_repos_data(watched=True)
198 return render('admin/my_account/my_account.mako')
194 return render('admin/my_account/my_account.mako')
199
195
200 def my_account_perms(self):
196 def my_account_perms(self):
201 c.active = 'perms'
197 c.active = 'perms'
202 self.__load_data()
198 self.__load_data()
203 c.perm_user = c.auth_user
199 c.perm_user = c.auth_user
204
200
205 return render('admin/my_account/my_account.mako')
201 return render('admin/my_account/my_account.mako')
206
202
207 def my_account_emails(self):
203 def my_account_emails(self):
208 c.active = 'emails'
204 c.active = 'emails'
209 self.__load_data()
205 self.__load_data()
210
206
211 c.user_email_map = UserEmailMap.query()\
207 c.user_email_map = UserEmailMap.query()\
212 .filter(UserEmailMap.user == c.user).all()
208 .filter(UserEmailMap.user == c.user).all()
213 return render('admin/my_account/my_account.mako')
209 return render('admin/my_account/my_account.mako')
214
210
215 @auth.CSRFRequired()
211 @auth.CSRFRequired()
216 def my_account_emails_add(self):
212 def my_account_emails_add(self):
217 email = request.POST.get('new_email')
213 email = request.POST.get('new_email')
218
214
219 try:
215 try:
220 UserModel().add_extra_email(c.rhodecode_user.user_id, email)
216 UserModel().add_extra_email(c.rhodecode_user.user_id, email)
221 Session().commit()
217 Session().commit()
222 h.flash(_("Added new email address `%s` for user account") % email,
218 h.flash(_("Added new email address `%s` for user account") % email,
223 category='success')
219 category='success')
224 except formencode.Invalid as error:
220 except formencode.Invalid as error:
225 msg = error.error_dict['email']
221 msg = error.error_dict['email']
226 h.flash(msg, category='error')
222 h.flash(msg, category='error')
227 except Exception:
223 except Exception:
228 log.exception("Exception in my_account_emails")
224 log.exception("Exception in my_account_emails")
229 h.flash(_('An error occurred during email saving'),
225 h.flash(_('An error occurred during email saving'),
230 category='error')
226 category='error')
231 return redirect(url('my_account_emails'))
227 return redirect(url('my_account_emails'))
232
228
233 @auth.CSRFRequired()
229 @auth.CSRFRequired()
234 def my_account_emails_delete(self):
230 def my_account_emails_delete(self):
235 email_id = request.POST.get('del_email_id')
231 email_id = request.POST.get('del_email_id')
236 user_model = UserModel()
232 user_model = UserModel()
237 user_model.delete_extra_email(c.rhodecode_user.user_id, email_id)
233 user_model.delete_extra_email(c.rhodecode_user.user_id, email_id)
238 Session().commit()
234 Session().commit()
239 h.flash(_("Removed email address from user account"),
235 h.flash(_("Removed email address from user account"),
240 category='success')
236 category='success')
241 return redirect(url('my_account_emails'))
237 return redirect(url('my_account_emails'))
242
238
243 def _extract_ordering(self, request):
239 def _extract_ordering(self, request):
244 column_index = safe_int(request.GET.get('order[0][column]'))
240 column_index = safe_int(request.GET.get('order[0][column]'))
245 order_dir = request.GET.get('order[0][dir]', 'desc')
241 order_dir = request.GET.get('order[0][dir]', 'desc')
246 order_by = request.GET.get(
242 order_by = request.GET.get(
247 'columns[%s][data][sort]' % column_index, 'name_raw')
243 'columns[%s][data][sort]' % column_index, 'name_raw')
248 return order_by, order_dir
244 return order_by, order_dir
249
245
250 def _get_pull_requests_list(self, statuses):
246 def _get_pull_requests_list(self, statuses):
251 start = safe_int(request.GET.get('start'), 0)
247 start = safe_int(request.GET.get('start'), 0)
252 length = safe_int(request.GET.get('length'), c.visual.dashboard_items)
248 length = safe_int(request.GET.get('length'), c.visual.dashboard_items)
253 order_by, order_dir = self._extract_ordering(request)
249 order_by, order_dir = self._extract_ordering(request)
254
250
255 pull_requests = PullRequestModel().get_im_participating_in(
251 pull_requests = PullRequestModel().get_im_participating_in(
256 user_id=c.rhodecode_user.user_id,
252 user_id=c.rhodecode_user.user_id,
257 statuses=statuses,
253 statuses=statuses,
258 offset=start, length=length, order_by=order_by,
254 offset=start, length=length, order_by=order_by,
259 order_dir=order_dir)
255 order_dir=order_dir)
260
256
261 pull_requests_total_count = PullRequestModel().count_im_participating_in(
257 pull_requests_total_count = PullRequestModel().count_im_participating_in(
262 user_id=c.rhodecode_user.user_id, statuses=statuses)
258 user_id=c.rhodecode_user.user_id, statuses=statuses)
263
259
264 from rhodecode.lib.utils import PartialRenderer
260 from rhodecode.lib.utils import PartialRenderer
265 _render = PartialRenderer('data_table/_dt_elements.mako')
261 _render = PartialRenderer('data_table/_dt_elements.mako')
266 data = []
262 data = []
267 for pr in pull_requests:
263 for pr in pull_requests:
268 repo_id = pr.target_repo_id
264 repo_id = pr.target_repo_id
269 comments = CommentsModel().get_all_comments(
265 comments = CommentsModel().get_all_comments(
270 repo_id, pull_request=pr)
266 repo_id, pull_request=pr)
271 owned = pr.user_id == c.rhodecode_user.user_id
267 owned = pr.user_id == c.rhodecode_user.user_id
272 status = pr.calculated_review_status()
268 status = pr.calculated_review_status()
273
269
274 data.append({
270 data.append({
275 'target_repo': _render('pullrequest_target_repo',
271 'target_repo': _render('pullrequest_target_repo',
276 pr.target_repo.repo_name),
272 pr.target_repo.repo_name),
277 'name': _render('pullrequest_name',
273 'name': _render('pullrequest_name',
278 pr.pull_request_id, pr.target_repo.repo_name,
274 pr.pull_request_id, pr.target_repo.repo_name,
279 short=True),
275 short=True),
280 'name_raw': pr.pull_request_id,
276 'name_raw': pr.pull_request_id,
281 'status': _render('pullrequest_status', status),
277 'status': _render('pullrequest_status', status),
282 'title': _render(
278 'title': _render(
283 'pullrequest_title', pr.title, pr.description),
279 'pullrequest_title', pr.title, pr.description),
284 'description': h.escape(pr.description),
280 'description': h.escape(pr.description),
285 'updated_on': _render('pullrequest_updated_on',
281 'updated_on': _render('pullrequest_updated_on',
286 h.datetime_to_time(pr.updated_on)),
282 h.datetime_to_time(pr.updated_on)),
287 'updated_on_raw': h.datetime_to_time(pr.updated_on),
283 'updated_on_raw': h.datetime_to_time(pr.updated_on),
288 'created_on': _render('pullrequest_updated_on',
284 'created_on': _render('pullrequest_updated_on',
289 h.datetime_to_time(pr.created_on)),
285 h.datetime_to_time(pr.created_on)),
290 'created_on_raw': h.datetime_to_time(pr.created_on),
286 'created_on_raw': h.datetime_to_time(pr.created_on),
291 'author': _render('pullrequest_author',
287 'author': _render('pullrequest_author',
292 pr.author.full_contact, ),
288 pr.author.full_contact, ),
293 'author_raw': pr.author.full_name,
289 'author_raw': pr.author.full_name,
294 'comments': _render('pullrequest_comments', len(comments)),
290 'comments': _render('pullrequest_comments', len(comments)),
295 'comments_raw': len(comments),
291 'comments_raw': len(comments),
296 'closed': pr.is_closed(),
292 'closed': pr.is_closed(),
297 'owned': owned
293 'owned': owned
298 })
294 })
299 # json used to render the grid
295 # json used to render the grid
300 data = ({
296 data = ({
301 'data': data,
297 'data': data,
302 'recordsTotal': pull_requests_total_count,
298 'recordsTotal': pull_requests_total_count,
303 'recordsFiltered': pull_requests_total_count,
299 'recordsFiltered': pull_requests_total_count,
304 })
300 })
305 return data
301 return data
306
302
307 def my_account_pullrequests(self):
303 def my_account_pullrequests(self):
308 c.active = 'pullrequests'
304 c.active = 'pullrequests'
309 self.__load_data()
305 self.__load_data()
310 c.show_closed = str2bool(request.GET.get('pr_show_closed'))
306 c.show_closed = str2bool(request.GET.get('pr_show_closed'))
311
307
312 statuses = [PullRequest.STATUS_NEW, PullRequest.STATUS_OPEN]
308 statuses = [PullRequest.STATUS_NEW, PullRequest.STATUS_OPEN]
313 if c.show_closed:
309 if c.show_closed:
314 statuses += [PullRequest.STATUS_CLOSED]
310 statuses += [PullRequest.STATUS_CLOSED]
315 data = self._get_pull_requests_list(statuses)
311 data = self._get_pull_requests_list(statuses)
316 if not request.is_xhr:
312 if not request.is_xhr:
317 c.data_participate = json.dumps(data['data'])
313 c.data_participate = json.dumps(data['data'])
318 c.records_total_participate = data['recordsTotal']
314 c.records_total_participate = data['recordsTotal']
319 return render('admin/my_account/my_account.mako')
315 return render('admin/my_account/my_account.mako')
320 else:
316 else:
321 return json.dumps(data)
317 return json.dumps(data)
322
318
323 def my_notifications(self):
319 def my_notifications(self):
324 c.active = 'notifications'
320 c.active = 'notifications'
325 return render('admin/my_account/my_account.mako')
321 return render('admin/my_account/my_account.mako')
326
322
327 @auth.CSRFRequired()
323 @auth.CSRFRequired()
328 @jsonify
324 @jsonify
329 def my_notifications_toggle_visibility(self):
325 def my_notifications_toggle_visibility(self):
330 user = c.rhodecode_user.get_instance()
326 user = c.rhodecode_user.get_instance()
331 new_status = not user.user_data.get('notification_status', True)
327 new_status = not user.user_data.get('notification_status', True)
332 user.update_userdata(notification_status=new_status)
328 user.update_userdata(notification_status=new_status)
333 Session().commit()
329 Session().commit()
334 return user.user_data['notification_status']
330 return user.user_data['notification_status']
335
336 @auth.CSRFRequired()
337 @jsonify
338 def my_account_notifications_test_channelstream(self):
339 message = 'Test message sent via Channelstream by user: {}, on {}'.format(
340 c.rhodecode_user.username, datetime.datetime.now())
341 payload = {
342 'type': 'message',
343 'timestamp': datetime.datetime.utcnow(),
344 'user': 'system',
345 #'channel': 'broadcast',
346 'pm_users': [c.rhodecode_user.username],
347 'message': {
348 'message': message,
349 'level': 'info',
350 'topic': '/notifications'
351 }
352 }
353
354 registry = get_current_registry()
355 rhodecode_plugins = getattr(registry, 'rhodecode_plugins', {})
356 channelstream_config = rhodecode_plugins.get('channelstream', {})
357
358 try:
359 channelstream_request(channelstream_config, [payload], '/message')
360 except ChannelstreamException as e:
361 log.exception('Failed to send channelstream data')
362 return {"response": 'ERROR: {}'.format(e.__class__.__name__)}
363 return {"response": 'Channelstream data sent. '
364 'You should see a new live message now.'}
@@ -1,127 +1,128 b''
1
1
2 /******************************************************************************
2 /******************************************************************************
3 * *
3 * *
4 * DO NOT CHANGE THIS FILE MANUALLY *
4 * DO NOT CHANGE THIS FILE MANUALLY *
5 * *
5 * *
6 * *
6 * *
7 * This file is automatically generated when the app starts up with *
7 * This file is automatically generated when the app starts up with *
8 * generate_js_files = true *
8 * generate_js_files = true *
9 * *
9 * *
10 * To add a route here pass jsroute=True to the route definition in the app *
10 * To add a route here pass jsroute=True to the route definition in the app *
11 * *
11 * *
12 ******************************************************************************/
12 ******************************************************************************/
13 function registerRCRoutes() {
13 function registerRCRoutes() {
14 // routes registration
14 // routes registration
15 pyroutes.register('new_repo', '/_admin/create_repository', []);
15 pyroutes.register('new_repo', '/_admin/create_repository', []);
16 pyroutes.register('edit_user', '/_admin/users/%(user_id)s/edit', ['user_id']);
16 pyroutes.register('edit_user', '/_admin/users/%(user_id)s/edit', ['user_id']);
17 pyroutes.register('edit_user_group_members', '/_admin/user_groups/%(user_group_id)s/edit/members', ['user_group_id']);
17 pyroutes.register('edit_user_group_members', '/_admin/user_groups/%(user_group_id)s/edit/members', ['user_group_id']);
18 pyroutes.register('gists', '/_admin/gists', []);
18 pyroutes.register('gists', '/_admin/gists', []);
19 pyroutes.register('new_gist', '/_admin/gists/new', []);
19 pyroutes.register('new_gist', '/_admin/gists/new', []);
20 pyroutes.register('toggle_following', '/_admin/toggle_following', []);
20 pyroutes.register('toggle_following', '/_admin/toggle_following', []);
21 pyroutes.register('repo_stats', '/%(repo_name)s/repo_stats/%(commit_id)s', ['repo_name', 'commit_id']);
21 pyroutes.register('repo_stats', '/%(repo_name)s/repo_stats/%(commit_id)s', ['repo_name', 'commit_id']);
22 pyroutes.register('repo_refs_data', '/%(repo_name)s/refs-data', ['repo_name']);
22 pyroutes.register('repo_refs_data', '/%(repo_name)s/refs-data', ['repo_name']);
23 pyroutes.register('repo_refs_changelog_data', '/%(repo_name)s/refs-data-changelog', ['repo_name']);
23 pyroutes.register('repo_refs_changelog_data', '/%(repo_name)s/refs-data-changelog', ['repo_name']);
24 pyroutes.register('repo_default_reviewers_data', '/%(repo_name)s/default-reviewers', ['repo_name']);
24 pyroutes.register('repo_default_reviewers_data', '/%(repo_name)s/default-reviewers', ['repo_name']);
25 pyroutes.register('changeset_home', '/%(repo_name)s/changeset/%(revision)s', ['repo_name', 'revision']);
25 pyroutes.register('changeset_home', '/%(repo_name)s/changeset/%(revision)s', ['repo_name', 'revision']);
26 pyroutes.register('changeset_comment', '/%(repo_name)s/changeset/%(revision)s/comment', ['repo_name', 'revision']);
26 pyroutes.register('changeset_comment', '/%(repo_name)s/changeset/%(revision)s/comment', ['repo_name', 'revision']);
27 pyroutes.register('changeset_comment_preview', '/%(repo_name)s/changeset/comment/preview', ['repo_name']);
27 pyroutes.register('changeset_comment_preview', '/%(repo_name)s/changeset/comment/preview', ['repo_name']);
28 pyroutes.register('changeset_comment_delete', '/%(repo_name)s/changeset/comment/%(comment_id)s/delete', ['repo_name', 'comment_id']);
28 pyroutes.register('changeset_comment_delete', '/%(repo_name)s/changeset/comment/%(comment_id)s/delete', ['repo_name', 'comment_id']);
29 pyroutes.register('changeset_info', '/%(repo_name)s/changeset_info/%(revision)s', ['repo_name', 'revision']);
29 pyroutes.register('changeset_info', '/%(repo_name)s/changeset_info/%(revision)s', ['repo_name', 'revision']);
30 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']);
30 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']);
31 pyroutes.register('pullrequest_home', '/%(repo_name)s/pull-request/new', ['repo_name']);
31 pyroutes.register('pullrequest_home', '/%(repo_name)s/pull-request/new', ['repo_name']);
32 pyroutes.register('pullrequest', '/%(repo_name)s/pull-request/new', ['repo_name']);
32 pyroutes.register('pullrequest', '/%(repo_name)s/pull-request/new', ['repo_name']);
33 pyroutes.register('pullrequest_repo_refs', '/%(repo_name)s/pull-request/refs/%(target_repo_name)s', ['repo_name', 'target_repo_name']);
33 pyroutes.register('pullrequest_repo_refs', '/%(repo_name)s/pull-request/refs/%(target_repo_name)s', ['repo_name', 'target_repo_name']);
34 pyroutes.register('pullrequest_repo_destinations', '/%(repo_name)s/pull-request/repo-destinations', ['repo_name']);
34 pyroutes.register('pullrequest_repo_destinations', '/%(repo_name)s/pull-request/repo-destinations', ['repo_name']);
35 pyroutes.register('pullrequest_show', '/%(repo_name)s/pull-request/%(pull_request_id)s', ['repo_name', 'pull_request_id']);
35 pyroutes.register('pullrequest_show', '/%(repo_name)s/pull-request/%(pull_request_id)s', ['repo_name', 'pull_request_id']);
36 pyroutes.register('pullrequest_update', '/%(repo_name)s/pull-request/%(pull_request_id)s', ['repo_name', 'pull_request_id']);
36 pyroutes.register('pullrequest_update', '/%(repo_name)s/pull-request/%(pull_request_id)s', ['repo_name', 'pull_request_id']);
37 pyroutes.register('pullrequest_show_all', '/%(repo_name)s/pull-request', ['repo_name']);
37 pyroutes.register('pullrequest_show_all', '/%(repo_name)s/pull-request', ['repo_name']);
38 pyroutes.register('pullrequest_comment', '/%(repo_name)s/pull-request-comment/%(pull_request_id)s', ['repo_name', 'pull_request_id']);
38 pyroutes.register('pullrequest_comment', '/%(repo_name)s/pull-request-comment/%(pull_request_id)s', ['repo_name', 'pull_request_id']);
39 pyroutes.register('pullrequest_comment_delete', '/%(repo_name)s/pull-request-comment/%(comment_id)s/delete', ['repo_name', 'comment_id']);
39 pyroutes.register('pullrequest_comment_delete', '/%(repo_name)s/pull-request-comment/%(comment_id)s/delete', ['repo_name', 'comment_id']);
40 pyroutes.register('changelog_home', '/%(repo_name)s/changelog', ['repo_name']);
40 pyroutes.register('changelog_home', '/%(repo_name)s/changelog', ['repo_name']);
41 pyroutes.register('changelog_file_home', '/%(repo_name)s/changelog/%(revision)s/%(f_path)s', ['repo_name', 'revision', 'f_path']);
41 pyroutes.register('changelog_file_home', '/%(repo_name)s/changelog/%(revision)s/%(f_path)s', ['repo_name', 'revision', 'f_path']);
42 pyroutes.register('changelog_elements', '/%(repo_name)s/changelog_details', ['repo_name']);
42 pyroutes.register('changelog_elements', '/%(repo_name)s/changelog_details', ['repo_name']);
43 pyroutes.register('files_home', '/%(repo_name)s/files/%(revision)s/%(f_path)s', ['repo_name', 'revision', 'f_path']);
43 pyroutes.register('files_home', '/%(repo_name)s/files/%(revision)s/%(f_path)s', ['repo_name', 'revision', 'f_path']);
44 pyroutes.register('files_history_home', '/%(repo_name)s/history/%(revision)s/%(f_path)s', ['repo_name', 'revision', 'f_path']);
44 pyroutes.register('files_history_home', '/%(repo_name)s/history/%(revision)s/%(f_path)s', ['repo_name', 'revision', 'f_path']);
45 pyroutes.register('files_authors_home', '/%(repo_name)s/authors/%(revision)s/%(f_path)s', ['repo_name', 'revision', 'f_path']);
45 pyroutes.register('files_authors_home', '/%(repo_name)s/authors/%(revision)s/%(f_path)s', ['repo_name', 'revision', 'f_path']);
46 pyroutes.register('files_annotate_home', '/%(repo_name)s/annotate/%(revision)s/%(f_path)s', ['repo_name', 'revision', 'f_path']);
46 pyroutes.register('files_annotate_home', '/%(repo_name)s/annotate/%(revision)s/%(f_path)s', ['repo_name', 'revision', 'f_path']);
47 pyroutes.register('files_annotate_previous', '/%(repo_name)s/annotate-previous/%(revision)s/%(f_path)s', ['repo_name', 'revision', 'f_path']);
47 pyroutes.register('files_annotate_previous', '/%(repo_name)s/annotate-previous/%(revision)s/%(f_path)s', ['repo_name', 'revision', 'f_path']);
48 pyroutes.register('files_archive_home', '/%(repo_name)s/archive/%(fname)s', ['repo_name', 'fname']);
48 pyroutes.register('files_archive_home', '/%(repo_name)s/archive/%(fname)s', ['repo_name', 'fname']);
49 pyroutes.register('files_nodelist_home', '/%(repo_name)s/nodelist/%(revision)s/%(f_path)s', ['repo_name', 'revision', 'f_path']);
49 pyroutes.register('files_nodelist_home', '/%(repo_name)s/nodelist/%(revision)s/%(f_path)s', ['repo_name', 'revision', 'f_path']);
50 pyroutes.register('files_nodetree_full', '/%(repo_name)s/nodetree_full/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
50 pyroutes.register('files_nodetree_full', '/%(repo_name)s/nodetree_full/%(commit_id)s/%(f_path)s', ['repo_name', 'commit_id', 'f_path']);
51 pyroutes.register('summary_home_slash', '/%(repo_name)s/', ['repo_name']);
51 pyroutes.register('summary_home_slash', '/%(repo_name)s/', ['repo_name']);
52 pyroutes.register('summary_home', '/%(repo_name)s', ['repo_name']);
52 pyroutes.register('summary_home', '/%(repo_name)s', ['repo_name']);
53 pyroutes.register('favicon', '/favicon.ico', []);
53 pyroutes.register('favicon', '/favicon.ico', []);
54 pyroutes.register('robots', '/robots.txt', []);
54 pyroutes.register('robots', '/robots.txt', []);
55 pyroutes.register('auth_home', '/_admin/auth*traverse', []);
55 pyroutes.register('auth_home', '/_admin/auth*traverse', []);
56 pyroutes.register('global_integrations_new', '/_admin/integrations/new', []);
56 pyroutes.register('global_integrations_new', '/_admin/integrations/new', []);
57 pyroutes.register('global_integrations_home', '/_admin/integrations', []);
57 pyroutes.register('global_integrations_home', '/_admin/integrations', []);
58 pyroutes.register('global_integrations_list', '/_admin/integrations/%(integration)s', ['integration']);
58 pyroutes.register('global_integrations_list', '/_admin/integrations/%(integration)s', ['integration']);
59 pyroutes.register('global_integrations_create', '/_admin/integrations/%(integration)s/new', ['integration']);
59 pyroutes.register('global_integrations_create', '/_admin/integrations/%(integration)s/new', ['integration']);
60 pyroutes.register('global_integrations_edit', '/_admin/integrations/%(integration)s/%(integration_id)s', ['integration', 'integration_id']);
60 pyroutes.register('global_integrations_edit', '/_admin/integrations/%(integration)s/%(integration_id)s', ['integration', 'integration_id']);
61 pyroutes.register('repo_group_integrations_home', '%(repo_group_name)s/settings/integrations', ['repo_group_name']);
61 pyroutes.register('repo_group_integrations_home', '%(repo_group_name)s/settings/integrations', ['repo_group_name']);
62 pyroutes.register('repo_group_integrations_list', '%(repo_group_name)s/settings/integrations/%(integration)s', ['repo_group_name', 'integration']);
62 pyroutes.register('repo_group_integrations_list', '%(repo_group_name)s/settings/integrations/%(integration)s', ['repo_group_name', 'integration']);
63 pyroutes.register('repo_group_integrations_new', '%(repo_group_name)s/settings/integrations/new', ['repo_group_name']);
63 pyroutes.register('repo_group_integrations_new', '%(repo_group_name)s/settings/integrations/new', ['repo_group_name']);
64 pyroutes.register('repo_group_integrations_create', '%(repo_group_name)s/settings/integrations/%(integration)s/new', ['repo_group_name', 'integration']);
64 pyroutes.register('repo_group_integrations_create', '%(repo_group_name)s/settings/integrations/%(integration)s/new', ['repo_group_name', 'integration']);
65 pyroutes.register('repo_group_integrations_edit', '%(repo_group_name)s/settings/integrations/%(integration)s/%(integration_id)s', ['repo_group_name', 'integration', 'integration_id']);
65 pyroutes.register('repo_group_integrations_edit', '%(repo_group_name)s/settings/integrations/%(integration)s/%(integration_id)s', ['repo_group_name', 'integration', 'integration_id']);
66 pyroutes.register('repo_integrations_home', '%(repo_name)s/settings/integrations', ['repo_name']);
66 pyroutes.register('repo_integrations_home', '%(repo_name)s/settings/integrations', ['repo_name']);
67 pyroutes.register('repo_integrations_list', '%(repo_name)s/settings/integrations/%(integration)s', ['repo_name', 'integration']);
67 pyroutes.register('repo_integrations_list', '%(repo_name)s/settings/integrations/%(integration)s', ['repo_name', 'integration']);
68 pyroutes.register('repo_integrations_new', '%(repo_name)s/settings/integrations/new', ['repo_name']);
68 pyroutes.register('repo_integrations_new', '%(repo_name)s/settings/integrations/new', ['repo_name']);
69 pyroutes.register('repo_integrations_create', '%(repo_name)s/settings/integrations/%(integration)s/new', ['repo_name', 'integration']);
69 pyroutes.register('repo_integrations_create', '%(repo_name)s/settings/integrations/%(integration)s/new', ['repo_name', 'integration']);
70 pyroutes.register('repo_integrations_edit', '%(repo_name)s/settings/integrations/%(integration)s/%(integration_id)s', ['repo_name', 'integration', 'integration_id']);
70 pyroutes.register('repo_integrations_edit', '%(repo_name)s/settings/integrations/%(integration)s/%(integration_id)s', ['repo_name', 'integration', 'integration_id']);
71 pyroutes.register('ops_ping', '_admin/ops/ping', []);
71 pyroutes.register('ops_ping', '_admin/ops/ping', []);
72 pyroutes.register('admin_settings_open_source', '_admin/settings/open_source', []);
72 pyroutes.register('admin_settings_open_source', '_admin/settings/open_source', []);
73 pyroutes.register('admin_settings_vcs_svn_generate_cfg', '_admin/settings/vcs/svn_generate_cfg', []);
73 pyroutes.register('admin_settings_vcs_svn_generate_cfg', '_admin/settings/vcs/svn_generate_cfg', []);
74 pyroutes.register('admin_settings_system', '_admin/settings/system', []);
74 pyroutes.register('admin_settings_system', '_admin/settings/system', []);
75 pyroutes.register('admin_settings_system_update', '_admin/settings/system/updates', []);
75 pyroutes.register('admin_settings_system_update', '_admin/settings/system/updates', []);
76 pyroutes.register('admin_settings_sessions', '_admin/settings/sessions', []);
76 pyroutes.register('admin_settings_sessions', '_admin/settings/sessions', []);
77 pyroutes.register('admin_settings_sessions_cleanup', '_admin/settings/sessions/cleanup', []);
77 pyroutes.register('admin_settings_sessions_cleanup', '_admin/settings/sessions/cleanup', []);
78 pyroutes.register('users', '_admin/users', []);
78 pyroutes.register('users', '_admin/users', []);
79 pyroutes.register('users_data', '_admin/users_data', []);
79 pyroutes.register('users_data', '_admin/users_data', []);
80 pyroutes.register('edit_user_auth_tokens', '_admin/users/%(user_id)s/edit/auth_tokens', ['user_id']);
80 pyroutes.register('edit_user_auth_tokens', '_admin/users/%(user_id)s/edit/auth_tokens', ['user_id']);
81 pyroutes.register('edit_user_auth_tokens_add', '_admin/users/%(user_id)s/edit/auth_tokens/new', ['user_id']);
81 pyroutes.register('edit_user_auth_tokens_add', '_admin/users/%(user_id)s/edit/auth_tokens/new', ['user_id']);
82 pyroutes.register('edit_user_auth_tokens_delete', '_admin/users/%(user_id)s/edit/auth_tokens/delete', ['user_id']);
82 pyroutes.register('edit_user_auth_tokens_delete', '_admin/users/%(user_id)s/edit/auth_tokens/delete', ['user_id']);
83 pyroutes.register('edit_user_groups_management', '_admin/users/%(user_id)s/edit/groups_management', ['user_id']);
83 pyroutes.register('edit_user_groups_management', '_admin/users/%(user_id)s/edit/groups_management', ['user_id']);
84 pyroutes.register('edit_user_groups_management_updates', '_admin/users/%(user_id)s/edit/edit_user_groups_management/updates', ['user_id']);
84 pyroutes.register('edit_user_groups_management_updates', '_admin/users/%(user_id)s/edit/edit_user_groups_management/updates', ['user_id']);
85 pyroutes.register('edit_user_audit_logs', '_admin/users/%(user_id)s/edit/audit', ['user_id']);
85 pyroutes.register('edit_user_audit_logs', '_admin/users/%(user_id)s/edit/audit', ['user_id']);
86 pyroutes.register('channelstream_connect', '/_admin/channelstream/connect', []);
86 pyroutes.register('channelstream_connect', '/_admin/channelstream/connect', []);
87 pyroutes.register('channelstream_subscribe', '/_admin/channelstream/subscribe', []);
87 pyroutes.register('channelstream_subscribe', '/_admin/channelstream/subscribe', []);
88 pyroutes.register('channelstream_proxy', '/_channelstream', []);
88 pyroutes.register('channelstream_proxy', '/_channelstream', []);
89 pyroutes.register('login', '/_admin/login', []);
89 pyroutes.register('login', '/_admin/login', []);
90 pyroutes.register('logout', '/_admin/logout', []);
90 pyroutes.register('logout', '/_admin/logout', []);
91 pyroutes.register('register', '/_admin/register', []);
91 pyroutes.register('register', '/_admin/register', []);
92 pyroutes.register('reset_password', '/_admin/password_reset', []);
92 pyroutes.register('reset_password', '/_admin/password_reset', []);
93 pyroutes.register('reset_password_confirmation', '/_admin/password_reset_confirmation', []);
93 pyroutes.register('reset_password_confirmation', '/_admin/password_reset_confirmation', []);
94 pyroutes.register('home', '/', []);
94 pyroutes.register('home', '/', []);
95 pyroutes.register('user_autocomplete_data', '/_users', []);
95 pyroutes.register('user_autocomplete_data', '/_users', []);
96 pyroutes.register('user_group_autocomplete_data', '/_user_groups', []);
96 pyroutes.register('user_group_autocomplete_data', '/_user_groups', []);
97 pyroutes.register('repo_list_data', '/_repos', []);
97 pyroutes.register('repo_list_data', '/_repos', []);
98 pyroutes.register('goto_switcher_data', '/_goto_data', []);
98 pyroutes.register('goto_switcher_data', '/_goto_data', []);
99 pyroutes.register('repo_summary_explicit', '/%(repo_name)s/summary', ['repo_name']);
99 pyroutes.register('repo_summary_explicit', '/%(repo_name)s/summary', ['repo_name']);
100 pyroutes.register('tags_home', '/%(repo_name)s/tags', ['repo_name']);
100 pyroutes.register('tags_home', '/%(repo_name)s/tags', ['repo_name']);
101 pyroutes.register('branches_home', '/%(repo_name)s/branches', ['repo_name']);
101 pyroutes.register('branches_home', '/%(repo_name)s/branches', ['repo_name']);
102 pyroutes.register('bookmarks_home', '/%(repo_name)s/bookmarks', ['repo_name']);
102 pyroutes.register('bookmarks_home', '/%(repo_name)s/bookmarks', ['repo_name']);
103 pyroutes.register('edit_repo', '/%(repo_name)s/settings', ['repo_name']);
103 pyroutes.register('edit_repo', '/%(repo_name)s/settings', ['repo_name']);
104 pyroutes.register('edit_repo_advanced', '/%(repo_name)s/settings/advanced', ['repo_name']);
104 pyroutes.register('edit_repo_advanced', '/%(repo_name)s/settings/advanced', ['repo_name']);
105 pyroutes.register('edit_repo_advanced_delete', '/%(repo_name)s/settings/advanced/delete', ['repo_name']);
105 pyroutes.register('edit_repo_advanced_delete', '/%(repo_name)s/settings/advanced/delete', ['repo_name']);
106 pyroutes.register('edit_repo_advanced_locking', '/%(repo_name)s/settings/advanced/locking', ['repo_name']);
106 pyroutes.register('edit_repo_advanced_locking', '/%(repo_name)s/settings/advanced/locking', ['repo_name']);
107 pyroutes.register('edit_repo_advanced_journal', '/%(repo_name)s/settings/advanced/journal', ['repo_name']);
107 pyroutes.register('edit_repo_advanced_journal', '/%(repo_name)s/settings/advanced/journal', ['repo_name']);
108 pyroutes.register('edit_repo_advanced_fork', '/%(repo_name)s/settings/advanced/fork', ['repo_name']);
108 pyroutes.register('edit_repo_advanced_fork', '/%(repo_name)s/settings/advanced/fork', ['repo_name']);
109 pyroutes.register('edit_repo_caches', '/%(repo_name)s/settings/caches', ['repo_name']);
109 pyroutes.register('edit_repo_caches', '/%(repo_name)s/settings/caches', ['repo_name']);
110 pyroutes.register('edit_repo_perms', '/%(repo_name)s/settings/permissions', ['repo_name']);
110 pyroutes.register('edit_repo_perms', '/%(repo_name)s/settings/permissions', ['repo_name']);
111 pyroutes.register('repo_reviewers', '/%(repo_name)s/settings/review/rules', ['repo_name']);
111 pyroutes.register('repo_reviewers', '/%(repo_name)s/settings/review/rules', ['repo_name']);
112 pyroutes.register('repo_maintenance', '/%(repo_name)s/settings/maintenance', ['repo_name']);
112 pyroutes.register('repo_maintenance', '/%(repo_name)s/settings/maintenance', ['repo_name']);
113 pyroutes.register('repo_maintenance_execute', '/%(repo_name)s/settings/maintenance/execute', ['repo_name']);
113 pyroutes.register('repo_maintenance_execute', '/%(repo_name)s/settings/maintenance/execute', ['repo_name']);
114 pyroutes.register('strip', '/%(repo_name)s/settings/strip', ['repo_name']);
114 pyroutes.register('strip', '/%(repo_name)s/settings/strip', ['repo_name']);
115 pyroutes.register('strip_check', '/%(repo_name)s/settings/strip_check', ['repo_name']);
115 pyroutes.register('strip_check', '/%(repo_name)s/settings/strip_check', ['repo_name']);
116 pyroutes.register('strip_execute', '/%(repo_name)s/settings/strip_execute', ['repo_name']);
116 pyroutes.register('strip_execute', '/%(repo_name)s/settings/strip_execute', ['repo_name']);
117 pyroutes.register('search', '/_admin/search', []);
117 pyroutes.register('search', '/_admin/search', []);
118 pyroutes.register('search_repo', '/%(repo_name)s/search', ['repo_name']);
118 pyroutes.register('search_repo', '/%(repo_name)s/search', ['repo_name']);
119 pyroutes.register('user_profile', '/_profiles/%(username)s', ['username']);
119 pyroutes.register('user_profile', '/_profiles/%(username)s', ['username']);
120 pyroutes.register('my_account_profile', '/_admin/my_account/profile', []);
120 pyroutes.register('my_account_profile', '/_admin/my_account/profile', []);
121 pyroutes.register('my_account_password', '/_admin/my_account/password', []);
121 pyroutes.register('my_account_password', '/_admin/my_account/password', []);
122 pyroutes.register('my_account_password_update', '/_admin/my_account/password', []);
122 pyroutes.register('my_account_password_update', '/_admin/my_account/password', []);
123 pyroutes.register('my_account_auth_tokens', '/_admin/my_account/auth_tokens', []);
123 pyroutes.register('my_account_auth_tokens', '/_admin/my_account/auth_tokens', []);
124 pyroutes.register('my_account_auth_tokens_add', '/_admin/my_account/auth_tokens/new', []);
124 pyroutes.register('my_account_auth_tokens_add', '/_admin/my_account/auth_tokens/new', []);
125 pyroutes.register('my_account_auth_tokens_delete', '/_admin/my_account/auth_tokens/delete', []);
125 pyroutes.register('my_account_auth_tokens_delete', '/_admin/my_account/auth_tokens/delete', []);
126 pyroutes.register('my_account_notifications_test_channelstream', '/_admin/my_account/test_channelstream', []);
126 pyroutes.register('apiv2', '/_admin/api', []);
127 pyroutes.register('apiv2', '/_admin/api', []);
127 }
128 }
@@ -1,130 +1,130 b''
1 <template is="dom-bind" id="notificationsPage">
1 <template is="dom-bind" id="notificationsPage">
2 <iron-ajax id="toggleNotifications"
2 <iron-ajax id="toggleNotifications"
3 method="post"
3 method="post"
4 url="${url('my_account_notifications_toggle_visibility')}"
4 url="${url('my_account_notifications_toggle_visibility')}"
5 content-type="application/json"
5 content-type="application/json"
6 loading="{{changeNotificationsLoading}}"
6 loading="{{changeNotificationsLoading}}"
7 on-response="handleNotifications"
7 on-response="handleNotifications"
8 handle-as="json">
8 handle-as="json">
9 </iron-ajax>
9 </iron-ajax>
10
10
11 <iron-ajax id="sendTestNotification"
11 <iron-ajax id="sendTestNotification"
12 method="post"
12 method="post"
13 url="${url('my_account_notifications_test_channelstream')}"
13 url="${h.route_path('my_account_notifications_test_channelstream')}"
14 content-type="application/json"
14 content-type="application/json"
15 on-response="handleTestNotification"
15 on-response="handleTestNotification"
16 handle-as="json">
16 handle-as="json">
17 </iron-ajax>
17 </iron-ajax>
18
18
19 <div class="panel panel-default">
19 <div class="panel panel-default">
20 <div class="panel-heading">
20 <div class="panel-heading">
21 <h3 class="panel-title">${_('Your Live Notification Settings')}</h3>
21 <h3 class="panel-title">${_('Your Live Notification Settings')}</h3>
22 </div>
22 </div>
23 <div class="panel-body">
23 <div class="panel-body">
24
24
25 <p><strong>IMPORTANT:</strong> This feature requires enabled channelstream websocket server to function correctly.</p>
25 <p><strong>IMPORTANT:</strong> This feature requires enabled channelstream websocket server to function correctly.</p>
26
26
27 <p class="hidden">Status of browser notifications permission: <strong id="browser-notification-status"></strong></p>
27 <p class="hidden">Status of browser notifications permission: <strong id="browser-notification-status"></strong></p>
28
28
29 <div class="form">
29 <div class="form">
30 <div class="fields">
30 <div class="fields">
31 <div class="field">
31 <div class="field">
32 <div class="label">
32 <div class="label">
33 <label for="new_email">${_('Notifications Status')}:</label>
33 <label for="new_email">${_('Notifications Status')}:</label>
34 </div>
34 </div>
35 <div class="checkboxes">
35 <div class="checkboxes">
36 <rhodecode-toggle id="live-notifications" active="[[changeNotificationsLoading]]" on-change="toggleNotifications" ${'checked' if c.rhodecode_user.get_instance().user_data.get('notification_status') else ''}></rhodecode-toggle>
36 <rhodecode-toggle id="live-notifications" active="[[changeNotificationsLoading]]" on-change="toggleNotifications" ${'checked' if c.rhodecode_user.get_instance().user_data.get('notification_status') else ''}></rhodecode-toggle>
37 </div>
37 </div>
38 </div>
38 </div>
39 </div>
39 </div>
40 </div>
40 </div>
41 </div>
41 </div>
42 </div>
42 </div>
43
43
44 <div class="panel panel-default">
44 <div class="panel panel-default">
45 <div class="panel-heading">
45 <div class="panel-heading">
46 <h3 class="panel-title">${_('Test Notifications')}</h3>
46 <h3 class="panel-title">${_('Test Notifications')}</h3>
47 </div>
47 </div>
48 <div class="panel-body">
48 <div class="panel-body">
49
49
50
50
51 <div style="padding: 0px 0px 20px 0px">
51 <div style="padding: 0px 0px 20px 0px">
52 <button class="btn" id="test-notification" on-tap="testNotifications">Test flash message</button>
52 <button class="btn" id="test-notification" on-tap="testNotifications">Test flash message</button>
53 <button class="btn" id="test-notification-live" on-tap="testNotificationsLive">Test live notification</button>
53 <button class="btn" id="test-notification-live" on-tap="testNotificationsLive">Test live notification</button>
54 </div>
54 </div>
55 <h4 id="test-response"></h4>
55 <h4 id="test-response"></h4>
56
56
57 </div>
57 </div>
58
58
59
59
60
60
61 </div>
61 </div>
62
62
63 <script type="text/javascript">
63 <script type="text/javascript">
64 /** because im not creating a custom element for this page
64 /** because im not creating a custom element for this page
65 * we need to push the function onto the dom-template
65 * we need to push the function onto the dom-template
66 * ideally we turn this into notification-settings elements
66 * ideally we turn this into notification-settings elements
67 * then it will be cleaner
67 * then it will be cleaner
68 */
68 */
69 var ctrlr = $('#notificationsPage')[0];
69 var ctrlr = $('#notificationsPage')[0];
70 ctrlr.toggleNotifications = function(event){
70 ctrlr.toggleNotifications = function(event){
71 var ajax = $('#toggleNotifications')[0];
71 var ajax = $('#toggleNotifications')[0];
72 ajax.headers = {"X-CSRF-Token": CSRF_TOKEN};
72 ajax.headers = {"X-CSRF-Token": CSRF_TOKEN};
73 ajax.body = {notification_status:event.target.active};
73 ajax.body = {notification_status:event.target.active};
74 ajax.generateRequest();
74 ajax.generateRequest();
75 };
75 };
76 ctrlr.handleNotifications = function(event){
76 ctrlr.handleNotifications = function(event){
77 $('#live-notifications')[0].checked = event.detail.response;
77 $('#live-notifications')[0].checked = event.detail.response;
78 };
78 };
79
79
80 ctrlr.testNotifications = function(event){
80 ctrlr.testNotifications = function(event){
81 var levels = ['info', 'error', 'warning', 'success'];
81 var levels = ['info', 'error', 'warning', 'success'];
82 var level = levels[Math.floor(Math.random()*levels.length)];
82 var level = levels[Math.floor(Math.random()*levels.length)];
83 function getRandomArbitrary(min, max) {
83 function getRandomArbitrary(min, max) {
84 return parseInt(Math.random() * (max - min) + min);
84 return parseInt(Math.random() * (max - min) + min);
85 }
85 }
86 function shuffle(a) {
86 function shuffle(a) {
87 var j, x, i;
87 var j, x, i;
88 for (i = a.length; i; i--) {
88 for (i = a.length; i; i--) {
89 j = Math.floor(Math.random() * i);
89 j = Math.floor(Math.random() * i);
90 x = a[i - 1];
90 x = a[i - 1];
91 a[i - 1] = a[j];
91 a[i - 1] = a[j];
92 a[j] = x;
92 a[j] = x;
93 }
93 }
94 }
94 }
95 var wordDb = [
95 var wordDb = [
96 "Leela,", "Bender,", "we are", "going", "grave", "robbing.",
96 "Leela,", "Bender,", "we are", "going", "grave", "robbing.",
97 "Oh,", "I", "think", "we", "should", "just", "stay", "friends.",
97 "Oh,", "I", "think", "we", "should", "just", "stay", "friends.",
98 "got", "to", "find", "a", "way", "to", "escape", "the", "horrible",
98 "got", "to", "find", "a", "way", "to", "escape", "the", "horrible",
99 "ravages", "of", "youth.", "Suddenly,", "going", "to",
99 "ravages", "of", "youth.", "Suddenly,", "going", "to",
100 "the", "bathroom", "like", "clockwork,", "every", "three",
100 "the", "bathroom", "like", "clockwork,", "every", "three",
101 "hours.", "And", "those", "jerks", "at", "Social", "Security",
101 "hours.", "And", "those", "jerks", "at", "Social", "Security",
102 "stopped", "sending", "me", "checks.", "Now", "have", "to", "pay"
102 "stopped", "sending", "me", "checks.", "Now", "have", "to", "pay"
103 ];
103 ];
104 shuffle(wordDb);
104 shuffle(wordDb);
105 wordDb = wordDb.slice(0, getRandomArbitrary(3, wordDb.length));
105 wordDb = wordDb.slice(0, getRandomArbitrary(3, wordDb.length));
106 var randomMessage = wordDb.join(" ");
106 var randomMessage = wordDb.join(" ");
107 var payload = {
107 var payload = {
108 message: {
108 message: {
109 message: randomMessage + " " + new Date(),
109 message: randomMessage + " " + new Date(),
110 level: level,
110 level: level,
111 force: true
111 force: true
112 }
112 }
113 };
113 };
114 $.Topic('/notifications').publish(payload);
114 $.Topic('/notifications').publish(payload);
115 };
115 };
116 ctrlr.testNotificationsLive = function(event){
116 ctrlr.testNotificationsLive = function(event){
117 var ajax = $('#sendTestNotification')[0];
117 var ajax = $('#sendTestNotification')[0];
118 ajax.headers = {"X-CSRF-Token": CSRF_TOKEN};
118 ajax.headers = {"X-CSRF-Token": CSRF_TOKEN};
119 ajax.body = {test_msg: 'Hello !'};
119 ajax.body = {test_msg: 'Hello !'};
120 ajax.generateRequest();
120 ajax.generateRequest();
121 };
121 };
122 ctrlr.handleTestNotification = function(event){
122 ctrlr.handleTestNotification = function(event){
123 var reply = event.detail.response.response;
123 var reply = event.detail.response.response;
124 reply = reply || 'no reply form server';
124 reply = reply || 'no reply form server';
125 $('#test-response').html(reply);
125 $('#test-response').html(reply);
126 };
126 };
127
127
128 </script>
128 </script>
129
129
130 </template>
130 </template>
General Comments 0
You need to be logged in to leave comments. Login now