##// END OF EJS Templates
release: Merge default into stable for release preparation
marcink -
r1396:20388f8c merge stable
parent child Browse files
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -0,0 +1,60 b''
1 .. _user-session-ref:
2
3 Increase User Session Performance
4 ---------------------------------
5
6 The default file-based sessions are only suitable for smaller setups, or
7 instances that doesn't have a lot of users or traffic.
8 They are set as default option because it's setup-free solution.
9
10 The most common issue of file based sessions are file limit errors which occur
11 if there are lots of session files.
12
13 Therefore, in a large scale deployment, to give better performance,
14 scalability, and maintainability we recommend switching from file-based
15 sessions to database-based user sessions or memcached sessions.
16
17 To switch to database-based user sessions uncomment the following section in
18 your :file:`/home/{user}/.rccontrol/{instance-id}/rhodecode.ini` file.
19
20
21 .. code-block:: ini
22
23 ## db based session, fast, and allows easy management over logged in users
24 beaker.session.type = ext:database
25 beaker.session.table_name = db_session
26
27 # use just one of the following accoring to the type of database
28 beaker.session.sa.url = postgresql://postgres:secret@localhost/rhodecode
29 beaker.session.sa.url = mysql://root:secret@127.0.0.1/rhodecode
30
31 beaker.session.sa.pool_recycle = 3600
32 beaker.session.sa.echo = false
33
34
35 and make sure you comment out the file based sessions.
36
37 .. code-block:: ini
38
39 ## types are file, ext:memcached, ext:database, and memory (default).
40 #beaker.session.type = file
41 #beaker.session.data_dir = %(here)s/data/sessions/data
42
43
44 To switch to memcached-based user sessions uncomment the following section in
45 your :file:`/home/{user}/.rccontrol/{instance-id}/rhodecode.ini` file.
46
47 .. code-block:: ini
48
49 ## memcached sessions
50 beaker.session.type = ext:memcached
51 beaker.session.url = localhost:11211
52
53
54 and make sure you comment out the file based sessions.
55
56 .. code-block:: ini
57
58 ## types are file, ext:memcached, ext:database, and memory (default).
59 #beaker.session.type = file
60 #beaker.session.data_dir = %(here)s/data/sessions/data No newline at end of file
@@ -0,0 +1,158 b''
1 |RCE| 4.6.0 |RNS|
2 -----------------
3
4 Release Date
5 ^^^^^^^^^^^^
6
7 - 2017-02-03
8
9
10 New Features
11 ^^^^^^^^^^^^
12
13 - Pull requests: introduced versioning for pull requests.
14 Each update of pull requests creates and exposes a new version of it.
15 Users can navigate each version to show the previous state of pull request, or
16 generate diffs between versions to show what changed since the last update.
17 Also on each update attached comments are pinned to versions, so users can
18 tell at which state particular comment was made.
19 Various UI/UX fixes on PR page.
20
21 - Pull requests: introduced new merge-checks.
22 Merge checks show nicer UI for the status of merge approval.
23 Merge checks now also forbid a merge if TODO notes are present.
24 Submitting a status will auto-refresh merge checks, it means that it's no
25 longer required to re-load diff to merge a PR.
26 Same logic is now used for API, pre-conditions on show, and checks on
27 actual merge API call.
28
29 - Code review: approval state is now bound to pull request versioning. Users
30 can track their last approval and only show changes of pull requests between
31 their last approval and latest state.
32 - Code review: inline and main comments have now two types. a `note` and `todo`.
33 unresolved TODO comments show up in pull requests or commit view.
34 Unresolved TODO also prevents a PR from being merged.
35 - Code review: added navigation on outdated comments.
36
37 - Diffs: compare mode overhaul.
38 Made compare and commit range pages more consistent with other commit
39 diff pages. Old diff2way is replaced by new diffs with side-by-side
40 mode, and it also removes mergerly. Cleanup button behaviour on the compare
41 page. Switched file-diffs to use the compare page with file filter.
42 Added collapse/expand commits buttons in compare views. Generally improved UX.
43 - Diffs: added a wide-mode button to expand large diffs.
44
45 - Comments: an overhaul of comments forms. Adjust them for new comment types and
46 resolution comments.
47 - Comments: replaced a ctrl+space commands with slash commands. This becomes
48 more standardized and easier to use.
49
50 - Changelog: added load more anchors into changelog view.
51 Users in changelog can now load comments via ajax and extend the data
52 set to show more than 100 commits. This also re-renders the graph. So it's
53 possible to show 1000s of commits in an efficient way with the DAG graph.
54
55 - User sessions: added interface to show, and cleanup user auth sessions.
56 It's possible to show, and clean obsolete sessions. Also a cleanup of all
57 sessions option were added to completely log-out all users from the system.
58
59 - Integrations: webhook integration have now additional setting to choose if
60 the call should be made with POST or GET.
61
62 - API: get_repos call now allows to filter returned data by specifying a start
63 root location. Additionally, a traverse flag was added to define if returned
64 data should be only from top-level or recursive.
65 - API: comment_type (`note` or `todo`) for comment API.
66 - API: added comment_resolved_id into comments API to resolve TODO notes.
67
68
69 General
70 ^^^^^^^
71
72 - Api: comment_pull_request, added commit_id parameter to validate status
73 changed on particular commit. In case users set status on the commit
74 which is not current valid head this API call won't change the status anymore.
75 - Channelstream: added testing panel for live notifications.
76 - Authentication: disable password change form for accounts that are not
77 managed by RhodeCode, in the case of external accounts such as LDAP/oAuth,
78 password reset doesn't make sense.
79 - Core: let pyramid handle tracebacks for all exceptions.
80 Otherwise, we'll miss exception caused in pure pyramid views.
81 - Vcs server: expose remote tracebacks from HTTP backend using
82 the Pyro4AwareFormatter. This will now in most cases propagate VCSServer
83 exception into Enterprise logs for easier tracking of errors
84 - Ishell: updated code with latest iShell changes.
85 - Svn: generate HTTP downgrade via the auto-generated config. This allows
86 a HTTPs/HTTP configuration with SVN.
87 - Dependencies: bumped various pytest related libraries to latest versions.
88 - Dependencies: bumped gevent to 1.1.2 and greenlet to 0.4.10 versions.
89 - Dependencies: bumped msgpack to version 0.4.8.
90 - Dependencies: bumped supervisor to 3.3.1 version.
91 - Dependencies: bumped Whoosh to version 2.7.4.
92 - Dependencies: bumped Markdown library to 2.6.7
93 - Dependencies: bumped mako templates to 1.0.6
94 - Dependencies: bumped waitress version to 1.0.1
95 - Dependencies: bumped pygments to 2.2.0
96 - dependencies: bumped Mercurial version to 4.0.2
97 - dependencies: bumped git version to 2.9.3
98
99
100 Security
101 ^^^^^^^^
102
103 - Login: Don't display partial password helper hash inside the logs.
104 The information is not-required and will prevent people worrying about this
105 shown in logs.
106 - Auth: use pyramid HTTP exception when detecting CSRF errors. It helps
107 catching this error by our error handler and displaying it nicely to users.
108 - SVN: hide password entries in logs using specially generated configuration
109 for Apache Mod-Dav
110 - Permissions: fixed call to correctly check permissions for admin, before admin
111 users were ban deleting of pull requests in certain conditions.
112
113
114 Performance
115 ^^^^^^^^^^^
116
117 - Markup renderer: use global Markdown object to speed up markdown rendering.
118 We'll skip heavy initialization on each render thanks to this.
119 - Diffs: optimize how lexer is fetched for rich highlight mode.
120 Speeds up initial diff creation significantly since lexer cache is re used
121 and we don't need to fetch lexer many times.
122 - VCS: do an early detection of vcs-type request.
123 In case we're handling a VCS request, we can skip some of the pylons
124 stack initialization, speeding the request processing.
125
126
127 Fixes
128 ^^^^^
129
130 - Code review: render outdated comments that don't fit current context.
131 Comments attached to files that were removed from pull-request now will also
132 properly show up.
133 - Markup renderer: don't render plaintext files as RST. This prevents plain
134 Readme files have been wrongly rendered.
135 - VCS: raise a better exception if file node history cannot be extracted.
136 Helps to trace corrupted repositories.
137 - Exception handling: nicer error catching on repository creation.
138 - Fixed excessive number of session object creation. There should be now a
139 significant reduction in new file or DB entries created for sessions.
140 - Core: remove global timezone hook from tests. This was leaking into main
141 application causing TZ problems (such as UTC log dates).
142 - Pull requests: wait for all dynamic checks before enabling opening a PR.
143 This ensures that all code analysis were run before users are allowed to open
144 a pull request.
145 - i18n: use a consistent way of setting user language.
146 - API: added merge checks into API because it was not validated before and could
147 return an error if the merge wasn't possible for some reason.
148 - VCSServer: fetch proper locale before defaulting to default. Prevents
149 errors on some machines that don't have locales set.
150 - VCSServer: fixed 500 error if the wrong URL on HTTP mode vcsserver was accessed.
151
152
153 Upgrade notes
154 ^^^^^^^^^^^^^
155
156 - Integrations: since new POST/GET option was added to integrations, users
157 are advised to optionally check Webhooks integrations and pick one.
158 (default is still POST) No newline at end of file
@@ -0,0 +1,17 b''
1 # test related requirements
2 pytest==3.0.5
3 py==1.4.31
4 pytest-cov==2.4.0
5 pytest-sugar==0.7.1
6 pytest-runner==2.9.0
7 pytest-catchlog==1.2.2
8 pytest-profiling==1.2.2
9 gprof2dot==2016.10.13
10 pytest-timeout==1.2.0
11
12 mock==1.0.1
13 WebTest==1.4.3
14 cov-core==1.15.0
15 coverage==3.7.1
16 cssselect==0.9.1
17 lxml==3.4.4
@@ -0,0 +1,19 b''
1 # -*- coding: utf-8 -*-
2
3 # Copyright (C) 2016-2017 RhodeCode GmbH
4 #
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
@@ -0,0 +1,28 b''
1 # -*- coding: utf-8 -*-
2
3 # Copyright (C) 2016-2017 RhodeCode GmbH
4 #
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
21
22 class AdminSettingsView(object):
23
24 def __init__(self, context, request):
25 self.request = request
26 self.context = context
27 self.session = request.session
28 self._rhodecode_user = request.user
@@ -0,0 +1,48 b''
1 # -*- coding: utf-8 -*-
2
3 # Copyright (C) 2016-2017 RhodeCode GmbH
4 #
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
21 import collections
22 import logging
23
24 from pylons import tmpl_context as c
25 from pyramid.view import view_config
26
27 from rhodecode.admin.views.base import AdminSettingsView
28 from rhodecode.admin.navigation import navigation_list
29 from rhodecode.lib.auth import (LoginRequired, HasPermissionAllDecorator)
30 from rhodecode.lib.utils import read_opensource_licenses
31
32 log = logging.getLogger(__name__)
33
34
35 class OpenSourceLicensesAdminSettingsView(AdminSettingsView):
36
37 @LoginRequired()
38 @HasPermissionAllDecorator('hg.admin')
39 @view_config(
40 route_name='admin_settings_open_source', request_method='GET',
41 renderer='rhodecode:templates/admin/settings/settings.mako')
42 def open_source_licenses(self):
43 c.active = 'open_source'
44 c.navlist = navigation_list(self.request)
45 c.opensource_licenses = collections.OrderedDict(
46 sorted(read_opensource_licenses().items(), key=lambda t: t[0]))
47
48 return {}
@@ -0,0 +1,100 b''
1 # -*- coding: utf-8 -*-
2
3 # Copyright (C) 2016-2017 RhodeCode GmbH
4 #
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
21 import logging
22
23 from pylons import tmpl_context as c
24 from pyramid.view import view_config
25 from pyramid.httpexceptions import HTTPFound
26
27 from rhodecode.translation import _
28
29 from rhodecode.admin.views.base import AdminSettingsView
30 from rhodecode.lib.auth import (
31 LoginRequired, HasPermissionAllDecorator, CSRFRequired)
32 from rhodecode.lib.utils2 import safe_int
33 from rhodecode.lib import system_info
34 from rhodecode.lib import user_sessions
35
36
37 from rhodecode.admin.navigation import navigation_list
38
39
40 log = logging.getLogger(__name__)
41
42
43 class AdminSessionSettingsView(AdminSettingsView):
44
45 @LoginRequired()
46 @HasPermissionAllDecorator('hg.admin')
47 @view_config(
48 route_name='admin_settings_sessions', request_method='GET',
49 renderer='rhodecode:templates/admin/settings/settings.mako')
50 def settings_sessions(self):
51 c.active = 'sessions'
52 c.navlist = navigation_list(self.request)
53
54 c.cleanup_older_days = 60
55 older_than_seconds = 60 * 60 * 24 * c.cleanup_older_days
56
57 config = system_info.rhodecode_config().get_value()['value']['config']
58 c.session_model = user_sessions.get_session_handler(
59 config.get('beaker.session.type', 'memory'))(config)
60
61 c.session_conf = c.session_model.config
62 c.session_count = c.session_model.get_count()
63 c.session_expired_count = c.session_model.get_expired_count(
64 older_than_seconds)
65
66 return {}
67
68 @LoginRequired()
69 @CSRFRequired()
70 @HasPermissionAllDecorator('hg.admin')
71 @view_config(
72 route_name='admin_settings_sessions_cleanup', request_method='POST')
73 def settings_sessions_cleanup(self):
74 _ = self.request.translate
75 expire_days = safe_int(self.request.params.get('expire_days'))
76
77 if expire_days is None:
78 expire_days = 60
79
80 older_than_seconds = 60 * 60 * 24 * expire_days
81
82 config = system_info.rhodecode_config().get_value()['value']['config']
83 session_model = user_sessions.get_session_handler(
84 config.get('beaker.session.type', 'memory'))(config)
85
86 try:
87 session_model.clean_sessions(
88 older_than_seconds=older_than_seconds)
89 self.request.session.flash(
90 _('Cleaned up old sessions'), queue='success')
91 except user_sessions.CleanupCommand as msg:
92 self.request.session.flash(msg.message, queue='warning')
93 except Exception as e:
94 log.exception('Failed session cleanup')
95 self.request.session.flash(
96 _('Failed to cleanup up old sessions'), queue='error')
97
98 redirect_to = self.request.resource_path(
99 self.context, route_name='admin_settings_sessions')
100 return HTTPFound(redirect_to)
@@ -0,0 +1,60 b''
1 # -*- coding: utf-8 -*-
2
3 # Copyright (C) 2016-2017 RhodeCode GmbH
4 #
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
21 import logging
22
23 from pyramid.view import view_config
24
25 from rhodecode.svn_support.utils import generate_mod_dav_svn_config
26
27 from rhodecode.admin.views.base import AdminSettingsView
28 from rhodecode.lib.auth import (
29 LoginRequired, HasPermissionAllDecorator, CSRFRequired)
30
31 log = logging.getLogger(__name__)
32
33
34 class SvnConfigAdminSettingsView(AdminSettingsView):
35
36 @LoginRequired()
37 @CSRFRequired()
38 @HasPermissionAllDecorator('hg.admin')
39 @view_config(
40 route_name='admin_settings_vcs_svn_generate_cfg',
41 request_method='POST', renderer='json')
42 def vcs_svn_generate_config(self):
43 _ = self.request.translate
44 try:
45 generate_mod_dav_svn_config(self.request.registry)
46 msg = {
47 'message': _('Apache configuration for Subversion generated.'),
48 'level': 'success',
49 }
50 except Exception:
51 log.exception(
52 'Exception while generating the Apache '
53 'configuration for Subversion.')
54 msg = {
55 'message': _('Failed to generate the Apache configuration for Subversion.'),
56 'level': 'error',
57 }
58
59 data = {'message': msg}
60 return data
@@ -0,0 +1,202 b''
1 # -*- coding: utf-8 -*-
2
3 # Copyright (C) 2016-2017 RhodeCode GmbH
4 #
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
21 import logging
22 import urllib2
23 import packaging.version
24
25 from pylons import tmpl_context as c
26 from pyramid.view import view_config
27
28 import rhodecode
29 from rhodecode.lib import helpers as h
30 from rhodecode.lib.auth import (LoginRequired, HasPermissionAllDecorator)
31 from rhodecode.lib.utils2 import str2bool
32 from rhodecode.lib import system_info
33 from rhodecode.lib.ext_json import json
34
35 from rhodecode.admin.views.base import AdminSettingsView
36 from rhodecode.admin.navigation import navigation_list
37 from rhodecode.model.settings import SettingsModel
38
39 log = logging.getLogger(__name__)
40
41
42 class AdminSystemInfoSettingsView(AdminSettingsView):
43
44 @staticmethod
45 def get_update_data(update_url):
46 """Return the JSON update data."""
47 ver = rhodecode.__version__
48 log.debug('Checking for upgrade on `%s` server', update_url)
49 opener = urllib2.build_opener()
50 opener.addheaders = [('User-agent', 'RhodeCode-SCM/%s' % ver)]
51 response = opener.open(update_url)
52 response_data = response.read()
53 data = json.loads(response_data)
54
55 return data
56
57 def get_update_url(self):
58 settings = SettingsModel().get_all_settings()
59 return settings.get('rhodecode_update_url')
60
61 @LoginRequired()
62 @HasPermissionAllDecorator('hg.admin')
63 @view_config(
64 route_name='admin_settings_system', request_method='GET',
65 renderer='rhodecode:templates/admin/settings/settings.mako')
66 def settings_system_info(self):
67 _ = self.request.translate
68
69 c.active = 'system'
70 c.navlist = navigation_list(self.request)
71
72 # TODO(marcink), figure out how to allow only selected users to do this
73 c.allowed_to_snapshot = self._rhodecode_user.admin
74
75 snapshot = str2bool(self.request.params.get('snapshot'))
76
77 c.rhodecode_update_url = self.get_update_url()
78 server_info = system_info.get_system_info(self.request.environ)
79
80 for key, val in server_info.items():
81 setattr(c, key, val)
82
83 def val(name, subkey='human_value'):
84 return server_info[name][subkey]
85
86 def state(name):
87 return server_info[name]['state']
88
89 def val2(name):
90 val = server_info[name]['human_value']
91 state = server_info[name]['state']
92 return val, state
93
94 update_info_msg = _('Note: please make sure this server can '
95 'access `${url}` for the update link to work',
96 mapping=dict(url=c.rhodecode_update_url))
97 c.data_items = [
98 # update info
99 (_('Update info'), h.literal(
100 '<span class="link" id="check_for_update" >%s.</span>' % (
101 _('Check for updates')) +
102 '<br/> <span >%s.</span>' % (update_info_msg)
103 ), ''),
104
105 # RhodeCode specific
106 (_('RhodeCode Version'), val('rhodecode_app')['text'], state('rhodecode_app')),
107 (_('RhodeCode Server IP'), val('server')['server_ip'], state('server')),
108 (_('RhodeCode Server ID'), val('server')['server_id'], state('server')),
109 (_('RhodeCode Configuration'), val('rhodecode_config')['path'], state('rhodecode_config')),
110 ('', '', ''), # spacer
111
112 # Database
113 (_('Database'), val('database')['url'], state('database')),
114 (_('Database version'), val('database')['version'], state('database')),
115 ('', '', ''), # spacer
116
117 # Platform/Python
118 (_('Platform'), val('platform')['name'], state('platform')),
119 (_('Platform UUID'), val('platform')['uuid'], state('platform')),
120 (_('Python version'), val('python')['version'], state('python')),
121 (_('Python path'), val('python')['executable'], state('python')),
122 ('', '', ''), # spacer
123
124 # Systems stats
125 (_('CPU'), val('cpu'), state('cpu')),
126 (_('Load'), val('load')['text'], state('load')),
127 (_('Memory'), val('memory')['text'], state('memory')),
128 (_('Uptime'), val('uptime')['text'], state('uptime')),
129 ('', '', ''), # spacer
130
131 # Repo storage
132 (_('Storage location'), val('storage')['path'], state('storage')),
133 (_('Storage info'), val('storage')['text'], state('storage')),
134 (_('Storage inodes'), val('storage_inodes')['text'], state('storage_inodes')),
135
136 (_('Gist storage location'), val('storage_gist')['path'], state('storage_gist')),
137 (_('Gist storage info'), val('storage_gist')['text'], state('storage_gist')),
138
139 (_('Archive cache storage location'), val('storage_archive')['path'], state('storage_archive')),
140 (_('Archive cache info'), val('storage_archive')['text'], state('storage_archive')),
141
142 (_('Temp storage location'), val('storage_temp')['path'], state('storage_temp')),
143 (_('Temp storage info'), val('storage_temp')['text'], state('storage_temp')),
144
145 (_('Search info'), val('search')['text'], state('search')),
146 (_('Search location'), val('search')['location'], state('search')),
147 ('', '', ''), # spacer
148
149 # VCS specific
150 (_('VCS Backends'), val('vcs_backends'), state('vcs_backends')),
151 (_('VCS Server'), val('vcs_server')['text'], state('vcs_server')),
152 (_('GIT'), val('git'), state('git')),
153 (_('HG'), val('hg'), state('hg')),
154 (_('SVN'), val('svn'), state('svn')),
155
156 ]
157
158 if snapshot:
159 if c.allowed_to_snapshot:
160 c.data_items.pop(0) # remove server info
161 self.request.override_renderer = 'admin/settings/settings_system_snapshot.mako'
162 else:
163 self.request.session.flash(
164 'You are not allowed to do this', queue='warning')
165 return {}
166
167 @LoginRequired()
168 @HasPermissionAllDecorator('hg.admin')
169 @view_config(
170 route_name='admin_settings_system_update', request_method='GET',
171 renderer='rhodecode:templates/admin/settings/settings_system_update.mako')
172 def settings_system_info_check_update(self):
173 _ = self.request.translate
174
175 update_url = self.get_update_url()
176
177 _err = lambda s: '<div style="color:#ff8888; padding:4px 0px">{}</div>'.format(s)
178 try:
179 data = self.get_update_data(update_url)
180 except urllib2.URLError as e:
181 log.exception("Exception contacting upgrade server")
182 self.request.override_renderer = 'string'
183 return _err('Failed to contact upgrade server: %r' % e)
184 except ValueError as e:
185 log.exception("Bad data sent from update server")
186 self.request.override_renderer = 'string'
187 return _err('Bad data sent from update server')
188
189 latest = data['versions'][0]
190
191 c.update_url = update_url
192 c.latest_data = latest
193 c.latest_ver = latest['version']
194 c.cur_ver = rhodecode.__version__
195 c.should_upgrade = False
196
197 if (packaging.version.Version(c.latest_ver) >
198 packaging.version.Version(c.cur_ver)):
199 c.should_upgrade = True
200 c.important_notices = latest['general']
201
202 return {}
@@ -0,0 +1,44 b''
1 # -*- coding: utf-8 -*-
2
3 # Copyright (C) 2017-2017 RhodeCode GmbH
4 #
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
21 import mock
22 import pytest
23
24 from rhodecode.lib.user_sessions import FileAuthSessions
25 from rhodecode.api.tests.utils import (
26 build_data, api_call, assert_ok, assert_error, crash)
27
28
29 @pytest.mark.usefixtures("testuser_api", "app")
30 class TestCleanupSessions(object):
31 def test_api_cleanup_sessions(self):
32 id_, params = build_data(self.apikey, 'cleanup_sessions')
33 response = api_call(self.app, params)
34
35 expected = {'backend': 'file sessions', 'sessions_removed': 0}
36 assert_ok(id_, expected, given=response.body)
37
38 @mock.patch.object(FileAuthSessions, 'clean_sessions', crash)
39 def test_api_cleanup_error(self):
40 id_, params = build_data(self.apikey, 'cleanup_sessions', )
41 response = api_call(self.app, params)
42
43 expected = 'Error occurred during session cleanup'
44 assert_error(id_, expected, given=response.body)
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
@@ -1,5 +1,5 b''
1 [bumpversion]
1 [bumpversion]
2 current_version = 4.5.2
2 current_version = 4.6.0
3 message = release: Bump version {current_version} to {new_version}
3 message = release: Bump version {current_version} to {new_version}
4
4
5 [bumpversion:file:rhodecode/VERSION]
5 [bumpversion:file:rhodecode/VERSION]
@@ -4,26 +4,21 b' done = false'
4 [task:bump_version]
4 [task:bump_version]
5 done = true
5 done = true
6
6
7 [task:rc_tools_pinned]
8 done = true
9
10 [task:fixes_on_stable]
7 [task:fixes_on_stable]
11 done = true
12
8
13 [task:pip2nix_generated]
9 [task:pip2nix_generated]
14 done = true
15
10
16 [task:changelog_updated]
11 [task:changelog_updated]
17 done = true
18
12
19 [task:generate_api_docs]
13 [task:generate_api_docs]
20 done = true
14
15 [task:updated_translation]
21
16
22 [release]
17 [release]
23 state = prepared
18 state = in_progress
24 version = 4.5.2
19 version = 4.6.0
25
20
26 [task:updated_translation]
21 [task:rc_tools_pinned]
27
22
28 [task:generate_js_routes]
23 [task:generate_js_routes]
29
24
@@ -29,8 +29,6 b' recursive-include rhodecode *.mako'
29 # 502 page
29 # 502 page
30 include rhodecode/public/502.html
30 include rhodecode/public/502.html
31
31
32 # 502 page
33 include rhodecode/public/502.html
34
32
35 # images, css
33 # images, css
36 include rhodecode/public/css/*.css
34 include rhodecode/public/css/*.css
@@ -1,11 +1,25 b''
1
2 .PHONY: clean docs docs-clean docs-cleanup test test-clean test-only web-build
1
3
2 WEBPACK=./node_modules/webpack/bin/webpack.js
4 WEBPACK=./node_modules/webpack/bin/webpack.js
3 GRUNT=grunt
5 GRUNT=grunt
4 NODE_PATH=./node_modules
6 NODE_PATH=./node_modules
5 CI_PREFIX=enterprise
7
8
9 clean:
10 make test-clean
11 find . -type f \( -iname '*.c' -o -iname '*.pyc' -o -iname '*.so' \) -exec rm '{}' ';'
6
12
7 .PHONY: docs docs-clean ci-docs clean test test-clean test-lint test-only
13 test:
14 make test-clean
15 make test-only
8
16
17 test-clean:
18 rm -rf coverage.xml htmlcov junit.xml pylint.log result
19 find . -type d -name "__pycache__" -prune -exec rm -rf '{}' ';'
20
21 test-only:
22 PYTHONHASHSEED=random py.test -vv -r xw --cov=rhodecode --cov-report=term-missing --cov-report=html rhodecode
9
23
10 docs:
24 docs:
11 (cd docs; nix-build default.nix -o result; make clean html)
25 (cd docs; nix-build default.nix -o result; make clean html)
@@ -13,27 +27,9 b' docs:'
13 docs-clean:
27 docs-clean:
14 (cd docs; make clean)
28 (cd docs; make clean)
15
29
16 ci-docs: docs;
30 docs-cleanup:
17
31 (cd docs; make cleanup)
18
19 clean: test-clean
20 find . -type f \( -iname '*.c' -o -iname '*.pyc' -o -iname '*.so' \) -exec rm '{}' ';'
21
22 test: test-clean test-only
23
24 test-clean:
25 rm -rf coverage.xml htmlcov junit.xml pylint.log result
26
27 test-only:
28 PYTHONHASHSEED=random py.test -vv -r xw --cov=rhodecode --cov-report=term-missing --cov-report=html rhodecode/tests/
29
32
30 web-build:
33 web-build:
31 NODE_PATH=$(NODE_PATH) $(GRUNT)
34 NODE_PATH=$(NODE_PATH) $(GRUNT)
32
35
33 web-test:
34 @echo "no test for our javascript, yet!"
35
36 docs-bootstrap:
37 (cd docs; nix-build default.nix -o result)
38 @echo "Please go to docs folder and run make html"
39
@@ -415,19 +415,23 b' search.location = %(here)s/data/index'
415 ########################################
415 ########################################
416 ## channelstream enables persistent connections and live notification
416 ## channelstream enables persistent connections and live notification
417 ## in the system. It's also used by the chat system
417 ## in the system. It's also used by the chat system
418 channelstream.enabled = false
418
419
419 channelstream.enabled = false
420 ## server address for channelstream server on the backend
420 ## location of channelstream server on the backend
421 channelstream.server = 127.0.0.1:9800
421 channelstream.server = 127.0.0.1:9800
422
422 ## location of the channelstream server from outside world
423 ## location of the channelstream server from outside world
423 ## most likely this would be an http server special backend URL, that handles
424 ## use ws:// for http or wss:// for https. This address needs to be handled
424 ## websocket connections see nginx example for config
425 ## by external HTTP server such as Nginx or Apache
425 # channelstream.ws_url = ws://rhodecode.yourserver.com/_channelstream
426 ## see nginx/apache configuration examples in our docs
426 ## proxy path that can be used by http daemons for exposing channelstream
427 channelstream.ws_url = ws://rhodecode.yourserver.com/_channelstream
427 # channelstream.proxy_path = /_channelstream
428 channelstream.secret = secret
428 channelstream.secret = secret
429 channelstream.history.location = %(here)s/channelstream_history
429 channelstream.history.location = %(here)s/channelstream_history
430
430
431 ## Internal application path that Javascript uses to connect into.
432 ## If you use proxy-prefix the prefix should be added before /_channelstream
433 channelstream.proxy_path = /_channelstream
434
431
435
432 ###################################
436 ###################################
433 ## APPENLIGHT CONFIG ##
437 ## APPENLIGHT CONFIG ##
@@ -501,9 +505,9 b' appenlight.log_namespace_blacklist ='
501 ##############
505 ##############
502 debug_style = true
506 debug_style = true
503
507
504 #########################################################
508 ###########################################
505 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
509 ### MAIN RHODECODE DATABASE CONFIG ###
506 #########################################################
510 ###########################################
507 #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db?timeout=30
511 #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db?timeout=30
508 #sqlalchemy.db1.url = postgresql://postgres:qweqwe@localhost/rhodecode
512 #sqlalchemy.db1.url = postgresql://postgres:qweqwe@localhost/rhodecode
509 #sqlalchemy.db1.url = mysql://root:qweqwe@localhost/rhodecode
513 #sqlalchemy.db1.url = mysql://root:qweqwe@localhost/rhodecode
@@ -586,12 +590,16 b' svn.proxy.location_root = /'
586 ## be killed. Setting it to zero means no timeout. Defaults to 10 seconds.
590 ## be killed. Setting it to zero means no timeout. Defaults to 10 seconds.
587 #svn.proxy.reload_timeout = 10
591 #svn.proxy.reload_timeout = 10
588
592
593 ## Dummy marker to add new entries after.
594 ## Add any custom entries below. Please don't remove.
595 custom.conf = 1
596
589
597
590 ################################
598 ################################
591 ### LOGGING CONFIGURATION ####
599 ### LOGGING CONFIGURATION ####
592 ################################
600 ################################
593 [loggers]
601 [loggers]
594 keys = root, routes, rhodecode, sqlalchemy, beaker, pyro4, templates
602 keys = root, routes, rhodecode, sqlalchemy, beaker, templates
595
603
596 [handlers]
604 [handlers]
597 keys = console, console_sql
605 keys = console, console_sql
@@ -619,12 +627,6 b' handlers ='
619 qualname = beaker.container
627 qualname = beaker.container
620 propagate = 1
628 propagate = 1
621
629
622 [logger_pyro4]
623 level = DEBUG
624 handlers =
625 qualname = Pyro4
626 propagate = 1
627
628 [logger_templates]
630 [logger_templates]
629 level = INFO
631 level = INFO
630 handlers =
632 handlers =
@@ -649,13 +651,13 b' propagate = 0'
649
651
650 [handler_console]
652 [handler_console]
651 class = StreamHandler
653 class = StreamHandler
652 args = (sys.stderr,)
654 args = (sys.stderr, )
653 level = DEBUG
655 level = DEBUG
654 formatter = color_formatter
656 formatter = color_formatter
655
657
656 [handler_console_sql]
658 [handler_console_sql]
657 class = StreamHandler
659 class = StreamHandler
658 args = (sys.stderr,)
660 args = (sys.stderr, )
659 level = DEBUG
661 level = DEBUG
660 formatter = color_formatter_sql
662 formatter = color_formatter_sql
661
663
@@ -1,4 +1,17 b''
1 """gunicorn config hooks"""
1 """
2 gunicorn config extension and hooks. Sets additional configuration that is
3 available post the .ini config.
4
5 - workers = ${cpu_number}
6 - threads = 1
7 - proc_name = ${gunicorn_proc_name}
8 - worker_class = sync
9 - worker_connections = 10
10 - max_requests = 1000
11 - max_requests_jitter = 30
12 - timeout = 21600
13
14 """
2
15
3 import multiprocessing
16 import multiprocessing
4 import sys
17 import sys
@@ -6,50 +19,31 b' import threading'
6 import traceback
19 import traceback
7
20
8
21
9 # GLOBAL #
22 # GLOBAL
10 errorlog = '-'
23 errorlog = '-'
11 accesslog = '-'
24 accesslog = '-'
12 loglevel = 'debug'
25 loglevel = 'debug'
13
26
14 # SECURITY #
27 # SECURITY
15 limit_request_line = 4094
28 limit_request_line = 4094
16 limit_request_fields = 100
29 limit_request_fields = 100
17 limit_request_field_size = 8190
30 limit_request_field_size = 8190
18
31
19 # SERVER MECHANICS #
32 # SERVER MECHANICS
20 # None == system temp dir #
33 # None == system temp dir
21 worker_tmp_dir = None
34 worker_tmp_dir = None
22 tmp_upload_dir = None
35 tmp_upload_dir = None
23 #proc_name =
24
25 # self adjust workers based on CPU #
26 #workers = multiprocessing.cpu_count() * 2 + 1
27
28 access_log_format = '[%(p)s] %(h)15s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s" request_time:%(L)s'
29
30 # For the gevent worker classes #
31 # this limits the maximum number of simultaneous clients that #
32 # a single process can handle. #
33 #worker_connections = 10
34
36
35 # Max requests to handle by each worker before restarting it, #
37 # Custom log format
36 # could prevent memory leaks #
38 access_log_format = (
37 #max_requests = 1000
39 '%(t)s GNCRN %(p)-8s %(h)-15s rqt:%(L)s %(s)s %(b)s "%(m)s:%(U)s %(q)s" usr:%(u)s "%(f)s" "%(a)s"')
38 #max_requests_jitter = 30
39
40
40
41 # If a worker does not notify the master process in this #
41 # self adjust workers based on CPU count
42 # number of seconds it is killed and a new worker is spawned #
42 # workers = multiprocessing.cpu_count() * 2 + 1
43 # to replace it. #
44 #timeout = 3600
45
46 access_log_format = (
47 '[%(p)-10s] %(h)s time:%(L)s %(l)s %(u)s '
48 '%(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"')
49
43
50
44
51 def post_fork(server, worker):
45 def post_fork(server, worker):
52 server.log.info("[<%s>] worker spawned", worker.pid)
46 server.log.info("[<%-10s>] WORKER spawned", worker.pid)
53
47
54
48
55 def pre_fork(server, worker):
49 def pre_fork(server, worker):
@@ -67,7 +61,7 b' def when_ready(server):'
67 def worker_int(worker):
61 def worker_int(worker):
68 worker.log.info("[<%-10s>] worker received INT or QUIT signal", worker.pid)
62 worker.log.info("[<%-10s>] worker received INT or QUIT signal", worker.pid)
69
63
70 # get traceback info
64 # get traceback info, on worker crash
71 id2name = dict([(th.ident, th.name) for th in threading.enumerate()])
65 id2name = dict([(th.ident, th.name) for th in threading.enumerate()])
72 code = []
66 code = []
73 for thread_id, stack in sys._current_frames().items():
67 for thread_id, stack in sys._current_frames().items():
@@ -389,19 +389,23 b' search.location = %(here)s/data/index'
389 ########################################
389 ########################################
390 ## channelstream enables persistent connections and live notification
390 ## channelstream enables persistent connections and live notification
391 ## in the system. It's also used by the chat system
391 ## in the system. It's also used by the chat system
392 channelstream.enabled = false
392
393
393 channelstream.enabled = false
394 ## server address for channelstream server on the backend
394 ## location of channelstream server on the backend
395 channelstream.server = 127.0.0.1:9800
395 channelstream.server = 127.0.0.1:9800
396
396 ## location of the channelstream server from outside world
397 ## location of the channelstream server from outside world
397 ## most likely this would be an http server special backend URL, that handles
398 ## use ws:// for http or wss:// for https. This address needs to be handled
398 ## websocket connections see nginx example for config
399 ## by external HTTP server such as Nginx or Apache
399 # channelstream.ws_url = ws://rhodecode.yourserver.com/_channelstream
400 ## see nginx/apache configuration examples in our docs
400 ## proxy path that can be used by http daemons for exposing channelstream
401 channelstream.ws_url = ws://rhodecode.yourserver.com/_channelstream
401 # channelstream.proxy_path = /_channelstream
402 channelstream.secret = secret
402 channelstream.secret = secret
403 channelstream.history.location = %(here)s/channelstream_history
403 channelstream.history.location = %(here)s/channelstream_history
404
404
405 ## Internal application path that Javascript uses to connect into.
406 ## If you use proxy-prefix the prefix should be added before /_channelstream
407 channelstream.proxy_path = /_channelstream
408
405
409
406 ###################################
410 ###################################
407 ## APPENLIGHT CONFIG ##
411 ## APPENLIGHT CONFIG ##
@@ -470,9 +474,9 b' appenlight.log_namespace_blacklist ='
470 set debug = false
474 set debug = false
471
475
472
476
473 #########################################################
477 ###########################################
474 ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ###
478 ### MAIN RHODECODE DATABASE CONFIG ###
475 #########################################################
479 ###########################################
476 #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db?timeout=30
480 #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db?timeout=30
477 #sqlalchemy.db1.url = postgresql://postgres:qweqwe@localhost/rhodecode
481 #sqlalchemy.db1.url = postgresql://postgres:qweqwe@localhost/rhodecode
478 #sqlalchemy.db1.url = mysql://root:qweqwe@localhost/rhodecode
482 #sqlalchemy.db1.url = mysql://root:qweqwe@localhost/rhodecode
@@ -555,12 +559,16 b' svn.proxy.location_root = /'
555 ## be killed. Setting it to zero means no timeout. Defaults to 10 seconds.
559 ## be killed. Setting it to zero means no timeout. Defaults to 10 seconds.
556 #svn.proxy.reload_timeout = 10
560 #svn.proxy.reload_timeout = 10
557
561
562 ## Dummy marker to add new entries after.
563 ## Add any custom entries below. Please don't remove.
564 custom.conf = 1
565
558
566
559 ################################
567 ################################
560 ### LOGGING CONFIGURATION ####
568 ### LOGGING CONFIGURATION ####
561 ################################
569 ################################
562 [loggers]
570 [loggers]
563 keys = root, routes, rhodecode, sqlalchemy, beaker, pyro4, templates
571 keys = root, routes, rhodecode, sqlalchemy, beaker, templates
564
572
565 [handlers]
573 [handlers]
566 keys = console, console_sql
574 keys = console, console_sql
@@ -588,12 +596,6 b' handlers ='
588 qualname = beaker.container
596 qualname = beaker.container
589 propagate = 1
597 propagate = 1
590
598
591 [logger_pyro4]
592 level = DEBUG
593 handlers =
594 qualname = Pyro4
595 propagate = 1
596
597 [logger_templates]
599 [logger_templates]
598 level = INFO
600 level = INFO
599 handlers =
601 handlers =
@@ -618,13 +620,13 b' propagate = 0'
618
620
619 [handler_console]
621 [handler_console]
620 class = StreamHandler
622 class = StreamHandler
621 args = (sys.stderr,)
623 args = (sys.stderr, )
622 level = INFO
624 level = INFO
623 formatter = generic
625 formatter = generic
624
626
625 [handler_console_sql]
627 [handler_console_sql]
626 class = StreamHandler
628 class = StreamHandler
627 args = (sys.stderr,)
629 args = (sys.stderr, )
628 level = WARN
630 level = WARN
629 formatter = generic
631 formatter = generic
630
632
@@ -135,6 +135,8 b' let'
135 rhodecode-testdata
135 rhodecode-testdata
136 ]);
136 ]);
137
137
138 #TODO: either move this into overrides, OR use the new machanics from
139 # pip2nix and requiremtn.txt file
138 propagatedBuildInputs = attrs.propagatedBuildInputs ++ (with self; [
140 propagatedBuildInputs = attrs.propagatedBuildInputs ++ (with self; [
139 rhodecode-tools
141 rhodecode-tools
140 ]);
142 ]);
@@ -49,6 +49,12 b' help:'
49 clean:
49 clean:
50 rm -rf $(BUILDDIR)/*
50 rm -rf $(BUILDDIR)/*
51
51
52 cleanup:
53 @echo "cleaning build dir"
54 rm -rf $(BUILDDIR)/*
55 @echo "cleaning result symlink"
56 rm -v result
57
52 html:
58 html:
53 $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
59 $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
54 @echo
60 @echo
@@ -1,32 +1,68 b''
1 .. _apache-conf-eg:
1 .. _apache-conf-eg:
2
2
3 Apache Configuration Examples
3 Apache Configuration Example
4 -----------------------------
4 ----------------------------
5
6 Use the following example to configure Apache as a your web server.
7 Below config if for an Apache Reverse Proxy configuration.
8
9 .. note::
10
11 Apache requires the following modules to be enabled. Below is an example
12 how to enable them on Ubuntu Server
13
5
14
6 Use the following example to securely configure your Apache HTTP virtual hosts
15 .. code-block:: bash
7 file.
16
17 $ sudo a2enmod proxy
18 $ sudo a2enmod proxy_http
19 $ sudo a2enmod proxy_balancer
20 $ sudo a2enmod headers
21 $ sudo a2enmod ssl
22 $ sudo a2enmod rewrite
23
24 # requires Apache 2.4+, required to handle websockets/channelstream
25 $ sudo a2enmod proxy_wstunnel
26
8
27
9 .. code-block:: apache
28 .. code-block:: apache
10
29
30 ## HTTP to HTTPS rewrite
11 <VirtualHost *:80>
31 <VirtualHost *:80>
12 ServerName hg.myserver.com
32 ServerName rhodecode.myserver.com
13 ServerAlias hg.myserver.com
33 DocumentRoot /var/www/html
34 Redirect permanent / https://rhodecode.myserver.com/
35 </VirtualHost>
36
37 ## MAIN SSL enabled server
38 <VirtualHost *:443>
39
40 ServerName rhodecode.myserver.com
41 ServerAlias rhodecode.myserver.com
42
43 ## serve static files by Apache, recommended for performance
44 #Alias /_static /home/ubuntu/.rccontrol/community-1/static
45
46 RequestHeader set X-Forwarded-Proto "https"
47
48 ## channelstream websocket handling
49 ProxyPass /_channelstream ws://localhost:9800
50 ProxyPassReverse /_channelstream ws://localhost:9800
14
51
15 <Proxy *>
52 <Proxy *>
16 Order allow,deny
53 Order allow,deny
17 Allow from all
54 Allow from all
18 </Proxy>
55 </Proxy>
19
56
20 # important !
57 # Directive to properly generate url (clone url) for RhodeCode
21 # Directive to properly generate url (clone url) for pylons
22
23 ProxyPreserveHost On
58 ProxyPreserveHost On
24
59
25 #rhodecode instance
60 # Url to running RhodeCode instance. This is shown as `- URL:` when
26 ProxyPass / http://127.0.0.1:5000/
61 # running rccontrol status.
27 ProxyPassReverse / http://127.0.0.1:5000/
62 ProxyPass / http://127.0.0.1:10002/
63 ProxyPassReverse / http://127.0.0.1:10002/
28
64
29 # Set strict HTTPS
65 # strict http prevents from https -> http downgrade
30 Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"
66 Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"
31
67
32 # Set x-frame options
68 # Set x-frame options
@@ -35,80 +71,17 b' file.'
35 # To enable https use line below
71 # To enable https use line below
36 # SetEnvIf X-Url-Scheme https HTTPS=1
72 # SetEnvIf X-Url-Scheme https HTTPS=1
37
73
38 # Secure your Diffie-hellmann deployment
74 # SSL setup
75 SSLEngine On
76 SSLCertificateFile /etc/apache2/ssl/rhodecode.myserver.pem
77 SSLCertificateKeyFile /etc/apache2/ssl/rhodecode.myserver.key
78
39 SSLProtocol all -SSLv2 -SSLv3
79 SSLProtocol all -SSLv2 -SSLv3
40 SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA
80 SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA
41 SSLHonorCipherOrder on
81 SSLHonorCipherOrder on
42 SSLOpenSSLConfCmd DHParameters "{path to dhparams.pem}"
82
83 # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
84 #SSLOpenSSLConfCmd DHParameters "/etc/apache2/dhparam.pem"
43
85
44 </VirtualHost>
86 </VirtualHost>
45
87
46 Use the following example to configure Apache for a multi-node setup. The
47 timeout setting should be increased if you experience timeouts when working
48 with large |repos|.
49
50 .. code-block:: apache
51
52 #
53 # Timeout: The number of seconds before receives and sends time out.
54 #
55 Timeout 600
56
57 <VirtualHost *:80>
58
59 ProxyRequests off
60
61 #important !
62 #Directive to properly generate url (clone url) for pylons
63 ProxyPreserveHost On
64
65 ServerName your.rce.com
66 ServerAlias your.rce.com
67
68 <Proxy balancer://mycluster>
69 # WebHead1
70 BalancerMember http://10.58.1.171:10002 route=1
71 # WebHead2
72 BalancerMember http://10.58.1.172:10001 route=2
73
74 # Security "technically we aren't blocking
75 # anyone but this the place to make those
76 # chages
77 Order Deny,Allow
78 Deny from none
79 Allow from all
80
81 # Load Balancer Settings
82 # We will be configuring a simple Round
83 # Robin style load balancer. This means
84 # that all webheads take an equal share of
85 # of the load.
86 ProxySet stickysession=ROUTEID
87
88 </Proxy>
89
90 # balancer-manager
91 # This tool is built into the mod_proxy_balancer
92 # module and will allow you to do some simple
93 # modifications to the balanced group via a gui
94 # web interface.
95 <Location /balancer-manager>
96 SetHandler balancer-manager
97
98 # recommend locking this one down to your
99 # your office
100 Order deny,allow
101 Allow from all
102 </Location>
103
104 # Point of Balance
105 # This setting will allow to explicitly name the
106 # the location in the site that we want to be
107 # balanced, in this example we will balance "/"
108 # or everything in the site.
109 ProxyPass /balancer-manager !
110 ProxyPass / balancer://mycluster/
111
112 ProxyPassReverse / balancer://mycluster/
113
114 </VirtualHost>
@@ -9,7 +9,6 b' the information in the following section'
9 .. toctree::
9 .. toctree::
10
10
11 apache-diffie-hellman
11 apache-diffie-hellman
12 apache-conf-examples
12 apache-conf-example
13 apache-subdirectory
13 apache-subdirectory
14 apache-reverse-proxy
15 apache-wsgi-coding
14 apache-wsgi-coding
@@ -7,7 +7,8 b' Use the following example to configure A'
7
7
8 .. code-block:: apache
8 .. code-block:: apache
9
9
10 <Location /<someprefix>/ # Change <someprefix> into your chosen prefix
10 # Change someprefix into your chosen prefix
11 <Location /someprefix >
11 ProxyPreserveHost On
12 ProxyPreserveHost On
12 ProxyPass "http://127.0.0.1:5000/"
13 ProxyPass "http://127.0.0.1:5000/"
13 ProxyPassReverse "http://127.0.0.1:5000/"
14 ProxyPassReverse "http://127.0.0.1:5000/"
@@ -3,6 +3,7 b' Nginx Configuration Example'
3
3
4 Use the following example to configure Nginx as a your web server.
4 Use the following example to configure Nginx as a your web server.
5
5
6
6 .. code-block:: nginx
7 .. code-block:: nginx
7
8
8 log_format log_custom '$remote_addr - $remote_user [$time_local] '
9 log_format log_custom '$remote_addr - $remote_user [$time_local] '
@@ -10,8 +11,10 b' Use the following example to configure N'
10 '"$http_referer" "$http_user_agent" '
11 '"$http_referer" "$http_user_agent" '
11 '$request_time $upstream_response_time $pipe';
12 '$request_time $upstream_response_time $pipe';
12
13
14 ## define upstream (local RhodeCode instance) to connect to
13 upstream rc {
15 upstream rc {
14
16 # Url to running RhodeCode instance.
17 # This is shown as `- URL:` in output from rccontrol status.
15 server 127.0.0.1:10002;
18 server 127.0.0.1:10002;
16
19
17 # add more instances for load balancing
20 # add more instances for load balancing
@@ -19,8 +22,17 b' Use the following example to configure N'
19 # server 127.0.0.1:10004;
22 # server 127.0.0.1:10004;
20 }
23 }
21
24
22 ## gist alias server, for serving nicer GIST urls
25 ## HTTP to HTTPS rewrite
26 server {
27 listen 80;
28 server_name rhodecode.myserver.com;
23
29
30 if ($http_host = rhodecode.myserver.com) {
31 rewrite (.*) https://rhodecode.myserver.com$1 permanent;
32 }
33 }
34
35 ## Optional gist alias server, for serving nicer GIST urls.
24 server {
36 server {
25 listen 443;
37 listen 443;
26 server_name gist.myserver.com;
38 server_name gist.myserver.com;
@@ -37,6 +49,7 b' Use the following example to configure N'
37 ssl_prefer_server_ciphers on;
49 ssl_prefer_server_ciphers on;
38 ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
50 ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
39
51
52 # strict http prevents from https -> http downgrade
40 add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;";
53 add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;";
41
54
42 # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
55 # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
@@ -46,15 +59,6 b' Use the following example to configure N'
46 rewrite (.*) https://rhodecode.myserver.com/_admin/gists;
59 rewrite (.*) https://rhodecode.myserver.com/_admin/gists;
47 }
60 }
48
61
49 ## HTTP to HTTPS rewrite
50 server {
51 listen 80;
52 server_name rhodecode.myserver.com;
53
54 if ($http_host = rhodecode.myserver.com) {
55 rewrite (.*) https://rhodecode.myserver.com$1 permanent;
56 }
57 }
58
62
59 ## MAIN SSL enabled server
63 ## MAIN SSL enabled server
60 server {
64 server {
@@ -79,14 +83,15 b' Use the following example to configure N'
79
83
80 include /etc/nginx/proxy.conf;
84 include /etc/nginx/proxy.conf;
81
85
82 ## serve static files by nginx, recommended
86 ## serve static files by Nginx, recommended for performance
83 # location /_static/rhodecode {
87 # location /_static/rhodecode {
84 # alias /path/to/.rccontrol/enterprise-1/static;
88 # alias /path/to/.rccontrol/enterprise-1/static;
85 # }
89 # }
86
90
87 ## channel stream live components
91 ## channelstream websocket handling
88 location /_channelstream {
92 location /_channelstream {
89 rewrite /_channelstream/(.*) /$1 break;
93 rewrite /_channelstream/(.*) /$1 break;
94
90 proxy_pass http://127.0.0.1:9800;
95 proxy_pass http://127.0.0.1:9800;
91
96
92 proxy_connect_timeout 10;
97 proxy_connect_timeout 10;
@@ -1,7 +1,7 b''
1 .. _nginx-ws-ref:
1 .. _nginx-ws-ref:
2
2
3 Nginx Configuration
3 Nginx HTTP Server Configuration
4 ===================
4 -------------------------------
5
5
6 To set up your Nginx Web Server for optimal performance and security, use
6 To set up your Nginx Web Server for optimal performance and security, use
7 the information in the following sections.
7 the information in the following sections.
@@ -12,6 +12,7 b' it somehow becomes unavailable you can u'
12 Logging into the |RCE| database with ``iShell`` should only be done by an
12 Logging into the |RCE| database with ``iShell`` should only be done by an
13 experienced and knowledgeable database administrator.
13 experienced and knowledgeable database administrator.
14
14
15
15 Reset Admin Account Privileges
16 Reset Admin Account Privileges
16 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
17 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
17
18
@@ -22,8 +23,7 b' account permissions.'
22 .. code-block:: bash
23 .. code-block:: bash
23
24
24 # Open iShell from the terminal
25 # Open iShell from the terminal
25 $ .rccontrol/enterprise-1/profile/bin/paster \
26 $ rccontrol ishell enterprise-1
26 ishell .rccontrol/enterprise-1/rhodecode.ini
27
27
28 .. code-block:: mysql
28 .. code-block:: mysql
29
29
@@ -33,6 +33,7 b' account permissions.'
33 In [3]: Session().add(adminuser);Session().commit()
33 In [3]: Session().add(adminuser);Session().commit()
34 In [4]: exit()
34 In [4]: exit()
35
35
36
36 Set to read global ``.hgrc`` file
37 Set to read global ``.hgrc`` file
37 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
38 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
38
39
@@ -46,8 +47,7 b' following example to make changes to thi'
46 .. code-block:: bash
47 .. code-block:: bash
47
48
48 # Open iShell from the terminal
49 # Open iShell from the terminal
49 $ .rccontrol/enterprise-5/profile/bin/paster \
50 $ rccontrol ishell enterprise-1
50 ishell.rccontrol/enterprise-5/rhodecode.ini
51
51
52 .. code-block:: mysql
52 .. code-block:: mysql
53
53
@@ -59,6 +59,7 b' following example to make changes to thi'
59 In [5]: Session().add(new_option);Session().commit()
59 In [5]: Session().add(new_option);Session().commit()
60 In [6]: exit()
60 In [6]: exit()
61
61
62
62 Manually Reset Password
63 Manually Reset Password
63 ^^^^^^^^^^^^^^^^^^^^^^^
64 ^^^^^^^^^^^^^^^^^^^^^^^
64
65
@@ -73,8 +74,7 b' Use the following code example to carry '
73 .. code-block:: bash
74 .. code-block:: bash
74
75
75 # starts the ishell interactive prompt
76 # starts the ishell interactive prompt
76 $ .rccontrol/enterprise-1/profile/bin/paster \
77 $ rccontrol ishell enterprise-1
77 ishell .rccontrol/enterprise-1/rhodecode.ini
78
78
79 .. code-block:: mysql
79 .. code-block:: mysql
80
80
@@ -91,7 +91,6 b' Use the following code example to carry '
91 In [8]: exit()
91 In [8]: exit()
92
92
93
93
94
95 Change user details
94 Change user details
96 ^^^^^^^^^^^^^^^^^^^
95 ^^^^^^^^^^^^^^^^^^^
97
96
@@ -106,8 +105,7 b' Use the following code example to carry '
106 .. code-block:: bash
105 .. code-block:: bash
107
106
108 # starts the ishell interactive prompt
107 # starts the ishell interactive prompt
109 $ .rccontrol/enterprise-1/profile/bin/paster \
108 $ rccontrol ishell enterprise-1
110 ishell .rccontrol/enterprise-1/rhodecode.ini
111
109
112 .. code-block:: mysql
110 .. code-block:: mysql
113
111
@@ -117,3 +115,37 b' Use the following code example to carry '
117 In [3]: my_user.username = 'SomeUser'
115 In [3]: my_user.username = 'SomeUser'
118 In [4]: Session().add(my_user);Session().commit()
116 In [4]: Session().add(my_user);Session().commit()
119 In [5]: exit()
117 In [5]: exit()
118
119
120 Change user login type
121 ^^^^^^^^^^^^^^^^^^^^^^
122
123 Sometimes it's required to change account type from RhodeCode to LDAP or
124 other external authentication type.
125 If you need to manually change the method of login, use the following steps.
126
127 1. Navigate to your |RCE| install location.
128 2. Run the interactive ``ishell`` prompt.
129 3. Set a new arguments for users.
130
131 Use the following code example to carry out these steps.
132 Available values for new_extern_type can be found when browsing available
133 authentication types in RhodeCode admin interface for authentication.
134 Use the text which is shown after '#' sign, eg.
135 ` LDAP (egg:rhodecode-enterprise-ce#ldap)` it's type is 'ldap'
136
137 .. code-block:: bash
138
139 # starts the ishell interactive prompt
140 $ rccontrol ishell enterprise-1
141
142 .. code-block:: mysql
143
144 # Use this example to change users from authentication
145 # using rhodecode internal to ldap
146 In [1]: new_extern_type = 'ldap'
147 In [2]: my_user = User.get_by_username('some_username')
148 In [3]: my_user.extern_type = new_extern_type
149 In [4]: my_user.extern_name = new_extern_type
150 In [5]: Session().add(my_user);Session().commit()
151 In [6]: exit()
@@ -27,6 +27,7 b' Once installed you need to enable ``dav_'
27
27
28 $ sudo a2enmod dav_svn
28 $ sudo a2enmod dav_svn
29 $ sudo a2enmod headers
29 $ sudo a2enmod headers
30 $ sudo a2enmod authn_anon
30
31
31
32
32 Configuring Apache Setup
33 Configuring Apache Setup
@@ -55,7 +56,7 b' permission issues could occur. To do thi'
55 export APACHE_RUN_GROUP=rhodecode
56 export APACHE_RUN_GROUP=rhodecode
56
57
57 1. To configure Apache, create and edit a virtual hosts file, for example
58 1. To configure Apache, create and edit a virtual hosts file, for example
58 :file:`/etc/apache2/sites-available/default.conf`. Below is an example
59 :file:`/etc/apache2/sites-enabled/default.conf`. Below is an example
59 how to use one with auto-generated config ```mod_dav_svn.conf```
60 how to use one with auto-generated config ```mod_dav_svn.conf```
60 from configured |RCE| instance.
61 from configured |RCE| instance.
61
62
@@ -13,7 +13,7 b' 1. Open ishell from the terminal and use'
13 .. code-block:: bash
13 .. code-block:: bash
14
14
15 # Open iShell from the terminal and set ini file
15 # Open iShell from the terminal and set ini file
16 $ .rccontrol/enterprise-1/profile/bin/paster ishell .rccontrol/enterprise-1/rhodecode.ini
16 $ rccontrol ishell enterprise-1
17
17
18 2. Run the following commands, and ensure that |RCE| has write access to the
18 2. Run the following commands, and ensure that |RCE| has write access to the
19 new directory:
19 new directory:
@@ -3,21 +3,6 b''
3 Increase Database Performance
3 Increase Database Performance
4 -----------------------------
4 -----------------------------
5
5
6 To increase database performance switch to database-based user sessions.
6 For tuning PostgreSQL we recommend reading: http://www.revsys.com/writings/postgresql-performance.html
7 File-based sessions are only suitable for smaller setups. The most common
8 issue being file limit errors which occur if there are lots of session files.
9 Therefore, in a large scale deployment, to give better performance,
10 scalability, and maintainability we recommend switching from file-based
11 sessions to database-based user sessions.
12
7
13 To switch to database-based user sessions uncomment the following section in
8 For tuning MySQL we recommend reading: http://www.tecmint.com/mysql-mariadb-performance-tuning-and-optimization/ No newline at end of file
14 your :file:`/home/{user}/.rccontrol/{instance-id}/rhodecode.ini` file.
15
16 .. code-block:: ini
17
18 # db session
19 beaker.session.type = ext:database
20
21 # adjust this property to include your database credentials
22 beaker.session.sa.url = postgresql://postgres:<pass>@localhost/rhodecode
23 beaker.session.table_name = db_session
@@ -34,8 +34,8 b' performance boost.'
34
34
35 .. code-block:: bash
35 .. code-block:: bash
36
36
37 # mount tmp to memory with 2GB limit and 755 write permissions
37 # mount tmp to memory with 2GB limit and 1777 write permissions
38 mount -t tmpfs -o size=2G,mode=0755 tmpfs /tmp
38 mount -t tmpfs -o size=2G,mode=1777 tmpfs /tmp
39
39
40 For more information about TMPFS, see the documentation `here`_.
40 For more information about TMPFS, see the documentation `here`_.
41
41
@@ -10,6 +10,7 b' may find some of the following methods u'
10
10
11 tuning-gunicorn
11 tuning-gunicorn
12 tuning-vcs-memory-cache
12 tuning-vcs-memory-cache
13 tuning-user-sessions-performance
13 tuning-increase-db-performance
14 tuning-increase-db-performance
14 tuning-scale-horizontally
15 tuning-scale-horizontally
15 tuning-increase-cache-size
16 tuning-increase-cache-size
@@ -36,7 +36,7 b' close_pull_request'
36 comment_pull_request
36 comment_pull_request
37 --------------------
37 --------------------
38
38
39 .. py:function:: comment_pull_request(apiuser, repoid, pullrequestid, message=<Optional:None>, status=<Optional:None>, userid=<Optional:<OptionalAttr:apiuser>>)
39 .. py:function:: comment_pull_request(apiuser, repoid, pullrequestid, message=<Optional:None>, commit_id=<Optional:None>, status=<Optional:None>, comment_type=<Optional:u'note'>, resolves_comment_id=<Optional:None>, userid=<Optional:<OptionalAttr:apiuser>>)
40
40
41 Comment on the pull request specified with the `pullrequestid`,
41 Comment on the pull request specified with the `pullrequestid`,
42 in the |repo| specified by the `repoid`, and optionally change the
42 in the |repo| specified by the `repoid`, and optionally change the
@@ -48,15 +48,18 b' comment_pull_request'
48 :type repoid: str or int
48 :type repoid: str or int
49 :param pullrequestid: The pull request ID.
49 :param pullrequestid: The pull request ID.
50 :type pullrequestid: int
50 :type pullrequestid: int
51 :param commit_id: Specify the commit_id for which to set a comment. If
52 given commit_id is different than latest in the PR status
53 change won't be performed.
54 :type commit_id: str
51 :param message: The text content of the comment.
55 :param message: The text content of the comment.
52 :type message: str
56 :type message: str
53 :param status: (**Optional**) Set the approval status of the pull
57 :param status: (**Optional**) Set the approval status of the pull
54 request. Valid options are:
58 request. One of: 'not_reviewed', 'approved', 'rejected',
55 * not_reviewed
59 'under_review'
56 * approved
57 * rejected
58 * under_review
59 :type status: str
60 :type status: str
61 :param comment_type: Comment type, one of: 'note', 'todo'
62 :type comment_type: Optional(str), default: 'note'
60 :param userid: Comment on the pull request as this user
63 :param userid: Comment on the pull request as this user
61 :type userid: Optional(str or int)
64 :type userid: Optional(str or int)
62
65
@@ -68,7 +71,9 b' comment_pull_request'
68 result :
71 result :
69 {
72 {
70 "pull_request_id": "<Integer>",
73 "pull_request_id": "<Integer>",
71 "comment_id": "<Integer>"
74 "comment_id": "<Integer>",
75 "status": {"given": <given_status>,
76 "was_changed": <bool status_was_actually_changed> },
72 }
77 }
73 error : null
78 error : null
74
79
@@ -28,7 +28,7 b' add_field_to_repo'
28 comment_commit
28 comment_commit
29 --------------
29 --------------
30
30
31 .. py:function:: comment_commit(apiuser, repoid, commit_id, message, userid=<Optional:<OptionalAttr:apiuser>>, status=<Optional:None>)
31 .. py:function:: comment_commit(apiuser, repoid, commit_id, message, status=<Optional:None>, comment_type=<Optional:u'note'>, resolves_comment_id=<Optional:None>, userid=<Optional:<OptionalAttr:apiuser>>)
32
32
33 Set a commit comment, and optionally change the status of the commit.
33 Set a commit comment, and optionally change the status of the commit.
34
34
@@ -40,15 +40,17 b' comment_commit'
40 :type commit_id: str
40 :type commit_id: str
41 :param message: The comment text.
41 :param message: The comment text.
42 :type message: str
42 :type message: str
43 :param status: (**Optional**) status of commit, one of: 'not_reviewed',
44 'approved', 'rejected', 'under_review'
45 :type status: str
46 :param comment_type: Comment type, one of: 'note', 'todo'
47 :type comment_type: Optional(str), default: 'note'
43 :param userid: Set the user name of the comment creator.
48 :param userid: Set the user name of the comment creator.
44 :type userid: Optional(str or int)
49 :type userid: Optional(str or int)
45 :param status: status, one of 'not_reviewed', 'approved', 'rejected',
46 'under_review'
47 :type status: str
48
50
49 Example error output:
51 Example error output:
50
52
51 .. code-block:: json
53 .. code-block:: bash
52
54
53 {
55 {
54 "id" : <id_given_in_input>,
56 "id" : <id_given_in_input>,
@@ -539,7 +541,7 b' get_repo_settings'
539 get_repos
541 get_repos
540 ---------
542 ---------
541
543
542 .. py:function:: get_repos(apiuser)
544 .. py:function:: get_repos(apiuser, root=<Optional:None>, traverse=<Optional:True>)
543
545
544 Lists all existing repositories.
546 Lists all existing repositories.
545
547
@@ -548,6 +550,14 b' get_repos'
548
550
549 :param apiuser: This is filled automatically from the |authtoken|.
551 :param apiuser: This is filled automatically from the |authtoken|.
550 :type apiuser: AuthUser
552 :type apiuser: AuthUser
553 :param root: specify root repository group to fetch repositories.
554 filters the returned repositories to be members of given root group.
555 :type root: Optional(None)
556 :param traverse: traverse given root into subrepositories. With this flag
557 set to False, it will only return top-level repositories from `root`.
558 if root is empty it will return just top-level repositories.
559 :type traverse: Optional(True)
560
551
561
552 Example output:
562 Example output:
553
563
@@ -3,6 +3,49 b''
3 server methods
3 server methods
4 ==============
4 ==============
5
5
6 cleanup_sessions
7 ----------------
8
9 .. py:function:: cleanup_sessions(apiuser, older_then=<Optional:60>)
10
11 Triggers a session cleanup action.
12
13 If the ``older_then`` option is set, only sessions that hasn't been
14 accessed in the given number of days will be removed.
15
16 This command can only be run using an |authtoken| with admin rights to
17 the specified repository.
18
19 This command takes the following options:
20
21 :param apiuser: This is filled automatically from the |authtoken|.
22 :type apiuser: AuthUser
23 :param older_then: Deletes session that hasn't been accessed
24 in given number of days.
25 :type older_then: Optional(int)
26
27 Example output:
28
29 .. code-block:: bash
30
31 id : <id_given_in_input>
32 result: {
33 "backend": "<type of backend>",
34 "sessions_removed": <number_of_removed_sessions>
35 }
36 error : null
37
38 Example error output:
39
40 .. code-block:: bash
41
42 id : <id_given_in_input>
43 result : null
44 error : {
45 'Error occurred during session cleanup'
46 }
47
48
6 get_ip
49 get_ip
7 ------
50 ------
8
51
@@ -47,6 +47,17 b' Followed by::'
47 nix-channel --update
47 nix-channel --update
48
48
49
49
50 Install required binaries
51 -------------------------
52
53 We need some handy tools first.
54
55 run::
56
57 nix-env -i nix-prefetch-hg
58 nix-env -i nix-prefetch-git
59
60
50 Clone the required repositories
61 Clone the required repositories
51 -------------------------------
62 -------------------------------
52
63
@@ -64,6 +75,21 b' To do this, use the following example::'
64 via support@rhodecode.com
75 via support@rhodecode.com
65
76
66
77
78 Install some required libraries
79 -------------------------------
80
81 There are some required drivers that we need to install to test RhodeCode
82 under different types of databases. For example in Ubuntu we need to install
83 the following.
84
85 required libraries::
86
87 sudo apt-get install libapr1-dev libaprutil1-dev
88 sudo apt-get install libsvn-dev
89 sudo apt-get install mysql-server libmysqlclient-dev
90 sudo apt-get install postgresql postgresql-contrib libpq-dev
91 sudo apt-get install libcurl4-openssl-dev
92
67
93
68 Enter the Development Shell
94 Enter the Development Shell
69 ---------------------------
95 ---------------------------
@@ -9,6 +9,7 b' Release Notes'
9 .. toctree::
9 .. toctree::
10 :maxdepth: 1
10 :maxdepth: 1
11
11
12 release-notes-4.6.0.rst
12 release-notes-4.5.2.rst
13 release-notes-4.5.2.rst
13 release-notes-4.5.1.rst
14 release-notes-4.5.1.rst
14 release-notes-4.5.0.rst
15 release-notes-4.5.0.rst
@@ -68,6 +68,7 b''
68 "<%= dirs.js.src %>/rhodecode/utils/os.js",
68 "<%= dirs.js.src %>/rhodecode/utils/os.js",
69 "<%= dirs.js.src %>/rhodecode/utils/topics.js",
69 "<%= dirs.js.src %>/rhodecode/utils/topics.js",
70 "<%= dirs.js.src %>/rhodecode/init.js",
70 "<%= dirs.js.src %>/rhodecode/init.js",
71 "<%= dirs.js.src %>/rhodecode/changelog.js",
71 "<%= dirs.js.src %>/rhodecode/codemirror.js",
72 "<%= dirs.js.src %>/rhodecode/codemirror.js",
72 "<%= dirs.js.src %>/rhodecode/comments.js",
73 "<%= dirs.js.src %>/rhodecode/comments.js",
73 "<%= dirs.js.src %>/rhodecode/constants.js",
74 "<%= dirs.js.src %>/rhodecode/constants.js",
@@ -100,11 +100,7 b' self: super: {'
100 });
100 });
101
101
102 py-gfm = super.py-gfm.override {
102 py-gfm = super.py-gfm.override {
103 src = pkgs.fetchgit {
103 name = "py-gfm-0.1.3.rhodecode-upstream1";
104 url = "https://code.rhodecode.com/upstream/py-gfm";
105 rev = "0d66a19bc16e3d49de273c0f797d4e4781e8c0f2";
106 sha256 = "0ryp74jyihd3ckszq31bml5jr3bciimhfp7va7kw6ld92930ksv3";
107 };
108 };
104 };
109
105
110 pycurl = super.pycurl.override (attrs: {
106 pycurl = super.pycurl.override (attrs: {
@@ -123,12 +119,7 b' self: super: {'
123 });
119 });
124
120
125 Pylons = super.Pylons.override (attrs: {
121 Pylons = super.Pylons.override (attrs: {
126 name = "Pylons-1.0.1-patch1";
122 name = "Pylons-1.0.2.rhodecode-patch1";
127 src = pkgs.fetchgit {
128 url = "https://code.rhodecode.com/upstream/pylons";
129 rev = "707354ee4261b9c10450404fc9852ccea4fd667d";
130 sha256 = "b2763274c2780523a335f83a1df65be22ebe4ff413a7bc9e9288d23c1f62032e";
131 };
132 });
123 });
133
124
134 pyramid = super.pyramid.override (attrs: {
125 pyramid = super.pyramid.override (attrs: {
@@ -149,16 +140,6 b' self: super: {'
149 };
140 };
150 });
141 });
151
142
152 Pyro4 = super.Pyro4.override (attrs: {
153 # TODO: Was not able to generate this version, needs further
154 # investigation.
155 name = "Pyro4-4.35";
156 src = pkgs.fetchurl {
157 url = "https://pypi.python.org/packages/source/P/Pyro4/Pyro4-4.35.src.tar.gz";
158 md5 = "cbe6cb855f086a0f092ca075005855f3";
159 };
160 });
161
162 pysqlite = super.pysqlite.override (attrs: {
143 pysqlite = super.pysqlite.override (attrs: {
163 propagatedBuildInputs = [
144 propagatedBuildInputs = [
164 pkgs.sqlite
145 pkgs.sqlite
@@ -202,12 +183,6 b' self: super: {'
202 '';
183 '';
203 });
184 });
204
185
205 rhodecode-tools = super.rhodecode-tools.override (attrs: {
206 patches = [
207 ./patch-rhodecode-tools-setup.diff
208 ];
209 });
210
211 URLObject = super.URLObject.override (attrs: {
186 URLObject = super.URLObject.override (attrs: {
212 meta = {
187 meta = {
213 license = {
188 license = {
@@ -81,26 +81,26 b''
81 };
81 };
82 };
82 };
83 Mako = super.buildPythonPackage {
83 Mako = super.buildPythonPackage {
84 name = "Mako-1.0.1";
84 name = "Mako-1.0.6";
85 buildInputs = with self; [];
85 buildInputs = with self; [];
86 doCheck = false;
86 doCheck = false;
87 propagatedBuildInputs = with self; [MarkupSafe];
87 propagatedBuildInputs = with self; [MarkupSafe];
88 src = fetchurl {
88 src = fetchurl {
89 url = "https://pypi.python.org/packages/8e/a4/aa56533ecaa5f22ca92428f74e074d0c9337282933c722391902c8f9e0f8/Mako-1.0.1.tar.gz";
89 url = "https://pypi.python.org/packages/56/4b/cb75836863a6382199aefb3d3809937e21fa4cb0db15a4f4ba0ecc2e7e8e/Mako-1.0.6.tar.gz";
90 md5 = "9f0aafd177b039ef67b90ea350497a54";
90 md5 = "a28e22a339080316b2acc352b9ee631c";
91 };
91 };
92 meta = {
92 meta = {
93 license = [ pkgs.lib.licenses.mit ];
93 license = [ pkgs.lib.licenses.mit ];
94 };
94 };
95 };
95 };
96 Markdown = super.buildPythonPackage {
96 Markdown = super.buildPythonPackage {
97 name = "Markdown-2.6.2";
97 name = "Markdown-2.6.7";
98 buildInputs = with self; [];
98 buildInputs = with self; [];
99 doCheck = false;
99 doCheck = false;
100 propagatedBuildInputs = with self; [];
100 propagatedBuildInputs = with self; [];
101 src = fetchurl {
101 src = fetchurl {
102 url = "https://pypi.python.org/packages/62/8b/83658b5f6c220d5fcde9f9852d46ea54765d734cfbc5a9f4c05bfc36db4d/Markdown-2.6.2.tar.gz";
102 url = "https://pypi.python.org/packages/48/a4/fc6b002789c2239ac620ca963694c95b8f74e4747769cdf6021276939e74/Markdown-2.6.7.zip";
103 md5 = "256d19afcc564dc4ce4c229bb762f7ae";
103 md5 = "632710a7474bbb74a82084392251061f";
104 };
104 };
105 meta = {
105 meta = {
106 license = [ pkgs.lib.licenses.bsdOriginal ];
106 license = [ pkgs.lib.licenses.bsdOriginal ];
@@ -133,13 +133,13 b''
133 };
133 };
134 };
134 };
135 Paste = super.buildPythonPackage {
135 Paste = super.buildPythonPackage {
136 name = "Paste-2.0.2";
136 name = "Paste-2.0.3";
137 buildInputs = with self; [];
137 buildInputs = with self; [];
138 doCheck = false;
138 doCheck = false;
139 propagatedBuildInputs = with self; [six];
139 propagatedBuildInputs = with self; [six];
140 src = fetchurl {
140 src = fetchurl {
141 url = "https://pypi.python.org/packages/d5/8d/0f8ac40687b97ff3e07ebd1369be20bdb3f93864d2dc3c2ff542edb4ce50/Paste-2.0.2.tar.gz";
141 url = "https://pypi.python.org/packages/30/c3/5c2f7c7a02e4f58d4454353fa1c32c94f79fa4e36d07a67c0ac295ea369e/Paste-2.0.3.tar.gz";
142 md5 = "4bfc8a7eaf858f6309d2ac0f40fc951c";
142 md5 = "1231e14eae62fa7ed76e9130b04bc61e";
143 };
143 };
144 meta = {
144 meta = {
145 license = [ pkgs.lib.licenses.mit ];
145 license = [ pkgs.lib.licenses.mit ];
@@ -172,26 +172,26 b''
172 };
172 };
173 };
173 };
174 Pygments = super.buildPythonPackage {
174 Pygments = super.buildPythonPackage {
175 name = "Pygments-2.1.3";
175 name = "Pygments-2.2.0";
176 buildInputs = with self; [];
176 buildInputs = with self; [];
177 doCheck = false;
177 doCheck = false;
178 propagatedBuildInputs = with self; [];
178 propagatedBuildInputs = with self; [];
179 src = fetchurl {
179 src = fetchurl {
180 url = "https://pypi.python.org/packages/b8/67/ab177979be1c81bc99c8d0592ef22d547e70bb4c6815c383286ed5dec504/Pygments-2.1.3.tar.gz";
180 url = "https://pypi.python.org/packages/71/2a/2e4e77803a8bd6408a2903340ac498cb0a2181811af7c9ec92cb70b0308a/Pygments-2.2.0.tar.gz";
181 md5 = "ed3fba2467c8afcda4d317e4ef2c6150";
181 md5 = "13037baca42f16917cbd5ad2fab50844";
182 };
182 };
183 meta = {
183 meta = {
184 license = [ pkgs.lib.licenses.bsdOriginal ];
184 license = [ pkgs.lib.licenses.bsdOriginal ];
185 };
185 };
186 };
186 };
187 Pylons = super.buildPythonPackage {
187 Pylons = super.buildPythonPackage {
188 name = "Pylons-1.0.1";
188 name = "Pylons-1.0.2.dev20161213";
189 buildInputs = with self; [];
189 buildInputs = with self; [];
190 doCheck = false;
190 doCheck = false;
191 propagatedBuildInputs = with self; [Routes WebHelpers Beaker Paste PasteDeploy PasteScript FormEncode simplejson decorator nose Mako WebError WebTest Tempita MarkupSafe WebOb];
191 propagatedBuildInputs = with self; [Routes WebHelpers Beaker Paste PasteDeploy PasteScript FormEncode simplejson decorator nose Mako WebError WebTest Tempita MarkupSafe WebOb];
192 src = fetchurl {
192 src = fetchurl {
193 url = "https://pypi.python.org/packages/a2/69/b835a6bad00acbfeed3f33c6e44fa3f936efc998c795bfb15c61a79ecf62/Pylons-1.0.1.tar.gz";
193 url = "https://code.rhodecode.com/upstream/pylons/archive/707354ee4261b9c10450404fc9852ccea4fd667d.tar.gz?md5=f26633726fa2cd3a340316ee6a5d218f";
194 md5 = "6cb880d75fa81213192142b07a6e4915";
194 md5 = "f26633726fa2cd3a340316ee6a5d218f";
195 };
195 };
196 meta = {
196 meta = {
197 license = [ pkgs.lib.licenses.bsdOriginal ];
197 license = [ pkgs.lib.licenses.bsdOriginal ];
@@ -341,13 +341,13 b''
341 };
341 };
342 };
342 };
343 Whoosh = super.buildPythonPackage {
343 Whoosh = super.buildPythonPackage {
344 name = "Whoosh-2.7.0";
344 name = "Whoosh-2.7.4";
345 buildInputs = with self; [];
345 buildInputs = with self; [];
346 doCheck = false;
346 doCheck = false;
347 propagatedBuildInputs = with self; [];
347 propagatedBuildInputs = with self; [];
348 src = fetchurl {
348 src = fetchurl {
349 url = "https://pypi.python.org/packages/1c/dc/2f0231ff3875ded36df8c1ab851451e51a237dc0e5a86d3d96036158da94/Whoosh-2.7.0.zip";
349 url = "https://pypi.python.org/packages/25/2b/6beed2107b148edc1321da0d489afc4617b9ed317ef7b72d4993cad9b684/Whoosh-2.7.4.tar.gz";
350 md5 = "7abfd970f16fadc7311960f3fa0bc7a9";
350 md5 = "c2710105f20b3e29936bd2357383c325";
351 };
351 };
352 meta = {
352 meta = {
353 license = [ pkgs.lib.licenses.bsdOriginal pkgs.lib.licenses.bsd2 ];
353 license = [ pkgs.lib.licenses.bsdOriginal pkgs.lib.licenses.bsd2 ];
@@ -639,19 +639,6 b''
639 license = [ pkgs.lib.licenses.bsdOriginal ];
639 license = [ pkgs.lib.licenses.bsdOriginal ];
640 };
640 };
641 };
641 };
642 dulwich = super.buildPythonPackage {
643 name = "dulwich-0.12.0";
644 buildInputs = with self; [];
645 doCheck = false;
646 propagatedBuildInputs = with self; [];
647 src = fetchurl {
648 url = "https://pypi.python.org/packages/6f/04/fbe561b6d45c0ec758330d5b7f5ba4b6cb4f1ca1ab49859d2fc16320da75/dulwich-0.12.0.tar.gz";
649 md5 = "f3a8a12bd9f9dd8c233e18f3d49436fa";
650 };
651 meta = {
652 license = [ pkgs.lib.licenses.gpl2Plus ];
653 };
654 };
655 ecdsa = super.buildPythonPackage {
642 ecdsa = super.buildPythonPackage {
656 name = "ecdsa-0.11";
643 name = "ecdsa-0.11";
657 buildInputs = with self; [];
644 buildInputs = with self; [];
@@ -679,13 +666,13 b''
679 };
666 };
680 };
667 };
681 elasticsearch-dsl = super.buildPythonPackage {
668 elasticsearch-dsl = super.buildPythonPackage {
682 name = "elasticsearch-dsl-2.0.0";
669 name = "elasticsearch-dsl-2.2.0";
683 buildInputs = with self; [];
670 buildInputs = with self; [];
684 doCheck = false;
671 doCheck = false;
685 propagatedBuildInputs = with self; [six python-dateutil elasticsearch];
672 propagatedBuildInputs = with self; [six python-dateutil elasticsearch];
686 src = fetchurl {
673 src = fetchurl {
687 url = "https://pypi.python.org/packages/4e/5d/e788ae8dbe2ff4d13426db0a027533386a5c276c77a2654dc0e2007ce04a/elasticsearch-dsl-2.0.0.tar.gz";
674 url = "https://pypi.python.org/packages/66/2f/52a086968788e58461641570f45c3207a52d46ebbe9b77dc22b6a8ffda66/elasticsearch-dsl-2.2.0.tar.gz";
688 md5 = "4cdfec81bb35383dd3b7d02d7dc5ee68";
675 md5 = "fa6bd3c87ea3caa8f0f051bc37c53221";
689 };
676 };
690 meta = {
677 meta = {
691 license = [ pkgs.lib.licenses.asl20 ];
678 license = [ pkgs.lib.licenses.asl20 ];
@@ -731,13 +718,13 b''
731 };
718 };
732 };
719 };
733 gevent = super.buildPythonPackage {
720 gevent = super.buildPythonPackage {
734 name = "gevent-1.1.1";
721 name = "gevent-1.1.2";
735 buildInputs = with self; [];
722 buildInputs = with self; [];
736 doCheck = false;
723 doCheck = false;
737 propagatedBuildInputs = with self; [greenlet];
724 propagatedBuildInputs = with self; [greenlet];
738 src = fetchurl {
725 src = fetchurl {
739 url = "https://pypi.python.org/packages/12/dc/0b2e57823225de86f6e111a65d212c9e3b64847dddaa19691a6cb94b0b2e/gevent-1.1.1.tar.gz";
726 url = "https://pypi.python.org/packages/43/8f/cb3224a0e6ab663547f45c10d0651cfd52633fde4283bf68d627084df8cc/gevent-1.1.2.tar.gz";
740 md5 = "1532f5396ab4d07a231f1935483be7c3";
727 md5 = "bb32a2f852a4997138014d5007215c6e";
741 };
728 };
742 meta = {
729 meta = {
743 license = [ pkgs.lib.licenses.mit ];
730 license = [ pkgs.lib.licenses.mit ];
@@ -757,26 +744,26 b''
757 };
744 };
758 };
745 };
759 gprof2dot = super.buildPythonPackage {
746 gprof2dot = super.buildPythonPackage {
760 name = "gprof2dot-2015.12.1";
747 name = "gprof2dot-2016.10.13";
761 buildInputs = with self; [];
748 buildInputs = with self; [];
762 doCheck = false;
749 doCheck = false;
763 propagatedBuildInputs = with self; [];
750 propagatedBuildInputs = with self; [];
764 src = fetchurl {
751 src = fetchurl {
765 url = "https://pypi.python.org/packages/b9/34/7bf93c1952d40fa5c95ad963f4d8344b61ef58558632402eca18e6c14127/gprof2dot-2015.12.1.tar.gz";
752 url = "https://pypi.python.org/packages/a0/e0/73c71baed306f0402a00a94ffc7b2be94ad1296dfcb8b46912655b93154c/gprof2dot-2016.10.13.tar.gz";
766 md5 = "e23bf4e2f94db032750c193384b4165b";
753 md5 = "0125401f15fd2afe1df686a76c64a4fd";
767 };
754 };
768 meta = {
755 meta = {
769 license = [ { fullName = "LGPL"; } ];
756 license = [ { fullName = "LGPL"; } ];
770 };
757 };
771 };
758 };
772 greenlet = super.buildPythonPackage {
759 greenlet = super.buildPythonPackage {
773 name = "greenlet-0.4.9";
760 name = "greenlet-0.4.10";
774 buildInputs = with self; [];
761 buildInputs = with self; [];
775 doCheck = false;
762 doCheck = false;
776 propagatedBuildInputs = with self; [];
763 propagatedBuildInputs = with self; [];
777 src = fetchurl {
764 src = fetchurl {
778 url = "https://pypi.python.org/packages/4e/3d/9d421539b74e33608b245092870156b2e171fb49f2b51390aa4641eecb4a/greenlet-0.4.9.zip";
765 url = "https://pypi.python.org/packages/67/62/ca2a95648666eaa2ffeb6a9b3964f21d419ae27f82f2e66b53da5b943fc4/greenlet-0.4.10.zip";
779 md5 = "c6659cdb2a5e591723e629d2eef22e82";
766 md5 = "bed0c4b3b896702131f4d5c72f87c41d";
780 };
767 };
781 meta = {
768 meta = {
782 license = [ pkgs.lib.licenses.mit ];
769 license = [ pkgs.lib.licenses.mit ];
@@ -939,13 +926,13 b''
939 };
926 };
940 };
927 };
941 msgpack-python = super.buildPythonPackage {
928 msgpack-python = super.buildPythonPackage {
942 name = "msgpack-python-0.4.6";
929 name = "msgpack-python-0.4.8";
943 buildInputs = with self; [];
930 buildInputs = with self; [];
944 doCheck = false;
931 doCheck = false;
945 propagatedBuildInputs = with self; [];
932 propagatedBuildInputs = with self; [];
946 src = fetchurl {
933 src = fetchurl {
947 url = "https://pypi.python.org/packages/15/ce/ff2840885789ef8035f66cd506ea05bdb228340307d5e71a7b1e3f82224c/msgpack-python-0.4.6.tar.gz";
934 url = "https://pypi.python.org/packages/21/27/8a1d82041c7a2a51fcc73675875a5f9ea06c2663e02fcfeb708be1d081a0/msgpack-python-0.4.8.tar.gz";
948 md5 = "8b317669314cf1bc881716cccdaccb30";
935 md5 = "dcd854fb41ee7584ebbf35e049e6be98";
949 };
936 };
950 meta = {
937 meta = {
951 license = [ pkgs.lib.licenses.asl20 ];
938 license = [ pkgs.lib.licenses.asl20 ];
@@ -1108,13 +1095,13 b''
1108 };
1095 };
1109 };
1096 };
1110 py = super.buildPythonPackage {
1097 py = super.buildPythonPackage {
1111 name = "py-1.4.29";
1098 name = "py-1.4.31";
1112 buildInputs = with self; [];
1099 buildInputs = with self; [];
1113 doCheck = false;
1100 doCheck = false;
1114 propagatedBuildInputs = with self; [];
1101 propagatedBuildInputs = with self; [];
1115 src = fetchurl {
1102 src = fetchurl {
1116 url = "https://pypi.python.org/packages/2a/bc/a1a4a332ac10069b8e5e25136a35e08a03f01fd6ab03d819889d79a1fd65/py-1.4.29.tar.gz";
1103 url = "https://pypi.python.org/packages/f4/9a/8dfda23f36600dd701c6722316ba8a3ab4b990261f83e7d3ffc6dfedf7ef/py-1.4.31.tar.gz";
1117 md5 = "c28e0accba523a29b35a48bb703fb96c";
1104 md5 = "5d2c63c56dc3f2115ec35c066ecd582b";
1118 };
1105 };
1119 meta = {
1106 meta = {
1120 license = [ pkgs.lib.licenses.mit ];
1107 license = [ pkgs.lib.licenses.mit ];
@@ -1139,8 +1126,8 b''
1139 doCheck = false;
1126 doCheck = false;
1140 propagatedBuildInputs = with self; [setuptools Markdown];
1127 propagatedBuildInputs = with self; [setuptools Markdown];
1141 src = fetchurl {
1128 src = fetchurl {
1142 url = "https://pypi.python.org/packages/12/e4/6b3d8678da04f97d7490d8264d8de51c2dc9fb91209ccee9c515c95e14c5/py-gfm-0.1.3.tar.gz";
1129 url = "https://code.rhodecode.com/upstream/py-gfm/archive/0d66a19bc16e3d49de273c0f797d4e4781e8c0f2.tar.gz?md5=0d0d5385bfb629eea636a80b9c2bfd16";
1143 md5 = "e588d9e69640a241b97e2c59c22527a6";
1130 md5 = "0d0d5385bfb629eea636a80b9c2bfd16";
1144 };
1131 };
1145 meta = {
1132 meta = {
1146 license = [ pkgs.lib.licenses.bsdOriginal ];
1133 license = [ pkgs.lib.licenses.bsdOriginal ];
@@ -1290,13 +1277,13 b''
1290 };
1277 };
1291 };
1278 };
1292 pytest = super.buildPythonPackage {
1279 pytest = super.buildPythonPackage {
1293 name = "pytest-2.8.5";
1280 name = "pytest-3.0.5";
1294 buildInputs = with self; [];
1281 buildInputs = with self; [];
1295 doCheck = false;
1282 doCheck = false;
1296 propagatedBuildInputs = with self; [py];
1283 propagatedBuildInputs = with self; [py];
1297 src = fetchurl {
1284 src = fetchurl {
1298 url = "https://pypi.python.org/packages/b1/3d/d7ea9b0c51e0cacded856e49859f0a13452747491e842c236bbab3714afe/pytest-2.8.5.zip";
1285 url = "https://pypi.python.org/packages/a8/87/b7ca49efe52d2b4169f2bfc49aa5e384173c4619ea8e635f123a0dac5b75/pytest-3.0.5.tar.gz";
1299 md5 = "8493b06f700862f1294298d6c1b715a9";
1286 md5 = "cefd527b59332688bf5db4a10aa8a7cb";
1300 };
1287 };
1301 meta = {
1288 meta = {
1302 license = [ pkgs.lib.licenses.mit ];
1289 license = [ pkgs.lib.licenses.mit ];
@@ -1316,52 +1303,65 b''
1316 };
1303 };
1317 };
1304 };
1318 pytest-cov = super.buildPythonPackage {
1305 pytest-cov = super.buildPythonPackage {
1319 name = "pytest-cov-1.8.1";
1306 name = "pytest-cov-2.4.0";
1320 buildInputs = with self; [];
1307 buildInputs = with self; [];
1321 doCheck = false;
1308 doCheck = false;
1322 propagatedBuildInputs = with self; [py pytest coverage cov-core];
1309 propagatedBuildInputs = with self; [pytest coverage];
1323 src = fetchurl {
1310 src = fetchurl {
1324 url = "https://pypi.python.org/packages/11/4b/b04646e97f1721878eb21e9f779102d84dd044d324382263b1770a3e4838/pytest-cov-1.8.1.tar.gz";
1311 url = "https://pypi.python.org/packages/00/c0/2bfd1fcdb9d407b8ac8185b1cb5ff458105c6b207a9a7f0e13032de9828f/pytest-cov-2.4.0.tar.gz";
1325 md5 = "76c778afa2494088270348be42d759fc";
1312 md5 = "2fda09677d232acc99ec1b3c5831e33f";
1326 };
1313 };
1327 meta = {
1314 meta = {
1328 license = [ pkgs.lib.licenses.mit ];
1315 license = [ pkgs.lib.licenses.bsdOriginal pkgs.lib.licenses.mit ];
1329 };
1316 };
1330 };
1317 };
1331 pytest-profiling = super.buildPythonPackage {
1318 pytest-profiling = super.buildPythonPackage {
1332 name = "pytest-profiling-1.0.1";
1319 name = "pytest-profiling-1.2.2";
1333 buildInputs = with self; [];
1320 buildInputs = with self; [];
1334 doCheck = false;
1321 doCheck = false;
1335 propagatedBuildInputs = with self; [six pytest gprof2dot];
1322 propagatedBuildInputs = with self; [six pytest gprof2dot];
1336 src = fetchurl {
1323 src = fetchurl {
1337 url = "https://pypi.python.org/packages/d8/67/8ffab73406e22870e07fa4dc8dce1d7689b26dba8efd00161c9b6fc01ec0/pytest-profiling-1.0.1.tar.gz";
1324 url = "https://pypi.python.org/packages/73/e8/804681323bac0bc45c520ec34185ba8469008942266d0074699b204835c1/pytest-profiling-1.2.2.tar.gz";
1338 md5 = "354404eb5b3fd4dc5eb7fffbb3d9b68b";
1325 md5 = "0a16d7dda2d23b91e9730fa4558cf728";
1339 };
1326 };
1340 meta = {
1327 meta = {
1341 license = [ pkgs.lib.licenses.mit ];
1328 license = [ pkgs.lib.licenses.mit ];
1342 };
1329 };
1343 };
1330 };
1344 pytest-runner = super.buildPythonPackage {
1331 pytest-runner = super.buildPythonPackage {
1345 name = "pytest-runner-2.7.1";
1332 name = "pytest-runner-2.9";
1346 buildInputs = with self; [];
1333 buildInputs = with self; [];
1347 doCheck = false;
1334 doCheck = false;
1348 propagatedBuildInputs = with self; [];
1335 propagatedBuildInputs = with self; [];
1349 src = fetchurl {
1336 src = fetchurl {
1350 url = "https://pypi.python.org/packages/99/6b/c4ff4418d3424d4475b7af60724fd4a5cdd91ed8e489dc9443281f0052bc/pytest-runner-2.7.1.tar.gz";
1337 url = "https://pypi.python.org/packages/11/d4/c335ddf94463e451109e3494e909765c3e5205787b772e3b25ee8601b86a/pytest-runner-2.9.tar.gz";
1351 md5 = "e56f0bc8d79a6bd91772b44ef4215c7e";
1338 md5 = "2212a2e34404b0960b2fdc2c469247b2";
1352 };
1339 };
1353 meta = {
1340 meta = {
1354 license = [ pkgs.lib.licenses.mit ];
1341 license = [ pkgs.lib.licenses.mit ];
1355 };
1342 };
1356 };
1343 };
1344 pytest-sugar = super.buildPythonPackage {
1345 name = "pytest-sugar-0.7.1";
1346 buildInputs = with self; [];
1347 doCheck = false;
1348 propagatedBuildInputs = with self; [pytest termcolor];
1349 src = fetchurl {
1350 url = "https://pypi.python.org/packages/03/97/05d988b4fa870e7373e8ee4582408543b9ca2bd35c3c67b569369c6f9c49/pytest-sugar-0.7.1.tar.gz";
1351 md5 = "7400f7c11f3d572b2c2a3b60352d35fe";
1352 };
1353 meta = {
1354 license = [ pkgs.lib.licenses.bsdOriginal ];
1355 };
1356 };
1357 pytest-timeout = super.buildPythonPackage {
1357 pytest-timeout = super.buildPythonPackage {
1358 name = "pytest-timeout-0.4";
1358 name = "pytest-timeout-1.2.0";
1359 buildInputs = with self; [];
1359 buildInputs = with self; [];
1360 doCheck = false;
1360 doCheck = false;
1361 propagatedBuildInputs = with self; [pytest];
1361 propagatedBuildInputs = with self; [pytest];
1362 src = fetchurl {
1362 src = fetchurl {
1363 url = "https://pypi.python.org/packages/24/48/5f6bd4b8026a26e1dd427243d560a29a0f1b24a5c7cffca4bf049a7bb65b/pytest-timeout-0.4.tar.gz";
1363 url = "https://pypi.python.org/packages/cc/b7/b2a61365ea6b6d2e8881360ae7ed8dad0327ad2df89f2f0be4a02304deb2/pytest-timeout-1.2.0.tar.gz";
1364 md5 = "03b28aff69cbbfb959ed35ade5fde262";
1364 md5 = "83607d91aa163562c7ee835da57d061d";
1365 };
1365 };
1366 meta = {
1366 meta = {
1367 license = [ pkgs.lib.licenses.mit { fullName = "DFSG approved"; } ];
1367 license = [ pkgs.lib.licenses.mit { fullName = "DFSG approved"; } ];
@@ -1498,36 +1498,36 b''
1498 };
1498 };
1499 };
1499 };
1500 rhodecode-enterprise-ce = super.buildPythonPackage {
1500 rhodecode-enterprise-ce = super.buildPythonPackage {
1501 name = "rhodecode-enterprise-ce-4.5.2";
1501 name = "rhodecode-enterprise-ce-4.6.0";
1502 buildInputs = with self; [WebTest configobj cssselect lxml mock pytest pytest-cov pytest-runner pytest-sugar];
1502 buildInputs = with self; [pytest py pytest-cov pytest-sugar pytest-runner pytest-catchlog pytest-profiling gprof2dot pytest-timeout mock WebTest cov-core coverage cssselect lxml configobj];
1503 doCheck = true;
1503 doCheck = true;
1504 propagatedBuildInputs = with self; [Babel Beaker FormEncode Mako Markdown MarkupSafe MySQL-python Paste PasteDeploy PasteScript Pygments pygments-markdown-lexer Pylons Pyro4 Routes SQLAlchemy Tempita URLObject WebError WebHelpers WebHelpers2 WebOb WebTest Whoosh alembic amqplib anyjson appenlight-client authomatic backport-ipaddress celery channelstream colander decorator deform docutils gevent gunicorn infrae.cache ipython iso8601 kombu msgpack-python packaging psycopg2 py-gfm pycrypto pycurl pyparsing pyramid pyramid-debugtoolbar pyramid-mako pyramid-beaker pysqlite python-dateutil python-ldap python-memcached python-pam recaptcha-client repoze.lru requests simplejson subprocess32 waitress zope.cachedescriptors dogpile.cache dogpile.core psutil py-bcrypt];
1504 propagatedBuildInputs = with self; [Babel Beaker FormEncode Mako Markdown MarkupSafe MySQL-python Paste PasteDeploy PasteScript Pygments pygments-markdown-lexer Pylons Pyro4 Routes SQLAlchemy Tempita URLObject WebError WebHelpers WebHelpers2 WebOb WebTest Whoosh alembic amqplib anyjson appenlight-client authomatic backport-ipaddress celery channelstream colander decorator deform docutils gevent gunicorn infrae.cache ipython iso8601 kombu msgpack-python packaging psycopg2 py-gfm pycrypto pycurl pyparsing pyramid pyramid-debugtoolbar pyramid-mako pyramid-beaker pysqlite python-dateutil python-ldap python-memcached python-pam recaptcha-client repoze.lru requests simplejson subprocess32 waitress zope.cachedescriptors dogpile.cache dogpile.core psutil py-bcrypt];
1505 src = ./.;
1505 src = ./.;
1506 meta = {
1506 meta = {
1507 license = [ { fullName = "AGPLv3, and Commercial License"; } ];
1507 license = [ { fullName = "Affero GNU General Public License v3 or later (AGPLv3+)"; } { fullName = "AGPLv3, and Commercial License"; } ];
1508 };
1508 };
1509 };
1509 };
1510 rhodecode-tools = super.buildPythonPackage {
1510 rhodecode-tools = super.buildPythonPackage {
1511 name = "rhodecode-tools-0.10.2";
1511 name = "rhodecode-tools-0.11.0";
1512 buildInputs = with self; [];
1512 buildInputs = with self; [];
1513 doCheck = false;
1513 doCheck = false;
1514 propagatedBuildInputs = with self; [click future six Mako MarkupSafe requests Whoosh elasticsearch elasticsearch-dsl urllib3];
1514 propagatedBuildInputs = with self; [click future six Mako MarkupSafe requests elasticsearch elasticsearch-dsl urllib3 Whoosh];
1515 src = fetchurl {
1515 src = fetchurl {
1516 url = "https://code.rhodecode.com/rhodecode-tools-ce/archive/v0.10.2.zip";
1516 url = "https://code.rhodecode.com/rhodecode-tools-ce/archive/v0.11.0.tar.gz?md5=e5fd0a8363af08a0ced71b50ca9cce15";
1517 md5 = "d2af3985a1a32a678944d4d48870cb04";
1517 md5 = "e5fd0a8363af08a0ced71b50ca9cce15";
1518 };
1518 };
1519 meta = {
1519 meta = {
1520 license = [ { fullName = "AGPLv3 and Proprietary"; } ];
1520 license = [ { fullName = "AGPLv3 and Proprietary"; } ];
1521 };
1521 };
1522 };
1522 };
1523 serpent = super.buildPythonPackage {
1523 serpent = super.buildPythonPackage {
1524 name = "serpent-1.12";
1524 name = "serpent-1.15";
1525 buildInputs = with self; [];
1525 buildInputs = with self; [];
1526 doCheck = false;
1526 doCheck = false;
1527 propagatedBuildInputs = with self; [];
1527 propagatedBuildInputs = with self; [];
1528 src = fetchurl {
1528 src = fetchurl {
1529 url = "https://pypi.python.org/packages/3b/19/1e0e83b47c09edaef8398655088036e7e67386b5c48770218ebb339fbbd5/serpent-1.12.tar.gz";
1529 url = "https://pypi.python.org/packages/7b/38/b2b27673a882ff2ea5871bb3e3e6b496ebbaafd1612e51990ffb158b9254/serpent-1.15.tar.gz";
1530 md5 = "05869ac7b062828b34f8f927f0457b65";
1530 md5 = "e27b1aad5c218e16442f52abb7c7053a";
1531 };
1531 };
1532 meta = {
1532 meta = {
1533 license = [ pkgs.lib.licenses.mit ];
1533 license = [ pkgs.lib.licenses.mit ];
@@ -1547,26 +1547,26 b''
1547 };
1547 };
1548 };
1548 };
1549 setuptools = super.buildPythonPackage {
1549 setuptools = super.buildPythonPackage {
1550 name = "setuptools-20.8.1";
1550 name = "setuptools-30.1.0";
1551 buildInputs = with self; [];
1551 buildInputs = with self; [];
1552 doCheck = false;
1552 doCheck = false;
1553 propagatedBuildInputs = with self; [];
1553 propagatedBuildInputs = with self; [];
1554 src = fetchurl {
1554 src = fetchurl {
1555 url = "https://pypi.python.org/packages/c4/19/c1bdc88b53da654df43770f941079dbab4e4788c2dcb5658fb86259894c7/setuptools-20.8.1.zip";
1555 url = "https://pypi.python.org/packages/1e/43/002c8616db9a3e7be23c2556e39b90a32bb40ba0dc652de1999d5334d372/setuptools-30.1.0.tar.gz";
1556 md5 = "fe58a5cac0df20bb83942b252a4b0543";
1556 md5 = "cac497f42e5096ac8df29e38d3f81c3e";
1557 };
1557 };
1558 meta = {
1558 meta = {
1559 license = [ pkgs.lib.licenses.mit ];
1559 license = [ pkgs.lib.licenses.mit ];
1560 };
1560 };
1561 };
1561 };
1562 setuptools-scm = super.buildPythonPackage {
1562 setuptools-scm = super.buildPythonPackage {
1563 name = "setuptools-scm-1.11.0";
1563 name = "setuptools-scm-1.15.0";
1564 buildInputs = with self; [];
1564 buildInputs = with self; [];
1565 doCheck = false;
1565 doCheck = false;
1566 propagatedBuildInputs = with self; [];
1566 propagatedBuildInputs = with self; [];
1567 src = fetchurl {
1567 src = fetchurl {
1568 url = "https://pypi.python.org/packages/cd/5f/e3a038292358058d83d764a47d09114aa5a8003ed4529518f9e580f1a94f/setuptools_scm-1.11.0.tar.gz";
1568 url = "https://pypi.python.org/packages/80/b7/31b6ae5fcb188e37f7e31abe75f9be90490a5456a72860fa6e643f8a3cbc/setuptools_scm-1.15.0.tar.gz";
1569 md5 = "4c5c896ba52e134bbc3507bac6400087";
1569 md5 = "b6916c78ed6253d6602444fad4279c5b";
1570 };
1570 };
1571 meta = {
1571 meta = {
1572 license = [ pkgs.lib.licenses.mit ];
1572 license = [ pkgs.lib.licenses.mit ];
@@ -1625,18 +1625,31 b''
1625 };
1625 };
1626 };
1626 };
1627 supervisor = super.buildPythonPackage {
1627 supervisor = super.buildPythonPackage {
1628 name = "supervisor-3.3.0";
1628 name = "supervisor-3.3.1";
1629 buildInputs = with self; [];
1629 buildInputs = with self; [];
1630 doCheck = false;
1630 doCheck = false;
1631 propagatedBuildInputs = with self; [meld3];
1631 propagatedBuildInputs = with self; [meld3];
1632 src = fetchurl {
1632 src = fetchurl {
1633 url = "https://pypi.python.org/packages/44/80/d28047d120bfcc8158b4e41127706731ee6a3419c661e0a858fb0e7c4b2d/supervisor-3.3.0.tar.gz";
1633 url = "https://pypi.python.org/packages/80/37/964c0d53cbd328796b1aeb7abea4c0f7b0e8c7197ea9b0b9967b7d004def/supervisor-3.3.1.tar.gz";
1634 md5 = "46bac00378d1eddb616752b990c67416";
1634 md5 = "202f760f9bf4930ec06557bac73e5cf2";
1635 };
1635 };
1636 meta = {
1636 meta = {
1637 license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
1637 license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ];
1638 };
1638 };
1639 };
1639 };
1640 termcolor = super.buildPythonPackage {
1641 name = "termcolor-1.1.0";
1642 buildInputs = with self; [];
1643 doCheck = false;
1644 propagatedBuildInputs = with self; [];
1645 src = fetchurl {
1646 url = "https://pypi.python.org/packages/8a/48/a76be51647d0eb9f10e2a4511bf3ffb8cc1e6b14e9e4fab46173aa79f981/termcolor-1.1.0.tar.gz";
1647 md5 = "043e89644f8909d462fbbfa511c768df";
1648 };
1649 meta = {
1650 license = [ pkgs.lib.licenses.mit ];
1651 };
1652 };
1640 traitlets = super.buildPythonPackage {
1653 traitlets = super.buildPythonPackage {
1641 name = "traitlets-4.3.1";
1654 name = "traitlets-4.3.1";
1642 buildInputs = with self; [];
1655 buildInputs = with self; [];
@@ -1729,13 +1742,13 b''
1729 };
1742 };
1730 };
1743 };
1731 waitress = super.buildPythonPackage {
1744 waitress = super.buildPythonPackage {
1732 name = "waitress-0.8.9";
1745 name = "waitress-1.0.1";
1733 buildInputs = with self; [];
1746 buildInputs = with self; [];
1734 doCheck = false;
1747 doCheck = false;
1735 propagatedBuildInputs = with self; [setuptools];
1748 propagatedBuildInputs = with self; [];
1736 src = fetchurl {
1749 src = fetchurl {
1737 url = "https://pypi.python.org/packages/ee/65/fc9dee74a909a1187ca51e4f15ad9c4d35476e4ab5813f73421505c48053/waitress-0.8.9.tar.gz";
1750 url = "https://pypi.python.org/packages/78/7d/84d11b96c3f60164dec3bef4a859a03aeae0231aa93f57fbe0d05fa4ff36/waitress-1.0.1.tar.gz";
1738 md5 = "da3f2e62b3676be5dd630703a68e2a04";
1751 md5 = "dda92358a7569669086155923a46e57c";
1739 };
1752 };
1740 meta = {
1753 meta = {
1741 license = [ pkgs.lib.licenses.zpt21 ];
1754 license = [ pkgs.lib.licenses.zpt21 ];
@@ -1835,30 +1848,5 b''
1835
1848
1836 ### Test requirements
1849 ### Test requirements
1837
1850
1838 pytest-sugar = super.buildPythonPackage {
1851
1839 name = "pytest-sugar-0.7.1";
1840 buildInputs = with self; [];
1841 doCheck = false;
1842 propagatedBuildInputs = with self; [pytest termcolor];
1843 src = fetchurl {
1844 url = "https://pypi.python.org/packages/03/97/05d988b4fa870e7373e8ee4582408543b9ca2bd35c3c67b569369c6f9c49/pytest-sugar-0.7.1.tar.gz";
1845 md5 = "7400f7c11f3d572b2c2a3b60352d35fe";
1846 };
1847 meta = {
1848 license = [ pkgs.lib.licenses.bsdOriginal ];
1849 };
1850 };
1851 termcolor = super.buildPythonPackage {
1852 name = "termcolor-1.1.0";
1853 buildInputs = with self; [];
1854 doCheck = false;
1855 propagatedBuildInputs = with self; [];
1856 src = fetchurl {
1857 url = "https://pypi.python.org/packages/8a/48/a76be51647d0eb9f10e2a4511bf3ffb8cc1e6b14e9e4fab46173aa79f981/termcolor-1.1.0.tar.gz";
1858 md5 = "043e89644f8909d462fbbfa511c768df";
1859 };
1860 meta = {
1861 license = [ pkgs.lib.licenses.mit ];
1862 };
1863 };
1864 }
1852 }
@@ -1,150 +1,131 b''
1 Babel==1.3
1 ## core
2 Beaker==1.7.0
2 setuptools==30.1.0
3 Chameleon==2.24
3 setuptools-scm==1.15.0
4 CProfileV==1.0.6
5 FormEncode==1.2.4
6 Jinja2==2.7.3
7 Mako==1.0.1
8 Markdown==2.6.2
9 MarkupSafe==0.23
10 MySQL-python==1.2.5
11 Paste==2.0.2
12 PasteDeploy==1.5.2
13 PasteScript==1.7.5
14 Pygments==2.1.3
15 pygments-markdown-lexer==0.1.0.dev39
16
17 # TODO: This version is not available on PyPI
18 # Pylons==1.0.2.dev20160108
19 Pylons==1.0.1
20
4
21 # TODO: This version is not available, but newer ones are
22 # Pyro4==4.35
23 Pyro4==4.41
24
25 # TODO: This should probably not be in here
26 # -e hg+https://johbo@code.rhodecode.com/johbo/rhodecode-fork@3a454bd1f17c0b2b2a951cf2b111e0320d7942a9#egg=RhodeCodeEnterprise-dev
27
28 Routes==1.13
29 SQLAlchemy==0.9.9
30 Sphinx==1.2.2
31 Tempita==0.5.2
32 URLObject==2.4.0
33 WebError==0.10.3
34
35 # TODO: This is modified by us, needs a better integration. For now
36 # using the latest version before.
37 # WebHelpers==1.3.dev20150807
38 WebHelpers==1.3
39
40 WebHelpers2==2.0
41 WebOb==1.3.1
42 WebTest==1.4.3
43 Whoosh==2.7.0
44 alembic==0.8.4
45 amqplib==1.0.2
5 amqplib==1.0.2
46 anyjson==0.3.3
6 anyjson==0.3.3
47 appenlight-client==0.6.14
7 authomatic==0.1.0.post1
48 authomatic==0.1.0.post1;
8 Babel==1.3
49 backport-ipaddress==0.1
9 backport-ipaddress==0.1
50 bottle==0.12.8
10 Beaker==1.7.0
51 bumpversion==0.5.3
52 celery==2.2.10
11 celery==2.2.10
12 Chameleon==2.24
53 channelstream==0.5.2
13 channelstream==0.5.2
54 click==5.1
14 click==5.1
55 colander==1.2
15 colander==1.2
56 configobj==5.0.6
16 configobj==5.0.6
57 cov-core==1.15.0
58 coverage==3.7.1
59 cssselect==0.9.1
60 decorator==3.4.2
17 decorator==3.4.2
61 deform==2.0a2
18 deform==2.0a2
62 docutils==0.12
19 docutils==0.12
63 dogpile.cache==0.6.1
20 dogpile.cache==0.6.1
64 dogpile.core==0.4.1
21 dogpile.core==0.4.1
65 dulwich==0.12.0
66 ecdsa==0.11
22 ecdsa==0.11
23 FormEncode==1.2.4
67 future==0.14.3
24 future==0.14.3
68 futures==3.0.2
25 futures==3.0.2
69 gevent==1.1.1
70 gprof2dot==2015.12.1
71 greenlet==0.4.9
72 gunicorn==19.6.0
73
74 # TODO: Needs subvertpy and blows up without Subversion headers,
75 # actually we should not need this for Enterprise at all.
76 # hgsubversion==1.8.2
77
78 gnureadline==6.3.3
26 gnureadline==6.3.3
79 infrae.cache==1.0.1
27 infrae.cache==1.0.1
80 invoke==0.13.0
81 ipdb==0.10.1
82 ipython==5.1.0
83 iso8601==0.1.11
28 iso8601==0.1.11
84 itsdangerous==0.24
29 itsdangerous==0.24
30 Jinja2==2.7.3
85 kombu==1.5.1
31 kombu==1.5.1
86 lxml==3.4.4
32 Mako==1.0.6
33 Markdown==2.6.7
34 MarkupSafe==0.23
87 meld3==1.0.2
35 meld3==1.0.2
88 mock==1.0.1
36 msgpack-python==0.4.8
89 msgpack-python==0.4.6
37 MySQL-python==1.2.5
90 nose==1.3.6
38 nose==1.3.6
91 objgraph==2.0.0
39 objgraph==2.0.0
92 packaging==15.2
40 packaging==15.2
93 paramiko==1.15.1
41 paramiko==1.15.1
42 Paste==2.0.3
43 PasteDeploy==1.5.2
44 PasteScript==1.7.5
94 psutil==4.3.1
45 psutil==4.3.1
95 psycopg2==2.6.1
46 psycopg2==2.6.1
96 py==1.4.29
97 py-bcrypt==0.4
47 py-bcrypt==0.4
98 py-gfm==0.1.3
99 pycrypto==2.6.1
48 pycrypto==2.6.1
100 pycurl==7.19.5
49 pycurl==7.19.5
101 pyflakes==0.8.1
50 pyflakes==0.8.1
51 pygments-markdown-lexer==0.1.0.dev39
52 Pygments==2.2.0
102 pyparsing==1.5.7
53 pyparsing==1.5.7
103 pyramid==1.6.1
104 pyramid-beaker==0.8
54 pyramid-beaker==0.8
105 pyramid-debugtoolbar==2.4.2
55 pyramid-debugtoolbar==2.4.2
106 pyramid-jinja2==2.5
56 pyramid-jinja2==2.5
107 pyramid-mako==1.0.2
57 pyramid-mako==1.0.2
58 pyramid==1.6.1
108 pysqlite==2.6.3
59 pysqlite==2.6.3
109 pytest==2.8.5
110 pytest-runner==2.7.1
111 pytest-catchlog==1.2.2
112 pytest-cov==1.8.1
113 pytest-profiling==1.0.1
114 pytest-timeout==0.4
115 python-dateutil==1.5
60 python-dateutil==1.5
116 python-ldap==2.4.19
61 python-ldap==2.4.19
117 python-memcached==1.57
62 python-memcached==1.57
118 python-pam==1.8.2
63 python-pam==1.8.2
119 pytz==2015.4
64 pytz==2015.4
120 pyzmq==14.6.0
65 pyzmq==14.6.0
121
122 # TODO: This is not available in public
123 # rc-testdata==0.2.0
124
125 https://code.rhodecode.com/rhodecode-tools-ce/archive/v0.10.2.zip#md5=d2af3985a1a32a678944d4d48870cb04
126
127
128 recaptcha-client==1.0.6
66 recaptcha-client==1.0.6
129 repoze.lru==0.6
67 repoze.lru==0.6
130 requests==2.9.1
68 requests==2.9.1
131 serpent==1.12
69 Routes==1.13
132 setproctitle==1.1.8
70 setproctitle==1.1.8
133 setuptools==20.8.1
134 setuptools-scm==1.11.0
135 simplejson==3.7.2
71 simplejson==3.7.2
136 six==1.9.0
72 six==1.9.0
73 Sphinx==1.2.2
74 SQLAlchemy==0.9.9
137 subprocess32==3.2.6
75 subprocess32==3.2.6
138 supervisor==3.3.0
76 supervisor==3.3.1
139 transifex-client==0.10
77 Tempita==0.5.2
140 translationstring==1.3
78 translationstring==1.3
141 trollius==1.0.4
79 trollius==1.0.4
142 uWSGI==2.0.11.2
143 urllib3==1.16
80 urllib3==1.16
81 URLObject==2.4.0
144 venusian==1.0
82 venusian==1.0
145 waitress==0.8.9
83 WebError==0.10.3
84 WebHelpers2==2.0
85 WebHelpers==1.3
86 WebOb==1.3.1
87 Whoosh==2.7.4
146 wsgiref==0.1.2
88 wsgiref==0.1.2
147 zope.cachedescriptors==4.0.0
89 zope.cachedescriptors==4.0.0
148 zope.deprecation==4.1.2
90 zope.deprecation==4.1.2
149 zope.event==4.0.3
91 zope.event==4.0.3
150 zope.interface==4.1.3
92 zope.interface==4.1.3
93
94 ## customized/patched libs
95 # our patched version of Pylons==1.0.2
96 https://code.rhodecode.com/upstream/pylons/archive/707354ee4261b9c10450404fc9852ccea4fd667d.tar.gz?md5=f26633726fa2cd3a340316ee6a5d218f#egg=Pylons==1.0.2.rhodecode-patch-1
97 # not released py-gfm==0.1.3
98 https://code.rhodecode.com/upstream/py-gfm/archive/0d66a19bc16e3d49de273c0f797d4e4781e8c0f2.tar.gz?md5=0d0d5385bfb629eea636a80b9c2bfd16#egg=py-gfm==0.1.3.rhodecode-upstream1
99
100
101 ## cli tools
102 alembic==0.8.4
103 invoke==0.13.0
104 bumpversion==0.5.3
105 transifex-client==0.10
106
107 ## http servers
108 gevent==1.1.2
109 greenlet==0.4.10
110 gunicorn==19.6.0
111 waitress==1.0.1
112 uWSGI==2.0.11.2
113
114 ## debug
115 ipdb==0.10.1
116 ipython==5.1.0
117 CProfileV==1.0.6
118 bottle==0.12.8
119
120 ## rhodecode-tools, special case
121 https://code.rhodecode.com/rhodecode-tools-ce/archive/v0.11.0.tar.gz?md5=e5fd0a8363af08a0ced71b50ca9cce15#egg=rhodecode-tools==0.11.0
122
123 ## appenlight
124 appenlight-client==0.6.14
125
126 # Pyro/Deprecated TODO(Marcink): remove in 4.7 release.
127 Pyro4==4.41
128 serpent==1.15
129
130 ## test related requirements
131 -r requirements_test.txt
@@ -1,1 +1,1 b''
1 4.5.2 No newline at end of file
1 4.6.0 No newline at end of file
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -51,11 +51,11 b' PYRAMID_SETTINGS = {}'
51 EXTENSIONS = {}
51 EXTENSIONS = {}
52
52
53 __version__ = ('.'.join((str(each) for each in VERSION[:3])))
53 __version__ = ('.'.join((str(each) for each in VERSION[:3])))
54 __dbversion__ = 63 # defines current db version for migrations
54 __dbversion__ = 64 # defines current db version for migrations
55 __platform__ = platform.system()
55 __platform__ = platform.system()
56 __license__ = 'AGPLv3, and Commercial License'
56 __license__ = 'AGPLv3, and Commercial License'
57 __author__ = 'RhodeCode GmbH'
57 __author__ = 'RhodeCode GmbH'
58 __url__ = 'http://rhodecode.com'
58 __url__ = 'https://code.rhodecode.com'
59
59
60 is_windows = __platform__ in ['Windows']
60 is_windows = __platform__ in ['Windows']
61 is_unix = not is_windows
61 is_unix = not is_windows
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2016-2016 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
@@ -39,5 +39,19 b' def includeme(config):'
39 name='admin_settings_vcs_svn_generate_cfg',
39 name='admin_settings_vcs_svn_generate_cfg',
40 pattern=ADMIN_PREFIX + '/settings/vcs/svn_generate_cfg')
40 pattern=ADMIN_PREFIX + '/settings/vcs/svn_generate_cfg')
41
41
42 config.add_route(
43 name='admin_settings_system',
44 pattern=ADMIN_PREFIX + '/settings/system')
45 config.add_route(
46 name='admin_settings_system_update',
47 pattern=ADMIN_PREFIX + '/settings/system/updates')
48
49 config.add_route(
50 name='admin_settings_sessions',
51 pattern=ADMIN_PREFIX + '/settings/sessions')
52 config.add_route(
53 name='admin_settings_sessions_cleanup',
54 pattern=ADMIN_PREFIX + '/settings/sessions/cleanup')
55
42 # Scan module for configuration decorators.
56 # Scan module for configuration decorators.
43 config.scan()
57 config.scan()
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2016-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2016-2016 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
@@ -66,6 +66,15 b' class NavEntry(object):'
66 else:
66 else:
67 return url(self.view_name)
67 return url(self.view_name)
68
68
69 def get_localized_name(self, request):
70 if hasattr(request, 'translate'):
71 return request.translate(self.name)
72 else:
73 # TODO(marcink): Remove this after migrating to pyramid
74 from pyramid.threadlocal import get_current_request
75 pyramid_request = get_current_request()
76 return pyramid_request.translate(self.name)
77
69
78
70 @implementer(IAdminNavigationRegistry)
79 @implementer(IAdminNavigationRegistry)
71 class NavigationRegistry(object):
80 class NavigationRegistry(object):
@@ -80,18 +89,22 b' class NavigationRegistry(object):'
80 NavEntry('email', _('Email'), 'admin_settings_email'),
89 NavEntry('email', _('Email'), 'admin_settings_email'),
81 NavEntry('hooks', _('Hooks'), 'admin_settings_hooks'),
90 NavEntry('hooks', _('Hooks'), 'admin_settings_hooks'),
82 NavEntry('search', _('Full Text Search'), 'admin_settings_search'),
91 NavEntry('search', _('Full Text Search'), 'admin_settings_search'),
92
83 NavEntry('integrations', _('Integrations'),
93 NavEntry('integrations', _('Integrations'),
84 'global_integrations_home', pyramid=True),
94 'global_integrations_home', pyramid=True),
85 NavEntry('system', _('System Info'), 'admin_settings_system'),
95 NavEntry('system', _('System Info'),
96 'admin_settings_system', pyramid=True),
97 NavEntry('sessions', _('User Sessions'),
98 'admin_settings_sessions', pyramid=True),
86 NavEntry('open_source', _('Open Source Licenses'),
99 NavEntry('open_source', _('Open Source Licenses'),
87 'admin_settings_open_source', pyramid=True),
100 'admin_settings_open_source', pyramid=True),
101
88 # TODO: marcink: we disable supervisor now until the supervisor stats
102 # TODO: marcink: we disable supervisor now until the supervisor stats
89 # page is fixed in the nix configuration
103 # page is fixed in the nix configuration
90 # NavEntry('supervisor', _('Supervisor'), 'admin_settings_supervisor'),
104 # NavEntry('supervisor', _('Supervisor'), 'admin_settings_supervisor'),
91 ]
105 ]
92
106
93 _labs_entry = NavEntry('labs', _('Labs'),
107 _labs_entry = NavEntry('labs', _('Labs'), 'admin_settings_labs')
94 'admin_settings_labs')
95
108
96 def __init__(self, labs_active=False):
109 def __init__(self, labs_active=False):
97 self._registered_entries = collections.OrderedDict([
110 self._registered_entries = collections.OrderedDict([
@@ -105,7 +118,8 b' class NavigationRegistry(object):'
105 self._registered_entries[entry.key] = entry
118 self._registered_entries[entry.key] = entry
106
119
107 def get_navlist(self, request):
120 def get_navlist(self, request):
108 navlist = [NavListEntry(i.key, i.name, i.generate_url(request))
121 navlist = [NavListEntry(i.key, i.get_localized_name(request),
122 i.generate_url(request))
109 for i in self._registered_entries.values()]
123 for i in self._registered_entries.values()]
110 return navlist
124 return navlist
111
125
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2011-2016 RhodeCode GmbH
3 # Copyright (C) 2011-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
@@ -132,7 +132,7 b' def exception_view(exc, request):'
132 log.debug('json-rpc error rpc_id:%s "%s"', rpc_id, fault_message)
132 log.debug('json-rpc error rpc_id:%s "%s"', rpc_id, fault_message)
133 elif isinstance(exc, JSONRPCValidationError):
133 elif isinstance(exc, JSONRPCValidationError):
134 colander_exc = exc.colander_exception
134 colander_exc = exc.colander_exception
135 #TODO: think maybe of nicer way to serialize errors ?
135 # TODO(marcink): think maybe of nicer way to serialize errors ?
136 fault_message = colander_exc.asdict()
136 fault_message = colander_exc.asdict()
137 log.debug('json-rpc error rpc_id:%s "%s"', rpc_id, fault_message)
137 log.debug('json-rpc error rpc_id:%s "%s"', rpc_id, fault_message)
138 elif isinstance(exc, JSONRPCForbidden):
138 elif isinstance(exc, JSONRPCForbidden):
@@ -240,7 +240,7 b' def request_view(request):'
240 message=('Missing non optional `%s` arg in JSON DATA' % arg)
240 message=('Missing non optional `%s` arg in JSON DATA' % arg)
241 )
241 )
242
242
243 # sanitze extra passed arguments
243 # sanitize extra passed arguments
244 for k in request.rpc_params.keys()[:]:
244 for k in request.rpc_params.keys()[:]:
245 if k not in func_kwargs:
245 if k not in func_kwargs:
246 del request.rpc_params[k]
246 del request.rpc_params[k]
@@ -256,7 +256,7 b' def request_view(request):'
256 except JSONRPCBaseError:
256 except JSONRPCBaseError:
257 raise
257 raise
258 except Exception:
258 except Exception:
259 log.exception('Unhandled exception occured on api call: %s', func)
259 log.exception('Unhandled exception occurred on api call: %s', func)
260 return jsonrpc_error(request, retid=request.rpc_id,
260 return jsonrpc_error(request, retid=request.rpc_id,
261 message='Internal server error')
261 message='Internal server error')
262
262
@@ -269,9 +269,10 b' def setup_request(request):'
269 We need to raise JSONRPCError here if we want to return some errors back to
269 We need to raise JSONRPCError here if we want to return some errors back to
270 user.
270 user.
271 """
271 """
272
272 log.debug('Executing setup request: %r', request)
273 log.debug('Executing setup request: %r', request)
273 request.rpc_ip_addr = get_ip_addr(request.environ)
274 request.rpc_ip_addr = get_ip_addr(request.environ)
274 # TODO: marcink, deprecate GET at some point
275 # TODO(marcink): deprecate GET at some point
275 if request.method not in ['POST', 'GET']:
276 if request.method not in ['POST', 'GET']:
276 log.debug('unsupported request method "%s"', request.method)
277 log.debug('unsupported request method "%s"', request.method)
277 raise JSONRPCError(
278 raise JSONRPCError(
@@ -308,6 +309,8 b' def setup_request(request):'
308 if not api_key:
309 if not api_key:
309 raise KeyError('api_key or auth_token')
310 raise KeyError('api_key or auth_token')
310
311
312 # TODO(marcink): support passing in token in request header
313
311 request.rpc_api_key = api_key
314 request.rpc_api_key = api_key
312 request.rpc_id = json_body['id']
315 request.rpc_id = json_body['id']
313 request.rpc_method = json_body['method']
316 request.rpc_method = json_body['method']
@@ -485,8 +488,7 b' def includeme(config):'
485 config.registry.jsonrpc_methods = OrderedDict()
488 config.registry.jsonrpc_methods = OrderedDict()
486
489
487 # match filter by given method only
490 # match filter by given method only
488 config.add_view_predicate(
491 config.add_view_predicate('jsonrpc_method', MethodPredicate)
489 'jsonrpc_method', MethodPredicate)
490
492
491 config.add_renderer(DEFAULT_RENDERER, ExtJsonRenderer(
493 config.add_renderer(DEFAULT_RENDERER, ExtJsonRenderer(
492 serializer=json.dumps, indent=4))
494 serializer=json.dumps, indent=4))
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2011-2016 RhodeCode GmbH
3 # Copyright (C) 2011-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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -20,7 +20,7 b''
20
20
21 import pytest
21 import pytest
22
22
23 from rhodecode.model.comment import ChangesetCommentsModel
23 from rhodecode.model.comment import CommentsModel
24 from rhodecode.model.db import UserLog
24 from rhodecode.model.db import UserLog
25 from rhodecode.model.pull_request import PullRequestModel
25 from rhodecode.model.pull_request import PullRequestModel
26 from rhodecode.tests import TEST_USER_ADMIN_LOGIN
26 from rhodecode.tests import TEST_USER_ADMIN_LOGIN
@@ -52,13 +52,13 b' class TestCommentPullRequest(object):'
52 response = api_call(self.app, params)
52 response = api_call(self.app, params)
53 pull_request = PullRequestModel().get(pull_request.pull_request_id)
53 pull_request = PullRequestModel().get(pull_request.pull_request_id)
54
54
55 comments = ChangesetCommentsModel().get_comments(
55 comments = CommentsModel().get_comments(
56 pull_request.target_repo.repo_id, pull_request=pull_request)
56 pull_request.target_repo.repo_id, pull_request=pull_request)
57
57
58 expected = {
58 expected = {
59 'pull_request_id': pull_request.pull_request_id,
59 'pull_request_id': pull_request.pull_request_id,
60 'comment_id': comments[-1].comment_id,
60 'comment_id': comments[-1].comment_id,
61 'status': None
61 'status': {'given': None, 'was_changed': None}
62 }
62 }
63 assert_ok(id_, expected, response.body)
63 assert_ok(id_, expected, response.body)
64
64
@@ -83,12 +83,61 b' class TestCommentPullRequest(object):'
83 response = api_call(self.app, params)
83 response = api_call(self.app, params)
84 pull_request = PullRequestModel().get(pull_request_id)
84 pull_request = PullRequestModel().get(pull_request_id)
85
85
86 comments = ChangesetCommentsModel().get_comments(
86 comments = CommentsModel().get_comments(
87 pull_request.target_repo.repo_id, pull_request=pull_request)
87 pull_request.target_repo.repo_id, pull_request=pull_request)
88 expected = {
88 expected = {
89 'pull_request_id': pull_request.pull_request_id,
89 'pull_request_id': pull_request.pull_request_id,
90 'comment_id': comments[-1].comment_id,
90 'comment_id': comments[-1].comment_id,
91 'status': 'rejected'
91 'status': {'given': 'rejected', 'was_changed': True}
92 }
93 assert_ok(id_, expected, response.body)
94
95 @pytest.mark.backends("git", "hg")
96 def test_api_comment_pull_request_change_status_with_specific_commit_id(
97 self, pr_util, no_notifications):
98 pull_request = pr_util.create_pull_request()
99 pull_request_id = pull_request.pull_request_id
100 latest_commit_id = 'test_commit'
101 # inject additional revision, to fail test the status change on
102 # non-latest commit
103 pull_request.revisions = pull_request.revisions + ['test_commit']
104
105 id_, params = build_data(
106 self.apikey, 'comment_pull_request',
107 repoid=pull_request.target_repo.repo_name,
108 pullrequestid=pull_request.pull_request_id,
109 status='approved', commit_id=latest_commit_id)
110 response = api_call(self.app, params)
111 pull_request = PullRequestModel().get(pull_request_id)
112
113 expected = {
114 'pull_request_id': pull_request.pull_request_id,
115 'comment_id': None,
116 'status': {'given': 'approved', 'was_changed': False}
117 }
118 assert_ok(id_, expected, response.body)
119
120 @pytest.mark.backends("git", "hg")
121 def test_api_comment_pull_request_change_status_with_specific_commit_id(
122 self, pr_util, no_notifications):
123 pull_request = pr_util.create_pull_request()
124 pull_request_id = pull_request.pull_request_id
125 latest_commit_id = pull_request.revisions[0]
126
127 id_, params = build_data(
128 self.apikey, 'comment_pull_request',
129 repoid=pull_request.target_repo.repo_name,
130 pullrequestid=pull_request.pull_request_id,
131 status='approved', commit_id=latest_commit_id)
132 response = api_call(self.app, params)
133 pull_request = PullRequestModel().get(pull_request_id)
134
135 comments = CommentsModel().get_comments(
136 pull_request.target_repo.repo_id, pull_request=pull_request)
137 expected = {
138 'pull_request_id': pull_request.pull_request_id,
139 'comment_id': comments[-1].comment_id,
140 'status': {'given': 'approved', 'was_changed': True}
92 }
141 }
93 assert_ok(id_, expected, response.body)
142 assert_ok(id_, expected, response.body)
94
143
@@ -103,7 +152,7 b' class TestCommentPullRequest(object):'
103 pullrequestid=pull_request_id)
152 pullrequestid=pull_request_id)
104 response = api_call(self.app, params)
153 response = api_call(self.app, params)
105
154
106 expected = 'message and status parameter missing'
155 expected = 'Both message and status parameters are missing. At least one is required.'
107 assert_error(id_, expected, given=response.body)
156 assert_error(id_, expected, given=response.body)
108
157
109 @pytest.mark.backends("git", "hg")
158 @pytest.mark.backends("git", "hg")
@@ -118,7 +167,7 b' class TestCommentPullRequest(object):'
118 status='42')
167 status='42')
119 response = api_call(self.app, params)
168 response = api_call(self.app, params)
120
169
121 expected = 'unknown comment status`42`'
170 expected = 'Unknown comment status: `42`'
122 assert_error(id_, expected, given=response.body)
171 assert_error(id_, expected, given=response.body)
123
172
124 @pytest.mark.backends("git", "hg")
173 @pytest.mark.backends("git", "hg")
@@ -144,3 +193,17 b' class TestCommentPullRequest(object):'
144
193
145 expected = 'userid is not the same as your user'
194 expected = 'userid is not the same as your user'
146 assert_error(id_, expected, given=response.body)
195 assert_error(id_, expected, given=response.body)
196
197 @pytest.mark.backends("git", "hg")
198 def test_api_comment_pull_request_wrong_commit_id_error(self, pr_util):
199 pull_request = pr_util.create_pull_request()
200 id_, params = build_data(
201 self.apikey_regular, 'comment_pull_request',
202 repoid=pull_request.target_repo.repo_name,
203 status='approved',
204 pullrequestid=pull_request.pull_request_id,
205 commit_id='XXX')
206 response = api_call(self.app, params)
207
208 expected = 'Invalid commit_id `XXX` for this pull request.'
209 assert_error(id_, expected, given=response.body)
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -22,7 +22,8 b''
22 import pytest
22 import pytest
23
23
24 from rhodecode.model.repo import RepoModel
24 from rhodecode.model.repo import RepoModel
25 from rhodecode.api.tests.utils import build_data, api_call, assert_ok, jsonify
25 from rhodecode.api.tests.utils import (
26 build_data, api_call, assert_ok, assert_error, jsonify)
26 from rhodecode.model.db import User
27 from rhodecode.model.db import User
27
28
28
29
@@ -40,6 +41,76 b' class TestGetRepos(object):'
40 expected = ret
41 expected = ret
41 assert_ok(id_, expected, given=response.body)
42 assert_ok(id_, expected, given=response.body)
42
43
44 def test_api_get_repos_only_toplevel(self, user_util):
45 repo_group = user_util.create_repo_group(auto_cleanup=True)
46 user_util.create_repo(parent=repo_group)
47
48 id_, params = build_data(self.apikey, 'get_repos', traverse=0)
49 response = api_call(self.app, params)
50
51 result = []
52 for repo in RepoModel().get_repos_for_root(root=None):
53 result.append(repo.get_api_data(include_secrets=True))
54 expected = jsonify(result)
55
56 assert_ok(id_, expected, given=response.body)
57
58 def test_api_get_repos_with_wrong_root(self):
59 id_, params = build_data(self.apikey, 'get_repos', root='abracadabra')
60 response = api_call(self.app, params)
61
62 expected = 'Root repository group `abracadabra` does not exist'
63 assert_error(id_, expected, given=response.body)
64
65 def test_api_get_repos_with_root(self, user_util):
66 repo_group = user_util.create_repo_group(auto_cleanup=True)
67 repo_group_name = repo_group.group_name
68
69 user_util.create_repo(parent=repo_group)
70 user_util.create_repo(parent=repo_group)
71
72 # nested, should not show up
73 user_util._test_name = '{}/'.format(repo_group_name)
74 sub_repo_group = user_util.create_repo_group(auto_cleanup=True)
75 user_util.create_repo(parent=sub_repo_group)
76
77 id_, params = build_data(self.apikey, 'get_repos',
78 root=repo_group_name, traverse=0)
79 response = api_call(self.app, params)
80
81 result = []
82 for repo in RepoModel().get_repos_for_root(repo_group):
83 result.append(repo.get_api_data(include_secrets=True))
84
85 assert len(result) == 2
86 expected = jsonify(result)
87 assert_ok(id_, expected, given=response.body)
88
89 def test_api_get_repos_with_root_and_traverse(self, user_util):
90 repo_group = user_util.create_repo_group(auto_cleanup=True)
91 repo_group_name = repo_group.group_name
92
93 user_util.create_repo(parent=repo_group)
94 user_util.create_repo(parent=repo_group)
95
96 # nested, should not show up
97 user_util._test_name = '{}/'.format(repo_group_name)
98 sub_repo_group = user_util.create_repo_group(auto_cleanup=True)
99 user_util.create_repo(parent=sub_repo_group)
100
101 id_, params = build_data(self.apikey, 'get_repos',
102 root=repo_group_name, traverse=1)
103 response = api_call(self.app, params)
104
105 result = []
106 for repo in RepoModel().get_repos_for_root(
107 repo_group_name, traverse=True):
108 result.append(repo.get_api_data(include_secrets=True))
109
110 assert len(result) == 3
111 expected = jsonify(result)
112 assert_ok(id_, expected, given=response.body)
113
43 def test_api_get_repos_non_admin(self):
114 def test_api_get_repos_non_admin(self):
44 id_, params = build_data(self.apikey_regular, 'get_repos')
115 id_, params = build_data(self.apikey_regular, 'get_repos')
45 response = api_call(self.app, params)
116 response = api_call(self.app, params)
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -20,18 +20,17 b''
20
20
21 import pytest
21 import pytest
22
22
23 from rhodecode.model.db import UserLog
23 from rhodecode.model.db import UserLog, PullRequest
24 from rhodecode.model.meta import Session
24 from rhodecode.model.meta import Session
25 from rhodecode.model.pull_request import PullRequestModel
26 from rhodecode.tests import TEST_USER_ADMIN_LOGIN
25 from rhodecode.tests import TEST_USER_ADMIN_LOGIN
27 from rhodecode.api.tests.utils import (
26 from rhodecode.api.tests.utils import (
28 build_data, api_call, assert_error)
27 build_data, api_call, assert_error, assert_ok)
29
28
30
29
31 @pytest.mark.usefixtures("testuser_api", "app")
30 @pytest.mark.usefixtures("testuser_api", "app")
32 class TestMergePullRequest(object):
31 class TestMergePullRequest(object):
33 @pytest.mark.backends("git", "hg")
32 @pytest.mark.backends("git", "hg")
34 def test_api_merge_pull_request(self, pr_util, no_notifications):
33 def test_api_merge_pull_request_merge_failed(self, pr_util, no_notifications):
35 pull_request = pr_util.create_pull_request(mergeable=True)
34 pull_request = pr_util.create_pull_request(mergeable=True)
36 author = pull_request.user_id
35 author = pull_request.user_id
37 repo = pull_request.target_repo.repo_id
36 repo = pull_request.target_repo.repo_id
@@ -51,6 +50,41 b' class TestMergePullRequest(object):'
51 # it.
50 # it.
52 Session().add(pull_request)
51 Session().add(pull_request)
53
52
53 expected = 'merge not possible for following reasons: ' \
54 'Pull request reviewer approval is pending.'
55 assert_error(id_, expected, given=response.body)
56
57 @pytest.mark.backends("git", "hg")
58 def test_api_merge_pull_request(self, pr_util, no_notifications):
59 pull_request = pr_util.create_pull_request(mergeable=True, approved=True)
60 author = pull_request.user_id
61 repo = pull_request.target_repo.repo_id
62 pull_request_id = pull_request.pull_request_id
63 pull_request_repo = pull_request.target_repo.repo_name
64
65 id_, params = build_data(
66 self.apikey, 'comment_pull_request',
67 repoid=pull_request_repo,
68 pullrequestid=pull_request_id,
69 status='approved')
70
71 response = api_call(self.app, params)
72 expected = {
73 'comment_id': response.json.get('result', {}).get('comment_id'),
74 'pull_request_id': pull_request_id,
75 'status': {'given': 'approved', 'was_changed': True}
76 }
77 assert_ok(id_, expected, given=response.body)
78
79 id_, params = build_data(
80 self.apikey, 'merge_pull_request',
81 repoid=pull_request_repo,
82 pullrequestid=pull_request_id)
83
84 response = api_call(self.app, params)
85
86 pull_request = PullRequest.get(pull_request_id)
87
54 expected = {
88 expected = {
55 'executed': True,
89 'executed': True,
56 'failure_reason': 0,
90 'failure_reason': 0,
@@ -59,8 +93,7 b' class TestMergePullRequest(object):'
59 'merge_ref': pull_request.shadow_merge_ref._asdict()
93 'merge_ref': pull_request.shadow_merge_ref._asdict()
60 }
94 }
61
95
62 response_json = response.json['result']
96 assert_ok(id_, expected, response.body)
63 assert response_json == expected
64
97
65 action = 'user_merged_pull_request:%d' % (pull_request_id, )
98 action = 'user_merged_pull_request:%d' % (pull_request_id, )
66 journal = UserLog.query()\
99 journal = UserLog.query()\
@@ -75,8 +108,7 b' class TestMergePullRequest(object):'
75 repoid=pull_request_repo, pullrequestid=pull_request_id)
108 repoid=pull_request_repo, pullrequestid=pull_request_id)
76 response = api_call(self.app, params)
109 response = api_call(self.app, params)
77
110
78 expected = 'pull request `%s` merge failed, pull request is closed' % (
111 expected = 'merge not possible for following reasons: This pull request is closed.'
79 pull_request_id)
80 assert_error(id_, expected, given=response.body)
112 assert_error(id_, expected, given=response.body)
81
113
82 @pytest.mark.backends("git", "hg")
114 @pytest.mark.backends("git", "hg")
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -24,7 +24,8 b' from rhodecode.lib.vcs.nodes import File'
24 from rhodecode.model.db import User
24 from rhodecode.model.db import User
25 from rhodecode.model.pull_request import PullRequestModel
25 from rhodecode.model.pull_request import PullRequestModel
26 from rhodecode.tests import TEST_USER_ADMIN_LOGIN
26 from rhodecode.tests import TEST_USER_ADMIN_LOGIN
27 from rhodecode.api.tests.utils import (build_data, api_call)
27 from rhodecode.api.tests.utils import (
28 build_data, api_call, assert_ok, assert_error)
28
29
29
30
30 @pytest.mark.usefixtures("testuser_api", "app")
31 @pytest.mark.usefixtures("testuser_api", "app")
@@ -74,8 +75,7 b' class TestUpdatePullRequest(object):'
74 expected = 'pull request `{}` update failed, pull request ' \
75 expected = 'pull request `{}` update failed, pull request ' \
75 'is closed'.format(pull_request.pull_request_id)
76 'is closed'.format(pull_request.pull_request_id)
76
77
77 response_json = response.json['error']
78 assert_error(id_, expected, response.body)
78 assert response_json == expected
79
79
80 @pytest.mark.backends("git", "hg")
80 @pytest.mark.backends("git", "hg")
81 def test_api_update_update_commits(
81 def test_api_update_update_commits(
@@ -90,9 +90,11 b' class TestUpdatePullRequest(object):'
90 pr_util.update_source_repository(head='c')
90 pr_util.update_source_repository(head='c')
91 repo = pull_request.source_repo.scm_instance()
91 repo = pull_request.source_repo.scm_instance()
92 commits = [x for x in repo.get_commits()]
92 commits = [x for x in repo.get_commits()]
93 print commits
93
94
94 added_commit_id = commits[-1].raw_id # c commit
95 added_commit_id = commits[-1].raw_id # c commit
95 common_commits = commits[1].raw_id # b commit is common ancestor
96 common_commit_id = commits[1].raw_id # b commit is common ancestor
97 total_commits = [added_commit_id, common_commit_id]
96
98
97 id_, params = build_data(
99 id_, params = build_data(
98 self.apikey, 'update_pull_request',
100 self.apikey, 'update_pull_request',
@@ -107,12 +109,13 b' class TestUpdatePullRequest(object):'
107 pull_request.pull_request_id),
109 pull_request.pull_request_id),
108 "pull_request": response.json['result']['pull_request'],
110 "pull_request": response.json['result']['pull_request'],
109 "updated_commits": {"added": [added_commit_id],
111 "updated_commits": {"added": [added_commit_id],
110 "common": [common_commits], "removed": []},
112 "common": [common_commit_id],
113 "total": total_commits,
114 "removed": []},
111 "updated_reviewers": {"added": [], "removed": []},
115 "updated_reviewers": {"added": [], "removed": []},
112 }
116 }
113
117
114 response_json = response.json['result']
118 assert_ok(id_, expected, response.body)
115 assert response_json == expected
116
119
117 @pytest.mark.backends("git", "hg")
120 @pytest.mark.backends("git", "hg")
118 def test_api_update_change_reviewers(
121 def test_api_update_change_reviewers(
@@ -139,8 +142,7 b' class TestUpdatePullRequest(object):'
139 "updated_reviewers": {"added": added, "removed": removed},
142 "updated_reviewers": {"added": added, "removed": removed},
140 }
143 }
141
144
142 response_json = response.json['result']
145 assert_ok(id_, expected, response.body)
143 assert response_json == expected
144
146
145 @pytest.mark.backends("git", "hg")
147 @pytest.mark.backends("git", "hg")
146 def test_api_update_bad_user_in_reviewers(self, pr_util):
148 def test_api_update_bad_user_in_reviewers(self, pr_util):
@@ -155,8 +157,7 b' class TestUpdatePullRequest(object):'
155
157
156 expected = 'user `bad_name` does not exist'
158 expected = 'user `bad_name` does not exist'
157
159
158 response_json = response.json['error']
160 assert_error(id_, expected, response.body)
159 assert response_json == expected
160
161
161 @pytest.mark.backends("git", "hg")
162 @pytest.mark.backends("git", "hg")
162 def test_api_update_repo_error(self, pr_util):
163 def test_api_update_repo_error(self, pr_util):
@@ -184,9 +185,7 b' class TestUpdatePullRequest(object):'
184 response = api_call(self.app, params)
185 response = api_call(self.app, params)
185
186
186 expected = 'pull request `999999` does not exist'
187 expected = 'pull request `999999` does not exist'
187
188 assert_error(id_, expected, response.body)
188 response_json = response.json['error']
189 assert response_json == expected
190
189
191 @pytest.mark.backends("git", "hg")
190 @pytest.mark.backends("git", "hg")
192 def test_api_update_pull_request_no_perms_to_update(
191 def test_api_update_pull_request_no_perms_to_update(
@@ -203,5 +202,4 b' class TestUpdatePullRequest(object):'
203 expected = ('pull request `%s` update failed, '
202 expected = ('pull request `%s` update failed, '
204 'no permission to update.') % pull_request.pull_request_id
203 'no permission to update.') % pull_request.pull_request_id
205
204
206 response_json = response.json['error']
205 assert_error(id_, expected, response.body)
207 assert response_json == expected
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2014-2016 RhodeCode GmbH
3 # Copyright (C) 2014-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
@@ -26,11 +26,12 b' import collections'
26 import logging
26 import logging
27
27
28 from rhodecode.api.exc import JSONRPCError
28 from rhodecode.api.exc import JSONRPCError
29 from rhodecode.lib.auth import HasPermissionAnyApi, HasRepoPermissionAnyApi, \
29 from rhodecode.lib.auth import (
30 HasRepoGroupPermissionAnyApi
30 HasPermissionAnyApi, HasRepoPermissionAnyApi, HasRepoGroupPermissionAnyApi)
31 from rhodecode.lib.utils import safe_unicode
31 from rhodecode.lib.utils import safe_unicode
32 from rhodecode.lib.vcs.exceptions import RepositoryError
32 from rhodecode.controllers.utils import get_commit_from_ref_name
33 from rhodecode.controllers.utils import get_commit_from_ref_name
33 from rhodecode.lib.vcs.exceptions import RepositoryError
34 from rhodecode.lib.utils2 import str2bool
34
35
35 log = logging.getLogger(__name__)
36 log = logging.getLogger(__name__)
36
37
@@ -92,7 +93,7 b' class Optional(object):'
92 return self.type_
93 return self.type_
93
94
94 @classmethod
95 @classmethod
95 def extract(cls, val, evaluate_locals=None):
96 def extract(cls, val, evaluate_locals=None, binary=None):
96 """
97 """
97 Extracts value from Optional() instance
98 Extracts value from Optional() instance
98
99
@@ -101,7 +102,11 b' class Optional(object):'
101 value of instance
102 value of instance
102 """
103 """
103 if isinstance(val, cls):
104 if isinstance(val, cls):
104 return val.getval(evaluate_locals)
105 val = val.getval(evaluate_locals)
106
107 if binary:
108 val = str2bool(val)
109
105 return val
110 return val
106
111
107
112
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2015-2016 RhodeCode GmbH
3 # Copyright (C) 2015-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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2011-2016 RhodeCode GmbH
3 # Copyright (C) 2011-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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2011-2016 RhodeCode GmbH
3 # Copyright (C) 2011-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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2011-2016 RhodeCode GmbH
3 # Copyright (C) 2011-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
@@ -30,9 +30,9 b' from rhodecode.lib.auth import (HasRepoP'
30 from rhodecode.lib.base import vcs_operation_context
30 from rhodecode.lib.base import vcs_operation_context
31 from rhodecode.lib.utils2 import str2bool
31 from rhodecode.lib.utils2 import str2bool
32 from rhodecode.model.changeset_status import ChangesetStatusModel
32 from rhodecode.model.changeset_status import ChangesetStatusModel
33 from rhodecode.model.comment import ChangesetCommentsModel
33 from rhodecode.model.comment import CommentsModel
34 from rhodecode.model.db import Session, ChangesetStatus
34 from rhodecode.model.db import Session, ChangesetStatus, ChangesetComment
35 from rhodecode.model.pull_request import PullRequestModel
35 from rhodecode.model.pull_request import PullRequestModel, MergeCheck
36 from rhodecode.model.settings import SettingsModel
36 from rhodecode.model.settings import SettingsModel
37
37
38 log = logging.getLogger(__name__)
38 log = logging.getLogger(__name__)
@@ -270,13 +270,14 b' def merge_pull_request(request, apiuser,'
270 raise JSONRPCError('userid is not the same as your user')
270 raise JSONRPCError('userid is not the same as your user')
271
271
272 pull_request = get_pull_request_or_error(pullrequestid)
272 pull_request = get_pull_request_or_error(pullrequestid)
273 if not PullRequestModel().check_user_merge(
273
274 pull_request, apiuser, api=True):
274 check = MergeCheck.validate(pull_request, user=apiuser)
275 raise JSONRPCError('repository `%s` does not exist' % (repoid,))
275 merge_possible = not check.failed
276 if pull_request.is_closed():
276
277 if not merge_possible:
278 reasons = ','.join([msg for _e, msg in check.errors])
277 raise JSONRPCError(
279 raise JSONRPCError(
278 'pull request `%s` merge failed, pull request is closed' % (
280 'merge not possible for following reasons: {}'.format(reasons))
279 pullrequestid,))
280
281
281 target_repo = pull_request.target_repo
282 target_repo = pull_request.target_repo
282 extras = vcs_operation_context(
283 extras = vcs_operation_context(
@@ -359,9 +360,12 b' def close_pull_request(request, apiuser,'
359
360
360
361
361 @jsonrpc_method()
362 @jsonrpc_method()
362 def comment_pull_request(request, apiuser, repoid, pullrequestid,
363 def comment_pull_request(
363 message=Optional(None), status=Optional(None),
364 request, apiuser, repoid, pullrequestid, message=Optional(None),
364 userid=Optional(OAttr('apiuser'))):
365 commit_id=Optional(None), status=Optional(None),
366 comment_type=Optional(ChangesetComment.COMMENT_TYPE_NOTE),
367 resolves_comment_id=Optional(None),
368 userid=Optional(OAttr('apiuser'))):
365 """
369 """
366 Comment on the pull request specified with the `pullrequestid`,
370 Comment on the pull request specified with the `pullrequestid`,
367 in the |repo| specified by the `repoid`, and optionally change the
371 in the |repo| specified by the `repoid`, and optionally change the
@@ -373,15 +377,18 b' def comment_pull_request(request, apiuse'
373 :type repoid: str or int
377 :type repoid: str or int
374 :param pullrequestid: The pull request ID.
378 :param pullrequestid: The pull request ID.
375 :type pullrequestid: int
379 :type pullrequestid: int
380 :param commit_id: Specify the commit_id for which to set a comment. If
381 given commit_id is different than latest in the PR status
382 change won't be performed.
383 :type commit_id: str
376 :param message: The text content of the comment.
384 :param message: The text content of the comment.
377 :type message: str
385 :type message: str
378 :param status: (**Optional**) Set the approval status of the pull
386 :param status: (**Optional**) Set the approval status of the pull
379 request. Valid options are:
387 request. One of: 'not_reviewed', 'approved', 'rejected',
380 * not_reviewed
388 'under_review'
381 * approved
382 * rejected
383 * under_review
384 :type status: str
389 :type status: str
390 :param comment_type: Comment type, one of: 'note', 'todo'
391 :type comment_type: Optional(str), default: 'note'
385 :param userid: Comment on the pull request as this user
392 :param userid: Comment on the pull request as this user
386 :type userid: Optional(str or int)
393 :type userid: Optional(str or int)
387
394
@@ -393,7 +400,9 b' def comment_pull_request(request, apiuse'
393 result :
400 result :
394 {
401 {
395 "pull_request_id": "<Integer>",
402 "pull_request_id": "<Integer>",
396 "comment_id": "<Integer>"
403 "comment_id": "<Integer>",
404 "status": {"given": <given_status>,
405 "was_changed": <bool status_was_actually_changed> },
397 }
406 }
398 error : null
407 error : null
399 """
408 """
@@ -412,37 +421,68 b' def comment_pull_request(request, apiuse'
412 raise JSONRPCError('repository `%s` does not exist' % (repoid,))
421 raise JSONRPCError('repository `%s` does not exist' % (repoid,))
413 message = Optional.extract(message)
422 message = Optional.extract(message)
414 status = Optional.extract(status)
423 status = Optional.extract(status)
424 commit_id = Optional.extract(commit_id)
425 comment_type = Optional.extract(comment_type)
426 resolves_comment_id = Optional.extract(resolves_comment_id)
427
415 if not message and not status:
428 if not message and not status:
416 raise JSONRPCError('message and status parameter missing')
429 raise JSONRPCError(
430 'Both message and status parameters are missing. '
431 'At least one is required.')
417
432
418 if (status not in (st[0] for st in ChangesetStatus.STATUSES) and
433 if (status not in (st[0] for st in ChangesetStatus.STATUSES) and
419 status is not None):
434 status is not None):
420 raise JSONRPCError('unknown comment status`%s`' % status)
435 raise JSONRPCError('Unknown comment status: `%s`' % status)
436
437 if commit_id and commit_id not in pull_request.revisions:
438 raise JSONRPCError(
439 'Invalid commit_id `%s` for this pull request.' % commit_id)
421
440
422 allowed_to_change_status = PullRequestModel().check_user_change_status(
441 allowed_to_change_status = PullRequestModel().check_user_change_status(
423 pull_request, apiuser)
442 pull_request, apiuser)
443
444 # if commit_id is passed re-validated if user is allowed to change status
445 # based on latest commit_id from the PR
446 if commit_id:
447 commit_idx = pull_request.revisions.index(commit_id)
448 if commit_idx != 0:
449 allowed_to_change_status = False
450
451 if resolves_comment_id:
452 comment = ChangesetComment.get(resolves_comment_id)
453 if not comment:
454 raise JSONRPCError(
455 'Invalid resolves_comment_id `%s` for this pull request.'
456 % resolves_comment_id)
457 if comment.comment_type != ChangesetComment.COMMENT_TYPE_TODO:
458 raise JSONRPCError(
459 'Comment `%s` is wrong type for setting status to resolved.'
460 % resolves_comment_id)
461
424 text = message
462 text = message
463 status_label = ChangesetStatus.get_status_lbl(status)
425 if status and allowed_to_change_status:
464 if status and allowed_to_change_status:
426 st_message = (('Status change %(transition_icon)s %(status)s')
465 st_message = ('Status change %(transition_icon)s %(status)s'
427 % {'transition_icon': '>',
466 % {'transition_icon': '>', 'status': status_label})
428 'status': ChangesetStatus.get_status_lbl(status)})
429 text = message or st_message
467 text = message or st_message
430
468
431 rc_config = SettingsModel().get_all_settings()
469 rc_config = SettingsModel().get_all_settings()
432 renderer = rc_config.get('rhodecode_markup_renderer', 'rst')
470 renderer = rc_config.get('rhodecode_markup_renderer', 'rst')
433 comment = ChangesetCommentsModel().create(
471
472 status_change = status and allowed_to_change_status
473 comment = CommentsModel().create(
434 text=text,
474 text=text,
435 repo=pull_request.target_repo.repo_id,
475 repo=pull_request.target_repo.repo_id,
436 user=apiuser.user_id,
476 user=apiuser.user_id,
437 pull_request=pull_request.pull_request_id,
477 pull_request=pull_request.pull_request_id,
438 f_path=None,
478 f_path=None,
439 line_no=None,
479 line_no=None,
440 status_change=(ChangesetStatus.get_status_lbl(status)
480 status_change=(status_label if status_change else None),
441 if status and allowed_to_change_status else None),
481 status_change_type=(status if status_change else None),
442 status_change_type=(status
443 if status and allowed_to_change_status else None),
444 closing_pr=False,
482 closing_pr=False,
445 renderer=renderer
483 renderer=renderer,
484 comment_type=comment_type,
485 resolves_comment_id=resolves_comment_id
446 )
486 )
447
487
448 if allowed_to_change_status and status:
488 if allowed_to_change_status and status:
@@ -458,8 +498,8 b' def comment_pull_request(request, apiuse'
458 Session().commit()
498 Session().commit()
459 data = {
499 data = {
460 'pull_request_id': pull_request.pull_request_id,
500 'pull_request_id': pull_request.pull_request_id,
461 'comment_id': comment.comment_id,
501 'comment_id': comment.comment_id if comment else None,
462 'status': status
502 'status': {'given': status, 'was_changed': status_change},
463 }
503 }
464 return data
504 return data
465
505
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2011-2016 RhodeCode GmbH
3 # Copyright (C) 2011-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
@@ -34,9 +34,10 b' from rhodecode.lib.exceptions import Sta'
34 from rhodecode.lib.utils2 import str2bool, time_to_datetime
34 from rhodecode.lib.utils2 import str2bool, time_to_datetime
35 from rhodecode.lib.ext_json import json
35 from rhodecode.lib.ext_json import json
36 from rhodecode.model.changeset_status import ChangesetStatusModel
36 from rhodecode.model.changeset_status import ChangesetStatusModel
37 from rhodecode.model.comment import ChangesetCommentsModel
37 from rhodecode.model.comment import CommentsModel
38 from rhodecode.model.db import (
38 from rhodecode.model.db import (
39 Session, ChangesetStatus, RepositoryField, Repository)
39 Session, ChangesetStatus, RepositoryField, Repository, RepoGroup,
40 ChangesetComment)
40 from rhodecode.model.repo import RepoModel
41 from rhodecode.model.repo import RepoModel
41 from rhodecode.model.scm import ScmModel, RepoList
42 from rhodecode.model.scm import ScmModel, RepoList
42 from rhodecode.model.settings import SettingsModel, VcsSettingsModel
43 from rhodecode.model.settings import SettingsModel, VcsSettingsModel
@@ -217,7 +218,7 b' def get_repo(request, apiuser, repoid, c'
217
218
218
219
219 @jsonrpc_method()
220 @jsonrpc_method()
220 def get_repos(request, apiuser):
221 def get_repos(request, apiuser, root=Optional(None), traverse=Optional(True)):
221 """
222 """
222 Lists all existing repositories.
223 Lists all existing repositories.
223
224
@@ -226,6 +227,14 b' def get_repos(request, apiuser):'
226
227
227 :param apiuser: This is filled automatically from the |authtoken|.
228 :param apiuser: This is filled automatically from the |authtoken|.
228 :type apiuser: AuthUser
229 :type apiuser: AuthUser
230 :param root: specify root repository group to fetch repositories.
231 filters the returned repositories to be members of given root group.
232 :type root: Optional(None)
233 :param traverse: traverse given root into subrepositories. With this flag
234 set to False, it will only return top-level repositories from `root`.
235 if root is empty it will return just top-level repositories.
236 :type traverse: Optional(True)
237
229
238
230 Example output:
239 Example output:
231
240
@@ -257,8 +266,28 b' def get_repos(request, apiuser):'
257 _perms = ('repository.read', 'repository.write', 'repository.admin',)
266 _perms = ('repository.read', 'repository.write', 'repository.admin',)
258 extras = {'user': apiuser}
267 extras = {'user': apiuser}
259
268
260 repo_list = RepoList(
269 root = Optional.extract(root)
261 RepoModel().get_all(), perm_set=_perms, extra_kwargs=extras)
270 traverse = Optional.extract(traverse, binary=True)
271
272 if root:
273 # verify parent existance, if it's empty return an error
274 parent = RepoGroup.get_by_group_name(root)
275 if not parent:
276 raise JSONRPCError(
277 'Root repository group `{}` does not exist'.format(root))
278
279 if traverse:
280 repos = RepoModel().get_repos_for_root(root=root, traverse=traverse)
281 else:
282 repos = RepoModel().get_repos_for_root(root=parent)
283 else:
284 if traverse:
285 repos = RepoModel().get_all()
286 else:
287 # return just top-level
288 repos = RepoModel().get_repos_for_root(root=None)
289
290 repo_list = RepoList(repos, perm_set=_perms, extra_kwargs=extras)
262 return [repo.get_api_data(include_secrets=include_secrets)
291 return [repo.get_api_data(include_secrets=include_secrets)
263 for repo in repo_list]
292 for repo in repo_list]
264
293
@@ -1354,8 +1383,10 b' def lock(request, apiuser, repoid, locke'
1354
1383
1355 @jsonrpc_method()
1384 @jsonrpc_method()
1356 def comment_commit(
1385 def comment_commit(
1357 request, apiuser, repoid, commit_id, message,
1386 request, apiuser, repoid, commit_id, message, status=Optional(None),
1358 userid=Optional(OAttr('apiuser')), status=Optional(None)):
1387 comment_type=Optional(ChangesetComment.COMMENT_TYPE_NOTE),
1388 resolves_comment_id=Optional(None),
1389 userid=Optional(OAttr('apiuser'))):
1359 """
1390 """
1360 Set a commit comment, and optionally change the status of the commit.
1391 Set a commit comment, and optionally change the status of the commit.
1361
1392
@@ -1367,15 +1398,17 b' def comment_commit('
1367 :type commit_id: str
1398 :type commit_id: str
1368 :param message: The comment text.
1399 :param message: The comment text.
1369 :type message: str
1400 :type message: str
1401 :param status: (**Optional**) status of commit, one of: 'not_reviewed',
1402 'approved', 'rejected', 'under_review'
1403 :type status: str
1404 :param comment_type: Comment type, one of: 'note', 'todo'
1405 :type comment_type: Optional(str), default: 'note'
1370 :param userid: Set the user name of the comment creator.
1406 :param userid: Set the user name of the comment creator.
1371 :type userid: Optional(str or int)
1407 :type userid: Optional(str or int)
1372 :param status: status, one of 'not_reviewed', 'approved', 'rejected',
1373 'under_review'
1374 :type status: str
1375
1408
1376 Example error output:
1409 Example error output:
1377
1410
1378 .. code-block:: json
1411 .. code-block:: bash
1379
1412
1380 {
1413 {
1381 "id" : <id_given_in_input>,
1414 "id" : <id_given_in_input>,
@@ -1398,21 +1431,37 b' def comment_commit('
1398
1431
1399 user = get_user_or_error(userid)
1432 user = get_user_or_error(userid)
1400 status = Optional.extract(status)
1433 status = Optional.extract(status)
1434 comment_type = Optional.extract(comment_type)
1435 resolves_comment_id = Optional.extract(resolves_comment_id)
1401
1436
1402 allowed_statuses = [x[0] for x in ChangesetStatus.STATUSES]
1437 allowed_statuses = [x[0] for x in ChangesetStatus.STATUSES]
1403 if status and status not in allowed_statuses:
1438 if status and status not in allowed_statuses:
1404 raise JSONRPCError('Bad status, must be on '
1439 raise JSONRPCError('Bad status, must be on '
1405 'of %s got %s' % (allowed_statuses, status,))
1440 'of %s got %s' % (allowed_statuses, status,))
1406
1441
1442 if resolves_comment_id:
1443 comment = ChangesetComment.get(resolves_comment_id)
1444 if not comment:
1445 raise JSONRPCError(
1446 'Invalid resolves_comment_id `%s` for this commit.'
1447 % resolves_comment_id)
1448 if comment.comment_type != ChangesetComment.COMMENT_TYPE_TODO:
1449 raise JSONRPCError(
1450 'Comment `%s` is wrong type for setting status to resolved.'
1451 % resolves_comment_id)
1452
1407 try:
1453 try:
1408 rc_config = SettingsModel().get_all_settings()
1454 rc_config = SettingsModel().get_all_settings()
1409 renderer = rc_config.get('rhodecode_markup_renderer', 'rst')
1455 renderer = rc_config.get('rhodecode_markup_renderer', 'rst')
1410 status_change_label = ChangesetStatus.get_status_lbl(status)
1456 status_change_label = ChangesetStatus.get_status_lbl(status)
1411 comm = ChangesetCommentsModel().create(
1457 comm = CommentsModel().create(
1412 message, repo, user, revision=commit_id,
1458 message, repo, user, commit_id=commit_id,
1413 status_change=status_change_label,
1459 status_change=status_change_label,
1414 status_change_type=status,
1460 status_change_type=status,
1415 renderer=renderer)
1461 renderer=renderer,
1462 comment_type=comment_type,
1463 resolves_comment_id=resolves_comment_id
1464 )
1416 if status:
1465 if status:
1417 # also do a status change
1466 # also do a status change
1418 try:
1467 try:
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2011-2016 RhodeCode GmbH
3 # Copyright (C) 2011-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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2011-2016 RhodeCode GmbH
3 # Copyright (C) 2011-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
@@ -26,6 +26,8 b' from rhodecode.api import jsonrpc_method'
26 from rhodecode.api.utils import (
26 from rhodecode.api.utils import (
27 Optional, OAttr, has_superadmin_permission, get_user_or_error)
27 Optional, OAttr, has_superadmin_permission, get_user_or_error)
28 from rhodecode.lib.utils import repo2db_mapper
28 from rhodecode.lib.utils import repo2db_mapper
29 from rhodecode.lib import system_info
30 from rhodecode.lib import user_sessions
29 from rhodecode.model.db import UserIpMap
31 from rhodecode.model.db import UserIpMap
30 from rhodecode.model.scm import ScmModel
32 from rhodecode.model.scm import ScmModel
31
33
@@ -176,3 +178,67 b' def rescan_repos(request, apiuser, remov'
176 'Error occurred during rescan repositories action'
178 'Error occurred during rescan repositories action'
177 )
179 )
178
180
181
182 @jsonrpc_method()
183 def cleanup_sessions(request, apiuser, older_then=Optional(60)):
184 """
185 Triggers a session cleanup action.
186
187 If the ``older_then`` option is set, only sessions that hasn't been
188 accessed in the given number of days will be removed.
189
190 This command can only be run using an |authtoken| with admin rights to
191 the specified repository.
192
193 This command takes the following options:
194
195 :param apiuser: This is filled automatically from the |authtoken|.
196 :type apiuser: AuthUser
197 :param older_then: Deletes session that hasn't been accessed
198 in given number of days.
199 :type older_then: Optional(int)
200
201 Example output:
202
203 .. code-block:: bash
204
205 id : <id_given_in_input>
206 result: {
207 "backend": "<type of backend>",
208 "sessions_removed": <number_of_removed_sessions>
209 }
210 error : null
211
212 Example error output:
213
214 .. code-block:: bash
215
216 id : <id_given_in_input>
217 result : null
218 error : {
219 'Error occurred during session cleanup'
220 }
221
222 """
223 if not has_superadmin_permission(apiuser):
224 raise JSONRPCForbidden()
225
226 older_then = Optional.extract(older_then)
227 older_than_seconds = 60 * 60 * 24 * older_then
228
229 config = system_info.rhodecode_config().get_value()['value']['config']
230 session_model = user_sessions.get_session_handler(
231 config.get('beaker.session.type', 'memory'))(config)
232
233 backend = session_model.SESSION_TYPE
234 try:
235 cleaned = session_model.clean_sessions(
236 older_than_seconds=older_than_seconds)
237 return {'sessions_removed': cleaned, 'backend': backend}
238 except user_sessions.CleanupCommand as msg:
239 return {'cleanup_command': msg.message, 'backend': backend}
240 except Exception as e:
241 log.exception('Failed session cleanup')
242 raise JSONRPCError(
243 'Error occurred during session cleanup'
244 )
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2011-2016 RhodeCode GmbH
3 # Copyright (C) 2011-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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2011-2016 RhodeCode GmbH
3 # Copyright (C) 2011-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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2011-2016 RhodeCode GmbH
3 # Copyright (C) 2011-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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2012-2016 RhodeCode GmbH
3 # Copyright (C) 2012-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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2012-2016 RhodeCode GmbH
3 # Copyright (C) 2012-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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2012-2016 RhodeCode GmbH
3 # Copyright (C) 2012-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
@@ -197,14 +197,14 b' class RhodeCodeAuthPlugin(RhodeCodeExter'
197 config.add_view(
197 config.add_view(
198 'rhodecode.authentication.views.AuthnPluginViewBase',
198 'rhodecode.authentication.views.AuthnPluginViewBase',
199 attr='settings_get',
199 attr='settings_get',
200 renderer='rhodecode:templates/admin/auth/plugin_settings.html',
200 renderer='rhodecode:templates/admin/auth/plugin_settings.mako',
201 request_method='GET',
201 request_method='GET',
202 route_name='auth_home',
202 route_name='auth_home',
203 context=CrowdAuthnResource)
203 context=CrowdAuthnResource)
204 config.add_view(
204 config.add_view(
205 'rhodecode.authentication.views.AuthnPluginViewBase',
205 'rhodecode.authentication.views.AuthnPluginViewBase',
206 attr='settings_post',
206 attr='settings_post',
207 renderer='rhodecode:templates/admin/auth/plugin_settings.html',
207 renderer='rhodecode:templates/admin/auth/plugin_settings.mako',
208 request_method='POST',
208 request_method='POST',
209 route_name='auth_home',
209 route_name='auth_home',
210 context=CrowdAuthnResource)
210 context=CrowdAuthnResource)
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2012-2016 RhodeCode GmbH
3 # Copyright (C) 2012-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
@@ -83,14 +83,14 b' class RhodeCodeAuthPlugin(RhodeCodeExter'
83 config.add_view(
83 config.add_view(
84 'rhodecode.authentication.views.AuthnPluginViewBase',
84 'rhodecode.authentication.views.AuthnPluginViewBase',
85 attr='settings_get',
85 attr='settings_get',
86 renderer='rhodecode:templates/admin/auth/plugin_settings.html',
86 renderer='rhodecode:templates/admin/auth/plugin_settings.mako',
87 request_method='GET',
87 request_method='GET',
88 route_name='auth_home',
88 route_name='auth_home',
89 context=HeadersAuthnResource)
89 context=HeadersAuthnResource)
90 config.add_view(
90 config.add_view(
91 'rhodecode.authentication.views.AuthnPluginViewBase',
91 'rhodecode.authentication.views.AuthnPluginViewBase',
92 attr='settings_post',
92 attr='settings_post',
93 renderer='rhodecode:templates/admin/auth/plugin_settings.html',
93 renderer='rhodecode:templates/admin/auth/plugin_settings.mako',
94 request_method='POST',
94 request_method='POST',
95 route_name='auth_home',
95 route_name='auth_home',
96 context=HeadersAuthnResource)
96 context=HeadersAuthnResource)
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2012-2016 RhodeCode GmbH
3 # Copyright (C) 2012-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
@@ -74,14 +74,14 b' class RhodeCodeAuthPlugin(RhodeCodeExter'
74 config.add_view(
74 config.add_view(
75 'rhodecode.authentication.views.AuthnPluginViewBase',
75 'rhodecode.authentication.views.AuthnPluginViewBase',
76 attr='settings_get',
76 attr='settings_get',
77 renderer='rhodecode:templates/admin/auth/plugin_settings.html',
77 renderer='rhodecode:templates/admin/auth/plugin_settings.mako',
78 request_method='GET',
78 request_method='GET',
79 route_name='auth_home',
79 route_name='auth_home',
80 context=JasigCasAuthnResource)
80 context=JasigCasAuthnResource)
81 config.add_view(
81 config.add_view(
82 'rhodecode.authentication.views.AuthnPluginViewBase',
82 'rhodecode.authentication.views.AuthnPluginViewBase',
83 attr='settings_post',
83 attr='settings_post',
84 renderer='rhodecode:templates/admin/auth/plugin_settings.html',
84 renderer='rhodecode:templates/admin/auth/plugin_settings.mako',
85 request_method='POST',
85 request_method='POST',
86 route_name='auth_home',
86 route_name='auth_home',
87 context=JasigCasAuthnResource)
87 context=JasigCasAuthnResource)
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -332,14 +332,14 b' class RhodeCodeAuthPlugin(RhodeCodeExter'
332 config.add_view(
332 config.add_view(
333 'rhodecode.authentication.views.AuthnPluginViewBase',
333 'rhodecode.authentication.views.AuthnPluginViewBase',
334 attr='settings_get',
334 attr='settings_get',
335 renderer='rhodecode:templates/admin/auth/plugin_settings.html',
335 renderer='rhodecode:templates/admin/auth/plugin_settings.mako',
336 request_method='GET',
336 request_method='GET',
337 route_name='auth_home',
337 route_name='auth_home',
338 context=LdapAuthnResource)
338 context=LdapAuthnResource)
339 config.add_view(
339 config.add_view(
340 'rhodecode.authentication.views.AuthnPluginViewBase',
340 'rhodecode.authentication.views.AuthnPluginViewBase',
341 attr='settings_post',
341 attr='settings_post',
342 renderer='rhodecode:templates/admin/auth/plugin_settings.html',
342 renderer='rhodecode:templates/admin/auth/plugin_settings.mako',
343 request_method='POST',
343 request_method='POST',
344 route_name='auth_home',
344 route_name='auth_home',
345 context=LdapAuthnResource)
345 context=LdapAuthnResource)
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2012-2016 RhodeCode GmbH
3 # Copyright (C) 2012-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
@@ -82,14 +82,14 b' class RhodeCodeAuthPlugin(RhodeCodeExter'
82 config.add_view(
82 config.add_view(
83 'rhodecode.authentication.views.AuthnPluginViewBase',
83 'rhodecode.authentication.views.AuthnPluginViewBase',
84 attr='settings_get',
84 attr='settings_get',
85 renderer='rhodecode:templates/admin/auth/plugin_settings.html',
85 renderer='rhodecode:templates/admin/auth/plugin_settings.mako',
86 request_method='GET',
86 request_method='GET',
87 route_name='auth_home',
87 route_name='auth_home',
88 context=PamAuthnResource)
88 context=PamAuthnResource)
89 config.add_view(
89 config.add_view(
90 'rhodecode.authentication.views.AuthnPluginViewBase',
90 'rhodecode.authentication.views.AuthnPluginViewBase',
91 attr='settings_post',
91 attr='settings_post',
92 renderer='rhodecode:templates/admin/auth/plugin_settings.html',
92 renderer='rhodecode:templates/admin/auth/plugin_settings.mako',
93 request_method='POST',
93 request_method='POST',
94 route_name='auth_home',
94 route_name='auth_home',
95 context=PamAuthnResource)
95 context=PamAuthnResource)
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2012-2016 RhodeCode GmbH
3 # Copyright (C) 2012-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
@@ -52,14 +52,14 b' class RhodeCodeAuthPlugin(RhodeCodeAuthP'
52 config.add_view(
52 config.add_view(
53 'rhodecode.authentication.views.AuthnPluginViewBase',
53 'rhodecode.authentication.views.AuthnPluginViewBase',
54 attr='settings_get',
54 attr='settings_get',
55 renderer='rhodecode:templates/admin/auth/plugin_settings.html',
55 renderer='rhodecode:templates/admin/auth/plugin_settings.mako',
56 request_method='GET',
56 request_method='GET',
57 route_name='auth_home',
57 route_name='auth_home',
58 context=RhodecodeAuthnResource)
58 context=RhodecodeAuthnResource)
59 config.add_view(
59 config.add_view(
60 'rhodecode.authentication.views.AuthnPluginViewBase',
60 'rhodecode.authentication.views.AuthnPluginViewBase',
61 attr='settings_post',
61 attr='settings_post',
62 renderer='rhodecode:templates/admin/auth/plugin_settings.html',
62 renderer='rhodecode:templates/admin/auth/plugin_settings.mako',
63 request_method='POST',
63 request_method='POST',
64 route_name='auth_home',
64 route_name='auth_home',
65 context=RhodecodeAuthnResource)
65 context=RhodecodeAuthnResource)
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2016-2016 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
@@ -55,14 +55,14 b' class RhodeCodeAuthPlugin(RhodeCodeAuthP'
55 config.add_view(
55 config.add_view(
56 'rhodecode.authentication.views.AuthnPluginViewBase',
56 'rhodecode.authentication.views.AuthnPluginViewBase',
57 attr='settings_get',
57 attr='settings_get',
58 renderer='rhodecode:templates/admin/auth/plugin_settings.html',
58 renderer='rhodecode:templates/admin/auth/plugin_settings.mako',
59 request_method='GET',
59 request_method='GET',
60 route_name='auth_home',
60 route_name='auth_home',
61 context=RhodecodeAuthnResource)
61 context=RhodecodeAuthnResource)
62 config.add_view(
62 config.add_view(
63 'rhodecode.authentication.views.AuthnPluginViewBase',
63 'rhodecode.authentication.views.AuthnPluginViewBase',
64 attr='settings_post',
64 attr='settings_post',
65 renderer='rhodecode:templates/admin/auth/plugin_settings.html',
65 renderer='rhodecode:templates/admin/auth/plugin_settings.mako',
66 request_method='POST',
66 request_method='POST',
67 route_name='auth_home',
67 route_name='auth_home',
68 context=RhodecodeAuthnResource)
68 context=RhodecodeAuthnResource)
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2012-2016 RhodeCode GmbH
3 # Copyright (C) 2012-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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2012-2016 RhodeCode GmbH
3 # Copyright (C) 2012-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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2012-2016 RhodeCode GmbH
3 # Copyright (C) 2012-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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2016-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2016-2016 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
@@ -1,4 +1,4 b''
1 # Copyright (C) 2016 RhodeCode GmbH
1 # Copyright (C) 2017 RhodeCode GmbH
2 #
2 #
3 # This program is free software: you can redistribute it and/or modify
3 # This program is free software: you can redistribute it and/or modify
4 # it under the terms of the GNU Affero General Public License, version 3
4 # it under the terms of the GNU Affero General Public License, version 3
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2012-2016 RhodeCode GmbH
3 # Copyright (C) 2012-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
@@ -134,7 +134,7 b' class AuthSettingsView(object):'
134 'available_plugins': authn_registry.get_plugins(),
134 'available_plugins': authn_registry.get_plugins(),
135 'enabled_plugins': enabled_plugins,
135 'enabled_plugins': enabled_plugins,
136 }
136 }
137 html = render('rhodecode:templates/admin/auth/auth_settings.html',
137 html = render('rhodecode:templates/admin/auth/auth_settings.mako',
138 template_context,
138 template_context,
139 request=self.request)
139 request=self.request)
140
140
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -46,7 +46,7 b' PLUGIN_DEFINITION = {'
46 'javascript': [],
46 'javascript': [],
47 'css': [],
47 'css': [],
48 'template_hooks': {
48 'template_hooks': {
49 'plugin_init_template': 'rhodecode:templates/channelstream/plugin_init.html'
49 'plugin_init_template': 'rhodecode:templates/channelstream/plugin_init.mako'
50 },
50 },
51 'url_gen': url_gen,
51 'url_gen': url_gen,
52 'static': None,
52 'static': None,
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -62,7 +62,7 b' class ChannelstreamView(object):'
62 registry = request.registry
62 registry = request.registry
63 self.channelstream_config = registry.rhodecode_plugins['channelstream']
63 self.channelstream_config = registry.rhodecode_plugins['channelstream']
64 if not self.channelstream_config.get('enabled'):
64 if not self.channelstream_config.get('enabled'):
65 log.exception('Channelstream plugin is disabled')
65 log.error('Channelstream plugin is disabled')
66 raise HTTPBadRequest()
66 raise HTTPBadRequest()
67
67
68 @NotAnonymous()
68 @NotAnonymous()
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2013-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -52,7 +52,8 b' from rhodecode.lib.middleware.https_fixu'
52 from rhodecode.lib.middleware.vcs import VCSMiddleware
52 from rhodecode.lib.middleware.vcs import VCSMiddleware
53 from rhodecode.lib.plugins.utils import register_rhodecode_plugin
53 from rhodecode.lib.plugins.utils import register_rhodecode_plugin
54 from rhodecode.lib.utils2 import aslist as rhodecode_aslist
54 from rhodecode.lib.utils2 import aslist as rhodecode_aslist
55 from rhodecode.subscribers import scan_repositories_if_enabled
55 from rhodecode.subscribers import (
56 scan_repositories_if_enabled, write_metadata_if_needed)
56
57
57
58
58 log = logging.getLogger(__name__)
59 log = logging.getLogger(__name__)
@@ -232,6 +233,14 b' def error_handler(exception, request):'
232 if isinstance(exception, HTTPError):
233 if isinstance(exception, HTTPError):
233 base_response = exception
234 base_response = exception
234
235
236 def is_http_error(response):
237 # error which should have traceback
238 return response.status_code > 499
239
240 if is_http_error(base_response):
241 log.exception(
242 'error occurred handling this request for path: %s', request.path)
243
235 c = AttributeDict()
244 c = AttributeDict()
236 c.error_message = base_response.status
245 c.error_message = base_response.status
237 c.error_explanation = base_response.explanation or str(base_response)
246 c.error_explanation = base_response.explanation or str(base_response)
@@ -251,7 +260,7 b' def error_handler(exception, request):'
251 c.causes = base_response.causes
260 c.causes = base_response.causes
252
261
253 response = render_to_response(
262 response = render_to_response(
254 '/errors/error_document.html', {'c': c}, request=request,
263 '/errors/error_document.mako', {'c': c}, request=request,
255 response=base_response)
264 response=base_response)
256
265
257 return response
266 return response
@@ -283,8 +292,12 b' def includeme(config):'
283 config.add_route(
292 config.add_route(
284 'rhodecode_support', 'https://rhodecode.com/help/', static=True)
293 'rhodecode_support', 'https://rhodecode.com/help/', static=True)
285
294
295 config.add_translation_dirs('rhodecode:i18n/')
296 settings['default_locale_name'] = settings.get('lang', 'en')
297
286 # Add subscribers.
298 # Add subscribers.
287 config.add_subscriber(scan_repositories_if_enabled, ApplicationCreated)
299 config.add_subscriber(scan_repositories_if_enabled, ApplicationCreated)
300 config.add_subscriber(write_metadata_if_needed, ApplicationCreated)
288
301
289 # Set the authorization policy.
302 # Set the authorization policy.
290 authz_policy = ACLAuthorizationPolicy()
303 authz_policy = ACLAuthorizationPolicy()
@@ -320,6 +333,13 b' def includeme_first(config):'
320 config.add_view(favicon_redirect, route_name='favicon')
333 config.add_view(favicon_redirect, route_name='favicon')
321 config.add_route('favicon', '/favicon.ico')
334 config.add_route('favicon', '/favicon.ico')
322
335
336 def robots_redirect(context, request):
337 return HTTPFound(
338 request.static_path('rhodecode:public/robots.txt'))
339
340 config.add_view(robots_redirect, route_name='robots')
341 config.add_route('robots', '/robots.txt')
342
323 config.add_static_view(
343 config.add_static_view(
324 '_static/deform', 'deform:static')
344 '_static/deform', 'deform:static')
325 config.add_static_view(
345 config.add_static_view(
@@ -351,7 +371,6 b' def wrap_app_in_wsgi_middlewares(pyramid'
351 pyramid_app = make_gzip_middleware(
371 pyramid_app = make_gzip_middleware(
352 pyramid_app, settings, compress_level=1)
372 pyramid_app, settings, compress_level=1)
353
373
354
355 # this should be the outer most middleware in the wsgi stack since
374 # this should be the outer most middleware in the wsgi stack since
356 # middleware like Routes make database calls
375 # middleware like Routes make database calls
357 def pyramid_app_with_cleanup(environ, start_response):
376 def pyramid_app_with_cleanup(environ, start_response):
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2016-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -503,12 +503,6 b' def make_map(config):'
503 m.connect('admin_settings_search', '/settings/search',
503 m.connect('admin_settings_search', '/settings/search',
504 action='settings_search', conditions={'method': ['GET']})
504 action='settings_search', conditions={'method': ['GET']})
505
505
506 m.connect('admin_settings_system', '/settings/system',
507 action='settings_system', conditions={'method': ['GET']})
508
509 m.connect('admin_settings_system_update', '/settings/system/updates',
510 action='settings_system_update', conditions={'method': ['GET']})
511
512 m.connect('admin_settings_supervisor', '/settings/supervisor',
506 m.connect('admin_settings_supervisor', '/settings/supervisor',
513 action='settings_supervisor', conditions={'method': ['GET']})
507 action='settings_supervisor', conditions={'method': ['GET']})
514 m.connect('admin_settings_supervisor_log', '/settings/supervisor/{procid}/log',
508 m.connect('admin_settings_supervisor_log', '/settings/supervisor/{procid}/log',
@@ -566,6 +560,10 b' def make_map(config):'
566 '/my_account/toggle_visibility',
560 '/my_account/toggle_visibility',
567 action='my_notifications_toggle_visibility',
561 action='my_notifications_toggle_visibility',
568 conditions={'method': ['POST']})
562 conditions={'method': ['POST']})
563 m.connect('my_account_notifications_test_channelstream',
564 '/my_account/test_channelstream',
565 action='my_account_notifications_test_channelstream',
566 conditions={'method': ['POST']})
569
567
570 # NOTIFICATION REST ROUTES
568 # NOTIFICATION REST ROUTES
571 with rmap.submapper(path_prefix=ADMIN_PREFIX,
569 with rmap.submapper(path_prefix=ADMIN_PREFIX,
@@ -624,9 +622,11 b' def make_map(config):'
624 'pull_requests_global_0', '/pull_requests/{pull_request_id:[0-9]+}',
622 'pull_requests_global_0', '/pull_requests/{pull_request_id:[0-9]+}',
625 action='pull_requests')
623 action='pull_requests')
626 m.connect(
624 m.connect(
627 'pull_requests_global', '/pull-requests/{pull_request_id:[0-9]+}',
625 'pull_requests_global_1', '/pull-requests/{pull_request_id:[0-9]+}',
628 action='pull_requests')
626 action='pull_requests')
629
627 m.connect(
628 'pull_requests_global', '/pull-request/{pull_request_id:[0-9]+}',
629 action='pull_requests')
630
630
631 # USER JOURNAL
631 # USER JOURNAL
632 rmap.connect('journal', '%s/journal' % (ADMIN_PREFIX,),
632 rmap.connect('journal', '%s/journal' % (ADMIN_PREFIX,),
@@ -694,8 +694,8 b' def make_map(config):'
694 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
694 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
695
695
696 rmap.connect('repo_refs_data', '/{repo_name}/refs-data',
696 rmap.connect('repo_refs_data', '/{repo_name}/refs-data',
697 controller='summary', action='repo_refs_data', jsroute=True,
697 controller='summary', action='repo_refs_data',
698 requirements=URL_NAME_REQUIREMENTS)
698 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
699 rmap.connect('repo_refs_changelog_data', '/{repo_name}/refs-data-changelog',
699 rmap.connect('repo_refs_changelog_data', '/{repo_name}/refs-data-changelog',
700 controller='summary', action='repo_refs_changelog_data',
700 controller='summary', action='repo_refs_changelog_data',
701 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
701 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
@@ -704,9 +704,9 b' def make_map(config):'
704 jsroute=True, requirements=URL_NAME_REQUIREMENTS)
704 jsroute=True, requirements=URL_NAME_REQUIREMENTS)
705
705
706 rmap.connect('changeset_home', '/{repo_name}/changeset/{revision}',
706 rmap.connect('changeset_home', '/{repo_name}/changeset/{revision}',
707 controller='changeset', revision='tip', jsroute=True,
707 controller='changeset', revision='tip',
708 conditions={'function': check_repo},
708 conditions={'function': check_repo},
709 requirements=URL_NAME_REQUIREMENTS)
709 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
710 rmap.connect('changeset_children', '/{repo_name}/changeset_children/{revision}',
710 rmap.connect('changeset_children', '/{repo_name}/changeset_children/{revision}',
711 controller='changeset', revision='tip', action='changeset_children',
711 controller='changeset', revision='tip', action='changeset_children',
712 conditions={'function': check_repo},
712 conditions={'function': check_repo},
@@ -923,7 +923,7 b' def make_map(config):'
923 controller='pullrequests',
923 controller='pullrequests',
924 action='show', conditions={'function': check_repo,
924 action='show', conditions={'function': check_repo,
925 'method': ['GET']},
925 'method': ['GET']},
926 requirements=URL_NAME_REQUIREMENTS)
926 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
927
927
928 rmap.connect('pullrequest_update',
928 rmap.connect('pullrequest_update',
929 '/{repo_name}/pull-request/{pull_request_id}',
929 '/{repo_name}/pull-request/{pull_request_id}',
@@ -997,10 +997,10 b' def make_map(config):'
997 conditions={'function': check_repo},
997 conditions={'function': check_repo},
998 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
998 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
999
999
1000 rmap.connect('changelog_details', '/{repo_name}/changelog_details/{cs}',
1000 rmap.connect('changelog_elements', '/{repo_name}/changelog_details',
1001 controller='changelog', action='changelog_details',
1001 controller='changelog', action='changelog_elements',
1002 conditions={'function': check_repo},
1002 conditions={'function': check_repo},
1003 requirements=URL_NAME_REQUIREMENTS)
1003 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
1004
1004
1005 rmap.connect('files_home', '/{repo_name}/files/{revision}/{f_path}',
1005 rmap.connect('files_home', '/{repo_name}/files/{revision}/{f_path}',
1006 controller='files', revision='tip', f_path='',
1006 controller='files', revision='tip', f_path='',
@@ -1064,7 +1064,7 b' def make_map(config):'
1064 '/{repo_name}/annotate/{revision}/{f_path}',
1064 '/{repo_name}/annotate/{revision}/{f_path}',
1065 controller='files', action='index', revision='tip',
1065 controller='files', action='index', revision='tip',
1066 f_path='', annotate=True, conditions={'function': check_repo},
1066 f_path='', annotate=True, conditions={'function': check_repo},
1067 requirements=URL_NAME_REQUIREMENTS)
1067 requirements=URL_NAME_REQUIREMENTS, jsroute=True)
1068
1068
1069 rmap.connect('files_edit',
1069 rmap.connect('files_edit',
1070 '/{repo_name}/edit/{revision}/{f_path}',
1070 '/{repo_name}/edit/{revision}/{f_path}',
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -153,11 +153,11 b' class AdminController(BaseController):'
153
153
154 c.users_log = Page(users_log, page=p, items_per_page=10,
154 c.users_log = Page(users_log, page=p, items_per_page=10,
155 url=url_generator)
155 url=url_generator)
156 c.log_data = render('admin/admin_log.html')
156 c.log_data = render('admin/admin_log.mako')
157
157
158 if request.is_xhr:
158 if request.is_xhr:
159 return c.log_data
159 return c.log_data
160 return render('admin/admin.html')
160 return render('admin/admin.mako')
161
161
162 # global redirect doesn't need permissions
162 # global redirect doesn't need permissions
163 def pull_requests(self, pull_request_id):
163 def pull_requests(self, pull_request_id):
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -57,7 +57,7 b' class DefaultsController(BaseController)'
57 defaults = SettingsModel().get_default_repo_settings()
57 defaults = SettingsModel().get_default_repo_settings()
58
58
59 return htmlfill.render(
59 return htmlfill.render(
60 render('admin/defaults/defaults.html'),
60 render('admin/defaults/defaults.mako'),
61 defaults=defaults,
61 defaults=defaults,
62 encoding="UTF-8",
62 encoding="UTF-8",
63 force_defaults=False
63 force_defaults=False
@@ -88,7 +88,7 b' class DefaultsController(BaseController)'
88 defaults = errors.value
88 defaults = errors.value
89
89
90 return htmlfill.render(
90 return htmlfill.render(
91 render('admin/defaults/defaults.html'),
91 render('admin/defaults/defaults.mako'),
92 defaults=defaults,
92 defaults=defaults,
93 errors=errors.error_dict or {},
93 errors=errors.error_dict or {},
94 prefix_error=False,
94 prefix_error=False,
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2013-2016 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
@@ -114,7 +114,7 b' class GistsController(BaseController):'
114 c.active = 'public'
114 c.active = 'public'
115
115
116 from rhodecode.lib.utils import PartialRenderer
116 from rhodecode.lib.utils import PartialRenderer
117 _render = PartialRenderer('data_table/_dt_elements.html')
117 _render = PartialRenderer('data_table/_dt_elements.mako')
118
118
119 data = []
119 data = []
120
120
@@ -130,7 +130,7 b' class GistsController(BaseController):'
130 'description': _render('gist_description', gist.gist_description)
130 'description': _render('gist_description', gist.gist_description)
131 })
131 })
132 c.data = json.dumps(data)
132 c.data = json.dumps(data)
133 return render('admin/gists/index.html')
133 return render('admin/gists/index.mako')
134
134
135 @LoginRequired()
135 @LoginRequired()
136 @NotAnonymous()
136 @NotAnonymous()
@@ -186,7 +186,7 b' class GistsController(BaseController):'
186 del errors['nodes.0.filename']
186 del errors['nodes.0.filename']
187
187
188 return formencode.htmlfill.render(
188 return formencode.htmlfill.render(
189 render('admin/gists/new.html'),
189 render('admin/gists/new.mako'),
190 defaults=defaults,
190 defaults=defaults,
191 errors=errors,
191 errors=errors,
192 prefix_error=False,
192 prefix_error=False,
@@ -202,11 +202,11 b' class GistsController(BaseController):'
202
202
203 @LoginRequired()
203 @LoginRequired()
204 @NotAnonymous()
204 @NotAnonymous()
205 def new(self, format='html'):
205 def new(self):
206 """GET /admin/gists/new: Form to create a new item"""
206 """GET /admin/gists/new: Form to create a new item"""
207 # url('new_gist')
207 # url('new_gist')
208 self.__load_defaults()
208 self.__load_defaults()
209 return render('admin/gists/new.html')
209 return render('admin/gists/new.mako')
210
210
211 @LoginRequired()
211 @LoginRequired()
212 @NotAnonymous()
212 @NotAnonymous()
@@ -266,7 +266,7 b' class GistsController(BaseController):'
266 if (f_path is None or f.path == f_path)])
266 if (f_path is None or f.path == f_path)])
267 response.content_type = 'text/plain'
267 response.content_type = 'text/plain'
268 return content
268 return content
269 return render('admin/gists/show.html')
269 return render('admin/gists/show.mako')
270
270
271 @LoginRequired()
271 @LoginRequired()
272 @NotAnonymous()
272 @NotAnonymous()
@@ -322,7 +322,9 b' class GistsController(BaseController):'
322
322
323 @LoginRequired()
323 @LoginRequired()
324 @NotAnonymous()
324 @NotAnonymous()
325 def edit_form(self, gist_id, format='html'):
325 def edit_form(self, gist_id):
326 translate = _ = c.pyramid_request.translate
327
326 """GET /admin/gists/gist_id/edit: Form to edit an existing item"""
328 """GET /admin/gists/gist_id/edit: Form to edit an existing item"""
327 # url('edit_gist', gist_id=ID)
329 # url('edit_gist', gist_id=ID)
328 self._add_gist_to_context(gist_id)
330 self._add_gist_to_context(gist_id)
@@ -342,9 +344,11 b' class GistsController(BaseController):'
342 else:
344 else:
343 # this cannot use timeago, since it's used in select2 as a value
345 # this cannot use timeago, since it's used in select2 as a value
344 expiry = h.age(h.time_to_datetime(c.gist.gist_expires))
346 expiry = h.age(h.time_to_datetime(c.gist.gist_expires))
347
348 expiry = translate(expiry)
345 self.__load_defaults(
349 self.__load_defaults(
346 extra_values=(0, _('%(expiry)s - current value') % {'expiry': expiry}))
350 extra_values=(0, _('%(expiry)s - current value') % {'expiry': expiry}))
347 return render('admin/gists/edit.html')
351 return render('admin/gists/edit.mako')
348
352
349 @LoginRequired()
353 @LoginRequired()
350 @NotAnonymous()
354 @NotAnonymous()
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2013-2016 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
@@ -24,13 +24,16 b' my account controller for RhodeCode admi'
24 """
24 """
25
25
26 import logging
26 import logging
27 import datetime
27
28
28 import formencode
29 import formencode
29 from formencode import htmlfill
30 from formencode import htmlfill
31 from pyramid.threadlocal import get_current_registry
30 from pylons import request, tmpl_context as c, url, session
32 from pylons import request, tmpl_context as c, url, session
31 from pylons.controllers.util import redirect
33 from pylons.controllers.util import redirect
32 from pylons.i18n.translation import _
34 from pylons.i18n.translation import _
33 from sqlalchemy.orm import joinedload
35 from sqlalchemy.orm import joinedload
36 from webob.exc import HTTPBadGateway
34
37
35 from rhodecode import forms
38 from rhodecode import forms
36 from rhodecode.lib import helpers as h
39 from rhodecode.lib import helpers as h
@@ -41,6 +44,8 b' from rhodecode.lib.base import BaseContr'
41 from rhodecode.lib.utils import jsonify
44 from rhodecode.lib.utils import jsonify
42 from rhodecode.lib.utils2 import safe_int, md5, str2bool
45 from rhodecode.lib.utils2 import safe_int, md5, str2bool
43 from rhodecode.lib.ext_json import json
46 from rhodecode.lib.ext_json import json
47 from rhodecode.lib.channelstream import channelstream_request, \
48 ChannelstreamException
44
49
45 from rhodecode.model.validation_schema.schemas import user_schema
50 from rhodecode.model.validation_schema.schemas import user_schema
46 from rhodecode.model.db import (
51 from rhodecode.model.db import (
@@ -52,7 +57,7 b' from rhodecode.model.repo import RepoMod'
52 from rhodecode.model.auth_token import AuthTokenModel
57 from rhodecode.model.auth_token import AuthTokenModel
53 from rhodecode.model.meta import Session
58 from rhodecode.model.meta import Session
54 from rhodecode.model.pull_request import PullRequestModel
59 from rhodecode.model.pull_request import PullRequestModel
55 from rhodecode.model.comment import ChangesetCommentsModel
60 from rhodecode.model.comment import CommentsModel
56
61
57 log = logging.getLogger(__name__)
62 log = logging.getLogger(__name__)
58
63
@@ -76,6 +81,9 b' class MyAccountController(BaseController'
76 " crucial for entire application"), category='warning')
81 " crucial for entire application"), category='warning')
77 return redirect(url('users'))
82 return redirect(url('users'))
78
83
84 c.auth_user = AuthUser(
85 user_id=c.rhodecode_user.user_id, ip_addr=self.ip_addr)
86
79 def _load_my_repos_data(self, watched=False):
87 def _load_my_repos_data(self, watched=False):
80 if watched:
88 if watched:
81 admin = False
89 admin = False
@@ -104,8 +112,7 b' class MyAccountController(BaseController'
104 # url('my_account')
112 # url('my_account')
105 c.active = 'profile_edit'
113 c.active = 'profile_edit'
106 self.__load_data()
114 self.__load_data()
107 c.perm_user = AuthUser(user_id=c.rhodecode_user.user_id,
115 c.perm_user = c.auth_user
108 ip_addr=self.ip_addr)
109 c.extern_type = c.user.extern_type
116 c.extern_type = c.user.extern_type
110 c.extern_name = c.user.extern_name
117 c.extern_name = c.user.extern_name
111
118
@@ -137,7 +144,7 b' class MyAccountController(BaseController'
137
144
138 except formencode.Invalid as errors:
145 except formencode.Invalid as errors:
139 return htmlfill.render(
146 return htmlfill.render(
140 render('admin/my_account/my_account.html'),
147 render('admin/my_account/my_account.mako'),
141 defaults=errors.value,
148 defaults=errors.value,
142 errors=errors.error_dict or {},
149 errors=errors.error_dict or {},
143 prefix_error=False,
150 prefix_error=False,
@@ -152,7 +159,7 b' class MyAccountController(BaseController'
152 return redirect('my_account')
159 return redirect('my_account')
153
160
154 return htmlfill.render(
161 return htmlfill.render(
155 render('admin/my_account/my_account.html'),
162 render('admin/my_account/my_account.mako'),
156 defaults=defaults,
163 defaults=defaults,
157 encoding="UTF-8",
164 encoding="UTF-8",
158 force_defaults=False
165 force_defaults=False
@@ -168,7 +175,7 b' class MyAccountController(BaseController'
168
175
169 defaults = c.user.get_dict()
176 defaults = c.user.get_dict()
170 return htmlfill.render(
177 return htmlfill.render(
171 render('admin/my_account/my_account.html'),
178 render('admin/my_account/my_account.mako'),
172 defaults=defaults, encoding="UTF-8", force_defaults=False)
179 defaults=defaults, encoding="UTF-8", force_defaults=False)
173
180
174 def my_account_edit(self):
181 def my_account_edit(self):
@@ -177,14 +184,13 b' class MyAccountController(BaseController'
177 """
184 """
178 c.active = 'profile_edit'
185 c.active = 'profile_edit'
179 self.__load_data()
186 self.__load_data()
180 c.perm_user = AuthUser(user_id=c.rhodecode_user.user_id,
187 c.perm_user = c.auth_user
181 ip_addr=self.ip_addr)
182 c.extern_type = c.user.extern_type
188 c.extern_type = c.user.extern_type
183 c.extern_name = c.user.extern_name
189 c.extern_name = c.user.extern_name
184
190
185 defaults = c.user.get_dict()
191 defaults = c.user.get_dict()
186 return htmlfill.render(
192 return htmlfill.render(
187 render('admin/my_account/my_account.html'),
193 render('admin/my_account/my_account.mako'),
188 defaults=defaults,
194 defaults=defaults,
189 encoding="UTF-8",
195 encoding="UTF-8",
190 force_defaults=False
196 force_defaults=False
@@ -194,6 +200,7 b' class MyAccountController(BaseController'
194 def my_account_password(self):
200 def my_account_password(self):
195 c.active = 'password'
201 c.active = 'password'
196 self.__load_data()
202 self.__load_data()
203 c.extern_type = c.user.extern_type
197
204
198 schema = user_schema.ChangePasswordSchema().bind(
205 schema = user_schema.ChangePasswordSchema().bind(
199 username=c.rhodecode_user.username)
206 username=c.rhodecode_user.username)
@@ -201,7 +208,7 b' class MyAccountController(BaseController'
201 form = forms.Form(schema,
208 form = forms.Form(schema,
202 buttons=(forms.buttons.save, forms.buttons.reset))
209 buttons=(forms.buttons.save, forms.buttons.reset))
203
210
204 if request.method == 'POST':
211 if request.method == 'POST' and c.extern_type == 'rhodecode':
205 controls = request.POST.items()
212 controls = request.POST.items()
206 try:
213 try:
207 valid_data = form.validate(controls)
214 valid_data = form.validate(controls)
@@ -228,7 +235,7 b' class MyAccountController(BaseController'
228 return redirect(url('my_account_password'))
235 return redirect(url('my_account_password'))
229
236
230 c.form = form
237 c.form = form
231 return render('admin/my_account/my_account.html')
238 return render('admin/my_account/my_account.mako')
232
239
233 def my_account_repos(self):
240 def my_account_repos(self):
234 c.active = 'repos'
241 c.active = 'repos'
@@ -236,7 +243,7 b' class MyAccountController(BaseController'
236
243
237 # json used to render the grid
244 # json used to render the grid
238 c.data = self._load_my_repos_data()
245 c.data = self._load_my_repos_data()
239 return render('admin/my_account/my_account.html')
246 return render('admin/my_account/my_account.mako')
240
247
241 def my_account_watched(self):
248 def my_account_watched(self):
242 c.active = 'watched'
249 c.active = 'watched'
@@ -244,15 +251,14 b' class MyAccountController(BaseController'
244
251
245 # json used to render the grid
252 # json used to render the grid
246 c.data = self._load_my_repos_data(watched=True)
253 c.data = self._load_my_repos_data(watched=True)
247 return render('admin/my_account/my_account.html')
254 return render('admin/my_account/my_account.mako')
248
255
249 def my_account_perms(self):
256 def my_account_perms(self):
250 c.active = 'perms'
257 c.active = 'perms'
251 self.__load_data()
258 self.__load_data()
252 c.perm_user = AuthUser(user_id=c.rhodecode_user.user_id,
259 c.perm_user = c.auth_user
253 ip_addr=self.ip_addr)
254
260
255 return render('admin/my_account/my_account.html')
261 return render('admin/my_account/my_account.mako')
256
262
257 def my_account_emails(self):
263 def my_account_emails(self):
258 c.active = 'emails'
264 c.active = 'emails'
@@ -260,7 +266,7 b' class MyAccountController(BaseController'
260
266
261 c.user_email_map = UserEmailMap.query()\
267 c.user_email_map = UserEmailMap.query()\
262 .filter(UserEmailMap.user == c.user).all()
268 .filter(UserEmailMap.user == c.user).all()
263 return render('admin/my_account/my_account.html')
269 return render('admin/my_account/my_account.mako')
264
270
265 @auth.CSRFRequired()
271 @auth.CSRFRequired()
266 def my_account_emails_add(self):
272 def my_account_emails_add(self):
@@ -312,11 +318,11 b' class MyAccountController(BaseController'
312 user_id=c.rhodecode_user.user_id, statuses=statuses)
318 user_id=c.rhodecode_user.user_id, statuses=statuses)
313
319
314 from rhodecode.lib.utils import PartialRenderer
320 from rhodecode.lib.utils import PartialRenderer
315 _render = PartialRenderer('data_table/_dt_elements.html')
321 _render = PartialRenderer('data_table/_dt_elements.mako')
316 data = []
322 data = []
317 for pr in pull_requests:
323 for pr in pull_requests:
318 repo_id = pr.target_repo_id
324 repo_id = pr.target_repo_id
319 comments = ChangesetCommentsModel().get_all_comments(
325 comments = CommentsModel().get_all_comments(
320 repo_id, pull_request=pr)
326 repo_id, pull_request=pr)
321 owned = pr.user_id == c.rhodecode_user.user_id
327 owned = pr.user_id == c.rhodecode_user.user_id
322 status = pr.calculated_review_status()
328 status = pr.calculated_review_status()
@@ -366,7 +372,7 b' class MyAccountController(BaseController'
366 if not request.is_xhr:
372 if not request.is_xhr:
367 c.data_participate = json.dumps(data['data'])
373 c.data_participate = json.dumps(data['data'])
368 c.records_total_participate = data['recordsTotal']
374 c.records_total_participate = data['recordsTotal']
369 return render('admin/my_account/my_account.html')
375 return render('admin/my_account/my_account.mako')
370 else:
376 else:
371 return json.dumps(data)
377 return json.dumps(data)
372
378
@@ -387,7 +393,7 b' class MyAccountController(BaseController'
387 c.role_options = [(c.role_values, _("Role"))]
393 c.role_options = [(c.role_values, _("Role"))]
388 c.user_auth_tokens = AuthTokenModel().get_auth_tokens(
394 c.user_auth_tokens = AuthTokenModel().get_auth_tokens(
389 c.rhodecode_user.user_id, show_expired=show_expired)
395 c.rhodecode_user.user_id, show_expired=show_expired)
390 return render('admin/my_account/my_account.html')
396 return render('admin/my_account/my_account.mako')
391
397
392 @auth.CSRFRequired()
398 @auth.CSRFRequired()
393 def my_account_auth_tokens_add(self):
399 def my_account_auth_tokens_add(self):
@@ -420,7 +426,7 b' class MyAccountController(BaseController'
420
426
421 def my_notifications(self):
427 def my_notifications(self):
422 c.active = 'notifications'
428 c.active = 'notifications'
423 return render('admin/my_account/my_account.html')
429 return render('admin/my_account/my_account.mako')
424
430
425 @auth.CSRFRequired()
431 @auth.CSRFRequired()
426 @jsonify
432 @jsonify
@@ -430,3 +436,33 b' class MyAccountController(BaseController'
430 user.update_userdata(notification_status=new_status)
436 user.update_userdata(notification_status=new_status)
431 Session().commit()
437 Session().commit()
432 return user.user_data['notification_status']
438 return user.user_data['notification_status']
439
440 @auth.CSRFRequired()
441 @jsonify
442 def my_account_notifications_test_channelstream(self):
443 message = 'Test message sent via Channelstream by user: {}, on {}'.format(
444 c.rhodecode_user.username, datetime.datetime.now())
445 payload = {
446 'type': 'message',
447 'timestamp': datetime.datetime.utcnow(),
448 'user': 'system',
449 #'channel': 'broadcast',
450 'pm_users': [c.rhodecode_user.username],
451 'message': {
452 'message': message,
453 'level': 'info',
454 'topic': '/notifications'
455 }
456 }
457
458 registry = get_current_registry()
459 rhodecode_plugins = getattr(registry, 'rhodecode_plugins', {})
460 channelstream_config = rhodecode_plugins.get('channelstream', {})
461
462 try:
463 channelstream_request(channelstream_config, [payload], '/message')
464 except ChannelstreamException as e:
465 log.exception('Failed to send channelstream data')
466 return {"response": 'ERROR: {}'.format(e.__class__.__name__)}
467 return {"response": 'Channelstream data sent. '
468 'You should see a new live message now.'}
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -82,9 +82,9 b' class NotificationsController(BaseContro'
82 c.current_filter = 'comment'
82 c.current_filter = 'comment'
83
83
84 if request.is_xhr:
84 if request.is_xhr:
85 return render('admin/notifications/notifications_data.html')
85 return render('admin/notifications/notifications_data.mako')
86
86
87 return render('admin/notifications/notifications.html')
87 return render('admin/notifications/notifications.mako')
88
88
89
89
90 @auth.CSRFRequired()
90 @auth.CSRFRequired()
@@ -102,7 +102,7 b' class NotificationsController(BaseContro'
102 url('notifications'), request.GET)
102 url('notifications'), request.GET)
103 c.notifications = Page(notif, page=1, items_per_page=10,
103 c.notifications = Page(notif, page=1, items_per_page=10,
104 url=notifications_url)
104 url=notifications_url)
105 return render('admin/notifications/notifications_data.html')
105 return render('admin/notifications/notifications_data.mako')
106
106
107 def _has_permissions(self, notification):
107 def _has_permissions(self, notification):
108 def is_owner():
108 def is_owner():
@@ -173,6 +173,6 b' class NotificationsController(BaseContro'
173 Session().commit()
173 Session().commit()
174 c.notification = no
174 c.notification = no
175
175
176 return render('admin/notifications/show_notification.html')
176 return render('admin/notifications/show_notification.mako')
177
177
178 return abort(403)
178 return abort(403)
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -80,7 +80,7 b' class PermissionsController(BaseControll'
80 defaults.update(c.user.get_default_perms())
80 defaults.update(c.user.get_default_perms())
81
81
82 return htmlfill.render(
82 return htmlfill.render(
83 render('admin/permissions/permissions.html'),
83 render('admin/permissions/permissions.mako'),
84 defaults=defaults,
84 defaults=defaults,
85 encoding="UTF-8",
85 encoding="UTF-8",
86 force_defaults=False)
86 force_defaults=False)
@@ -116,7 +116,7 b' class PermissionsController(BaseControll'
116 defaults = errors.value
116 defaults = errors.value
117
117
118 return htmlfill.render(
118 return htmlfill.render(
119 render('admin/permissions/permissions.html'),
119 render('admin/permissions/permissions.mako'),
120 defaults=defaults,
120 defaults=defaults,
121 errors=errors.error_dict or {},
121 errors=errors.error_dict or {},
122 prefix_error=False,
122 prefix_error=False,
@@ -137,7 +137,7 b' class PermissionsController(BaseControll'
137 defaults = {}
137 defaults = {}
138 defaults.update(c.user.get_default_perms())
138 defaults.update(c.user.get_default_perms())
139 return htmlfill.render(
139 return htmlfill.render(
140 render('admin/permissions/permissions.html'),
140 render('admin/permissions/permissions.mako'),
141 defaults=defaults,
141 defaults=defaults,
142 encoding="UTF-8",
142 encoding="UTF-8",
143 force_defaults=False)
143 force_defaults=False)
@@ -165,7 +165,7 b' class PermissionsController(BaseControll'
165 defaults = errors.value
165 defaults = errors.value
166
166
167 return htmlfill.render(
167 return htmlfill.render(
168 render('admin/permissions/permissions.html'),
168 render('admin/permissions/permissions.mako'),
169 defaults=defaults,
169 defaults=defaults,
170 errors=errors.error_dict or {},
170 errors=errors.error_dict or {},
171 prefix_error=False,
171 prefix_error=False,
@@ -188,7 +188,7 b' class PermissionsController(BaseControll'
188 defaults.update(c.user.get_default_perms())
188 defaults.update(c.user.get_default_perms())
189
189
190 return htmlfill.render(
190 return htmlfill.render(
191 render('admin/permissions/permissions.html'),
191 render('admin/permissions/permissions.mako'),
192 defaults=defaults,
192 defaults=defaults,
193 encoding="UTF-8",
193 encoding="UTF-8",
194 force_defaults=False)
194 force_defaults=False)
@@ -219,7 +219,7 b' class PermissionsController(BaseControll'
219 defaults = errors.value
219 defaults = errors.value
220
220
221 return htmlfill.render(
221 return htmlfill.render(
222 render('admin/permissions/permissions.html'),
222 render('admin/permissions/permissions.mako'),
223 defaults=defaults,
223 defaults=defaults,
224 errors=errors.error_dict or {},
224 errors=errors.error_dict or {},
225 prefix_error=False,
225 prefix_error=False,
@@ -239,11 +239,11 b' class PermissionsController(BaseControll'
239 c.user_ip_map = (
239 c.user_ip_map = (
240 UserIpMap.query().filter(UserIpMap.user == c.user).all())
240 UserIpMap.query().filter(UserIpMap.user == c.user).all())
241
241
242 return render('admin/permissions/permissions.html')
242 return render('admin/permissions/permissions.mako')
243
243
244 @HasPermissionAllDecorator('hg.admin')
244 @HasPermissionAllDecorator('hg.admin')
245 def permission_perms(self):
245 def permission_perms(self):
246 c.active = 'perms'
246 c.active = 'perms'
247 c.user = User.get_default_user()
247 c.user = User.get_default_user()
248 c.perm_user = c.user.AuthUser
248 c.perm_user = c.user.AuthUser
249 return render('admin/permissions/permissions.html')
249 return render('admin/permissions/permissions.mako')
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -162,7 +162,7 b' class RepoGroupsController(BaseControlle'
162 repo_group_data = RepoGroupModel().get_repo_groups_as_dict(
162 repo_group_data = RepoGroupModel().get_repo_groups_as_dict(
163 repo_group_list=repo_group_list_acl, admin=True)
163 repo_group_list=repo_group_list_acl, admin=True)
164 c.data = json.dumps(repo_group_data)
164 c.data = json.dumps(repo_group_data)
165 return render('admin/repo_groups/repo_groups.html')
165 return render('admin/repo_groups/repo_groups.mako')
166
166
167 # perm checks inside
167 # perm checks inside
168 @NotAnonymous()
168 @NotAnonymous()
@@ -199,7 +199,7 b' class RepoGroupsController(BaseControlle'
199 # TODO: in futureaction_logger(, '', '', '', self.sa)
199 # TODO: in futureaction_logger(, '', '', '', self.sa)
200 except formencode.Invalid as errors:
200 except formencode.Invalid as errors:
201 return htmlfill.render(
201 return htmlfill.render(
202 render('admin/repo_groups/repo_group_add.html'),
202 render('admin/repo_groups/repo_group_add.mako'),
203 defaults=errors.value,
203 defaults=errors.value,
204 errors=errors.error_dict or {},
204 errors=errors.error_dict or {},
205 prefix_error=False,
205 prefix_error=False,
@@ -224,7 +224,7 b' class RepoGroupsController(BaseControlle'
224 return abort(403)
224 return abort(403)
225
225
226 self.__load_defaults()
226 self.__load_defaults()
227 return render('admin/repo_groups/repo_group_add.html')
227 return render('admin/repo_groups/repo_group_add.mako')
228
228
229 @HasRepoGroupPermissionAnyDecorator('group.admin')
229 @HasRepoGroupPermissionAnyDecorator('group.admin')
230 @auth.CSRFRequired()
230 @auth.CSRFRequired()
@@ -263,7 +263,7 b' class RepoGroupsController(BaseControlle'
263 except formencode.Invalid as errors:
263 except formencode.Invalid as errors:
264 c.active = 'settings'
264 c.active = 'settings'
265 return htmlfill.render(
265 return htmlfill.render(
266 render('admin/repo_groups/repo_group_edit.html'),
266 render('admin/repo_groups/repo_group_edit.mako'),
267 defaults=errors.value,
267 defaults=errors.value,
268 errors=errors.error_dict or {},
268 errors=errors.error_dict or {},
269 prefix_error=False,
269 prefix_error=False,
@@ -338,7 +338,7 b' class RepoGroupsController(BaseControlle'
338 defaults = self.__load_data(c.repo_group.group_id)
338 defaults = self.__load_data(c.repo_group.group_id)
339
339
340 return htmlfill.render(
340 return htmlfill.render(
341 render('admin/repo_groups/repo_group_edit.html'),
341 render('admin/repo_groups/repo_group_edit.mako'),
342 defaults=defaults,
342 defaults=defaults,
343 encoding="UTF-8",
343 encoding="UTF-8",
344 force_defaults=False
344 force_defaults=False
@@ -351,7 +351,7 b' class RepoGroupsController(BaseControlle'
351 c.active = 'advanced'
351 c.active = 'advanced'
352 c.repo_group = RepoGroupModel()._get_repo_group(group_name)
352 c.repo_group = RepoGroupModel()._get_repo_group(group_name)
353
353
354 return render('admin/repo_groups/repo_group_edit.html')
354 return render('admin/repo_groups/repo_group_edit.mako')
355
355
356 @HasRepoGroupPermissionAnyDecorator('group.admin')
356 @HasRepoGroupPermissionAnyDecorator('group.admin')
357 def edit_repo_group_perms(self, group_name):
357 def edit_repo_group_perms(self, group_name):
@@ -363,7 +363,7 b' class RepoGroupsController(BaseControlle'
363 defaults = self.__load_data(c.repo_group.group_id)
363 defaults = self.__load_data(c.repo_group.group_id)
364
364
365 return htmlfill.render(
365 return htmlfill.render(
366 render('admin/repo_groups/repo_group_edit.html'),
366 render('admin/repo_groups/repo_group_edit.mako'),
367 defaults=defaults,
367 defaults=defaults,
368 encoding="UTF-8",
368 encoding="UTF-8",
369 force_defaults=False
369 force_defaults=False
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2013-2016 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
@@ -147,7 +147,7 b' class ReposController(BaseRepoController'
147 # json used to render the grid
147 # json used to render the grid
148 c.data = json.dumps(repos_data)
148 c.data = json.dumps(repos_data)
149
149
150 return render('admin/repos/repos.html')
150 return render('admin/repos/repos.mako')
151
151
152 # perms check inside
152 # perms check inside
153 @NotAnonymous()
153 @NotAnonymous()
@@ -175,7 +175,7 b' class ReposController(BaseRepoController'
175 task_id = task.task_id
175 task_id = task.task_id
176 except formencode.Invalid as errors:
176 except formencode.Invalid as errors:
177 return htmlfill.render(
177 return htmlfill.render(
178 render('admin/repos/repo_add.html'),
178 render('admin/repos/repo_add.mako'),
179 defaults=errors.value,
179 defaults=errors.value,
180 errors=errors.error_dict or {},
180 errors=errors.error_dict or {},
181 prefix_error=False,
181 prefix_error=False,
@@ -235,7 +235,7 b' class ReposController(BaseRepoController'
235 defaults.update({'repo_group': parent_group_choice})
235 defaults.update({'repo_group': parent_group_choice})
236
236
237 return htmlfill.render(
237 return htmlfill.render(
238 render('admin/repos/repo_add.html'),
238 render('admin/repos/repo_add.mako'),
239 defaults=defaults,
239 defaults=defaults,
240 errors={},
240 errors={},
241 prefix_error=False,
241 prefix_error=False,
@@ -249,7 +249,7 b' class ReposController(BaseRepoController'
249 c.task_id = request.GET.get('task_id')
249 c.task_id = request.GET.get('task_id')
250 if not c.repo:
250 if not c.repo:
251 raise HTTPNotFound()
251 raise HTTPNotFound()
252 return render('admin/repos/repo_creating.html')
252 return render('admin/repos/repo_creating.mako')
253
253
254 @NotAnonymous()
254 @NotAnonymous()
255 @jsonify
255 @jsonify
@@ -334,7 +334,7 b' class ReposController(BaseRepoController'
334 defaults = self.__load_data(repo_name)
334 defaults = self.__load_data(repo_name)
335 defaults.update(errors.value)
335 defaults.update(errors.value)
336 return htmlfill.render(
336 return htmlfill.render(
337 render('admin/repos/repo_edit.html'),
337 render('admin/repos/repo_edit.mako'),
338 defaults=defaults,
338 defaults=defaults,
339 errors=errors.error_dict or {},
339 errors=errors.error_dict or {},
340 prefix_error=False,
340 prefix_error=False,
@@ -410,7 +410,7 b' class ReposController(BaseRepoController'
410 c.personal_repo_group = c.rhodecode_user.personal_repo_group
410 c.personal_repo_group = c.rhodecode_user.personal_repo_group
411 c.active = 'settings'
411 c.active = 'settings'
412 return htmlfill.render(
412 return htmlfill.render(
413 render('admin/repos/repo_edit.html'),
413 render('admin/repos/repo_edit.mako'),
414 defaults=defaults,
414 defaults=defaults,
415 encoding="UTF-8",
415 encoding="UTF-8",
416 force_defaults=False)
416 force_defaults=False)
@@ -424,7 +424,7 b' class ReposController(BaseRepoController'
424 defaults = RepoModel()._get_defaults(repo_name)
424 defaults = RepoModel()._get_defaults(repo_name)
425
425
426 return htmlfill.render(
426 return htmlfill.render(
427 render('admin/repos/repo_edit.html'),
427 render('admin/repos/repo_edit.mako'),
428 defaults=defaults,
428 defaults=defaults,
429 encoding="UTF-8",
429 encoding="UTF-8",
430 force_defaults=False)
430 force_defaults=False)
@@ -454,7 +454,7 b' class ReposController(BaseRepoController'
454 if request.POST:
454 if request.POST:
455
455
456 return redirect(url('repo_edit_fields'))
456 return redirect(url('repo_edit_fields'))
457 return render('admin/repos/repo_edit.html')
457 return render('admin/repos/repo_edit.mako')
458
458
459 @HasRepoPermissionAllDecorator('repository.admin')
459 @HasRepoPermissionAllDecorator('repository.admin')
460 @auth.CSRFRequired()
460 @auth.CSRFRequired()
@@ -509,7 +509,7 b' class ReposController(BaseRepoController'
509
509
510 if request.POST:
510 if request.POST:
511 return redirect(url('repo_edit_advanced'))
511 return redirect(url('repo_edit_advanced'))
512 return render('admin/repos/repo_edit.html')
512 return render('admin/repos/repo_edit.mako')
513
513
514 @HasRepoPermissionAllDecorator('repository.admin')
514 @HasRepoPermissionAllDecorator('repository.admin')
515 @auth.CSRFRequired()
515 @auth.CSRFRequired()
@@ -642,7 +642,7 b' class ReposController(BaseRepoController'
642 c.repo_info = self._load_repo(repo_name)
642 c.repo_info = self._load_repo(repo_name)
643 c.active = 'caches'
643 c.active = 'caches'
644
644
645 return render('admin/repos/repo_edit.html')
645 return render('admin/repos/repo_edit.mako')
646
646
647 @HasRepoPermissionAllDecorator('repository.admin')
647 @HasRepoPermissionAllDecorator('repository.admin')
648 @auth.CSRFRequired()
648 @auth.CSRFRequired()
@@ -664,7 +664,7 b' class ReposController(BaseRepoController'
664 c.repo_info = self._load_repo(repo_name)
664 c.repo_info = self._load_repo(repo_name)
665 c.active = 'remote'
665 c.active = 'remote'
666
666
667 return render('admin/repos/repo_edit.html')
667 return render('admin/repos/repo_edit.mako')
668
668
669 @HasRepoPermissionAllDecorator('repository.admin')
669 @HasRepoPermissionAllDecorator('repository.admin')
670 @auth.CSRFRequired()
670 @auth.CSRFRequired()
@@ -702,7 +702,7 b' class ReposController(BaseRepoController'
702
702
703 c.active = 'statistics'
703 c.active = 'statistics'
704
704
705 return render('admin/repos/repo_edit.html')
705 return render('admin/repos/repo_edit.mako')
706
706
707 @HasRepoPermissionAllDecorator('repository.admin')
707 @HasRepoPermissionAllDecorator('repository.admin')
708 @auth.CSRFRequired()
708 @auth.CSRFRequired()
@@ -771,7 +771,7 b' class ReposController(BaseRepoController'
771 c.global_patterns = c.settings_model.get_global_settings()
771 c.global_patterns = c.settings_model.get_global_settings()
772 c.repo_patterns = c.settings_model.get_repo_settings()
772 c.repo_patterns = c.settings_model.get_repo_settings()
773
773
774 return render('admin/repos/repo_edit.html')
774 return render('admin/repos/repo_edit.mako')
775
775
776 @HasRepoPermissionAllDecorator('repository.admin')
776 @HasRepoPermissionAllDecorator('repository.admin')
777 def repo_settings_vcs(self, repo_name):
777 def repo_settings_vcs(self, repo_name):
@@ -791,7 +791,7 b' class ReposController(BaseRepoController'
791 rhodecode.CONFIG.get('labs_settings_active', 'true'))
791 rhodecode.CONFIG.get('labs_settings_active', 'true'))
792
792
793 return htmlfill.render(
793 return htmlfill.render(
794 render('admin/repos/repo_edit.html'),
794 render('admin/repos/repo_edit.mako'),
795 defaults=defaults,
795 defaults=defaults,
796 encoding="UTF-8",
796 encoding="UTF-8",
797 force_defaults=False)
797 force_defaults=False)
@@ -819,7 +819,7 b' class ReposController(BaseRepoController'
819 _("Some form inputs contain invalid data."),
819 _("Some form inputs contain invalid data."),
820 category='error')
820 category='error')
821 return htmlfill.render(
821 return htmlfill.render(
822 render('admin/repos/repo_edit.html'),
822 render('admin/repos/repo_edit.mako'),
823 defaults=errors.value,
823 defaults=errors.value,
824 errors=errors.error_dict or {},
824 errors=errors.error_dict or {},
825 prefix_error=False,
825 prefix_error=False,
@@ -842,7 +842,7 b' class ReposController(BaseRepoController'
842 return redirect(url('repo_vcs_settings', repo_name=repo_name))
842 return redirect(url('repo_vcs_settings', repo_name=repo_name))
843
843
844 return htmlfill.render(
844 return htmlfill.render(
845 render('admin/repos/repo_edit.html'),
845 render('admin/repos/repo_edit.mako'),
846 defaults=self._vcs_form_defaults(repo_name),
846 defaults=self._vcs_form_defaults(repo_name),
847 encoding="UTF-8",
847 encoding="UTF-8",
848 force_defaults=False)
848 force_defaults=False)
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -25,15 +25,13 b' settings controller for rhodecode admin'
25
25
26 import collections
26 import collections
27 import logging
27 import logging
28 import urllib2
29
28
30 import datetime
29 import datetime
31 import formencode
30 import formencode
32 from formencode import htmlfill
31 from formencode import htmlfill
33 import packaging.version
34 from pylons import request, tmpl_context as c, url, config
32 from pylons import request, tmpl_context as c, url, config
35 from pylons.controllers.util import redirect
33 from pylons.controllers.util import redirect
36 from pylons.i18n.translation import _, lazy_ugettext
34 from pylons.i18n.translation import _
37 from pyramid.threadlocal import get_current_registry
35 from pyramid.threadlocal import get_current_registry
38 from webob.exc import HTTPBadRequest
36 from webob.exc import HTTPBadRequest
39
37
@@ -48,7 +46,6 b' from rhodecode.lib.utils import repo2db_'
48 from rhodecode.lib.utils2 import (
46 from rhodecode.lib.utils2 import (
49 str2bool, safe_unicode, AttributeDict, safe_int)
47 str2bool, safe_unicode, AttributeDict, safe_int)
50 from rhodecode.lib.compat import OrderedDict
48 from rhodecode.lib.compat import OrderedDict
51 from rhodecode.lib.ext_json import json
52 from rhodecode.lib.utils import jsonify
49 from rhodecode.lib.utils import jsonify
53
50
54 from rhodecode.model.db import RhodeCodeUi, Repository
51 from rhodecode.model.db import RhodeCodeUi, Repository
@@ -150,7 +147,7 b' class SettingsController(BaseController)'
150 _("Some form inputs contain invalid data."),
147 _("Some form inputs contain invalid data."),
151 category='error')
148 category='error')
152 return htmlfill.render(
149 return htmlfill.render(
153 render('admin/settings/settings.html'),
150 render('admin/settings/settings.mako'),
154 defaults=errors.value,
151 defaults=errors.value,
155 errors=errors.error_dict or {},
152 errors=errors.error_dict or {},
156 prefix_error=False,
153 prefix_error=False,
@@ -179,7 +176,7 b' class SettingsController(BaseController)'
179 return redirect(url('admin_settings_vcs'))
176 return redirect(url('admin_settings_vcs'))
180
177
181 return htmlfill.render(
178 return htmlfill.render(
182 render('admin/settings/settings.html'),
179 render('admin/settings/settings.mako'),
183 defaults=self._form_defaults(),
180 defaults=self._form_defaults(),
184 encoding="UTF-8",
181 encoding="UTF-8",
185 force_defaults=False)
182 force_defaults=False)
@@ -198,7 +195,7 b' class SettingsController(BaseController)'
198 c.svn_proxy_generate_config = pyramid_settings[generate_config]
195 c.svn_proxy_generate_config = pyramid_settings[generate_config]
199
196
200 return htmlfill.render(
197 return htmlfill.render(
201 render('admin/settings/settings.html'),
198 render('admin/settings/settings.mako'),
202 defaults=self._form_defaults(),
199 defaults=self._form_defaults(),
203 encoding="UTF-8",
200 encoding="UTF-8",
204 force_defaults=False)
201 force_defaults=False)
@@ -235,7 +232,7 b' class SettingsController(BaseController)'
235 c.active = 'mapping'
232 c.active = 'mapping'
236
233
237 return htmlfill.render(
234 return htmlfill.render(
238 render('admin/settings/settings.html'),
235 render('admin/settings/settings.mako'),
239 defaults=self._form_defaults(),
236 defaults=self._form_defaults(),
240 encoding="UTF-8",
237 encoding="UTF-8",
241 force_defaults=False)
238 force_defaults=False)
@@ -253,7 +250,7 b' class SettingsController(BaseController)'
253 form_result = application_form.to_python(dict(request.POST))
250 form_result = application_form.to_python(dict(request.POST))
254 except formencode.Invalid as errors:
251 except formencode.Invalid as errors:
255 return htmlfill.render(
252 return htmlfill.render(
256 render('admin/settings/settings.html'),
253 render('admin/settings/settings.mako'),
257 defaults=errors.value,
254 defaults=errors.value,
258 errors=errors.error_dict or {},
255 errors=errors.error_dict or {},
259 prefix_error=False,
256 prefix_error=False,
@@ -296,7 +293,7 b' class SettingsController(BaseController)'
296 .get_personal_group_name_pattern()
293 .get_personal_group_name_pattern()
297
294
298 return htmlfill.render(
295 return htmlfill.render(
299 render('admin/settings/settings.html'),
296 render('admin/settings/settings.mako'),
300 defaults=self._form_defaults(),
297 defaults=self._form_defaults(),
301 encoding="UTF-8",
298 encoding="UTF-8",
302 force_defaults=False)
299 force_defaults=False)
@@ -312,7 +309,7 b' class SettingsController(BaseController)'
312 form_result = application_form.to_python(dict(request.POST))
309 form_result = application_form.to_python(dict(request.POST))
313 except formencode.Invalid as errors:
310 except formencode.Invalid as errors:
314 return htmlfill.render(
311 return htmlfill.render(
315 render('admin/settings/settings.html'),
312 render('admin/settings/settings.mako'),
316 defaults=errors.value,
313 defaults=errors.value,
317 errors=errors.error_dict or {},
314 errors=errors.error_dict or {},
318 prefix_error=False,
315 prefix_error=False,
@@ -360,7 +357,7 b' class SettingsController(BaseController)'
360 c.active = 'visual'
357 c.active = 'visual'
361
358
362 return htmlfill.render(
359 return htmlfill.render(
363 render('admin/settings/settings.html'),
360 render('admin/settings/settings.mako'),
364 defaults=self._form_defaults(),
361 defaults=self._form_defaults(),
365 encoding="UTF-8",
362 encoding="UTF-8",
366 force_defaults=False)
363 force_defaults=False)
@@ -406,7 +403,7 b' class SettingsController(BaseController)'
406 'desc': defaults.get('rhodecode_issuetracker_desc_' + uid),
403 'desc': defaults.get('rhodecode_issuetracker_desc_' + uid),
407 })
404 })
408
405
409 return render('admin/settings/settings.html')
406 return render('admin/settings/settings.mako')
410
407
411 @HasPermissionAllDecorator('hg.admin')
408 @HasPermissionAllDecorator('hg.admin')
412 @auth.CSRFRequired()
409 @auth.CSRFRequired()
@@ -469,7 +466,7 b' class SettingsController(BaseController)'
469 c.rhodecode_ini = rhodecode.CONFIG
466 c.rhodecode_ini = rhodecode.CONFIG
470
467
471 return htmlfill.render(
468 return htmlfill.render(
472 render('admin/settings/settings.html'),
469 render('admin/settings/settings.mako'),
473 defaults=self._form_defaults(),
470 defaults=self._form_defaults(),
474 encoding="UTF-8",
471 encoding="UTF-8",
475 force_defaults=False)
472 force_defaults=False)
@@ -526,7 +523,7 b' class SettingsController(BaseController)'
526 c.custom_hooks = model.get_custom_hooks()
523 c.custom_hooks = model.get_custom_hooks()
527
524
528 return htmlfill.render(
525 return htmlfill.render(
529 render('admin/settings/settings.html'),
526 render('admin/settings/settings.mako'),
530 defaults=self._form_defaults(),
527 defaults=self._form_defaults(),
531 encoding="UTF-8",
528 encoding="UTF-8",
532 force_defaults=False)
529 force_defaults=False)
@@ -541,154 +538,7 b' class SettingsController(BaseController)'
541 searcher = searcher_from_config(config)
538 searcher = searcher_from_config(config)
542 c.statistics = searcher.statistics()
539 c.statistics = searcher.statistics()
543
540
544 return render('admin/settings/settings.html')
541 return render('admin/settings/settings.mako')
545
546 @HasPermissionAllDecorator('hg.admin')
547 def settings_system(self):
548 """GET /admin/settings/system: All items in the collection"""
549 # url('admin_settings_system')
550 snapshot = str2bool(request.GET.get('snapshot'))
551 defaults = self._form_defaults()
552
553 c.active = 'system'
554 c.rhodecode_update_url = defaults.get('rhodecode_update_url')
555 server_info = ScmModel().get_server_info(request.environ)
556
557 for key, val in server_info.iteritems():
558 setattr(c, key, val)
559
560 def val(name, subkey='human_value'):
561 return server_info[name][subkey]
562
563 def state(name):
564 return server_info[name]['state']
565
566 def val2(name):
567 val = server_info[name]['human_value']
568 state = server_info[name]['state']
569 return val, state
570
571 c.data_items = [
572 # update info
573 (_('Update info'), h.literal(
574 '<span class="link" id="check_for_update" >%s.</span>' % (
575 _('Check for updates')) +
576 '<br/> <span >%s.</span>' % (_('Note: please make sure this server can access `%s` for the update link to work') % c.rhodecode_update_url)
577 ), ''),
578
579 # RhodeCode specific
580 (_('RhodeCode Version'), val('rhodecode_app')['text'], state('rhodecode_app')),
581 (_('RhodeCode Server IP'), val('server')['server_ip'], state('server')),
582 (_('RhodeCode Server ID'), val('server')['server_id'], state('server')),
583 (_('RhodeCode Configuration'), val('rhodecode_config')['path'], state('rhodecode_config')),
584 ('', '', ''), # spacer
585
586 # Database
587 (_('Database'), val('database')['url'], state('database')),
588 (_('Database version'), val('database')['version'], state('database')),
589 ('', '', ''), # spacer
590
591 # Platform/Python
592 (_('Platform'), val('platform')['name'], state('platform')),
593 (_('Platform UUID'), val('platform')['uuid'], state('platform')),
594 (_('Python version'), val('python')['version'], state('python')),
595 (_('Python path'), val('python')['executable'], state('python')),
596 ('', '', ''), # spacer
597
598 # Systems stats
599 (_('CPU'), val('cpu'), state('cpu')),
600 (_('Load'), val('load')['text'], state('load')),
601 (_('Memory'), val('memory')['text'], state('memory')),
602 (_('Uptime'), val('uptime')['text'], state('uptime')),
603 ('', '', ''), # spacer
604
605 # Repo storage
606 (_('Storage location'), val('storage')['path'], state('storage')),
607 (_('Storage info'), val('storage')['text'], state('storage')),
608 (_('Storage inodes'), val('storage_inodes')['text'], state('storage_inodes')),
609
610 (_('Gist storage location'), val('storage_gist')['path'], state('storage_gist')),
611 (_('Gist storage info'), val('storage_gist')['text'], state('storage_gist')),
612
613 (_('Archive cache storage location'), val('storage_archive')['path'], state('storage_archive')),
614 (_('Archive cache info'), val('storage_archive')['text'], state('storage_archive')),
615
616 (_('Temp storage location'), val('storage_temp')['path'], state('storage_temp')),
617 (_('Temp storage info'), val('storage_temp')['text'], state('storage_temp')),
618
619 (_('Search info'), val('search')['text'], state('search')),
620 (_('Search location'), val('search')['location'], state('search')),
621 ('', '', ''), # spacer
622
623 # VCS specific
624 (_('VCS Backends'), val('vcs_backends'), state('vcs_backends')),
625 (_('VCS Server'), val('vcs_server')['text'], state('vcs_server')),
626 (_('GIT'), val('git'), state('git')),
627 (_('HG'), val('hg'), state('hg')),
628 (_('SVN'), val('svn'), state('svn')),
629
630 ]
631
632 # TODO: marcink, figure out how to allow only selected users to do this
633 c.allowed_to_snapshot = c.rhodecode_user.admin
634
635 if snapshot:
636 if c.allowed_to_snapshot:
637 c.data_items.pop(0) # remove server info
638 return render('admin/settings/settings_system_snapshot.html')
639 else:
640 h.flash('You are not allowed to do this', category='warning')
641
642 return htmlfill.render(
643 render('admin/settings/settings.html'),
644 defaults=defaults,
645 encoding="UTF-8",
646 force_defaults=False)
647
648 @staticmethod
649 def get_update_data(update_url):
650 """Return the JSON update data."""
651 ver = rhodecode.__version__
652 log.debug('Checking for upgrade on `%s` server', update_url)
653 opener = urllib2.build_opener()
654 opener.addheaders = [('User-agent', 'RhodeCode-SCM/%s' % ver)]
655 response = opener.open(update_url)
656 response_data = response.read()
657 data = json.loads(response_data)
658
659 return data
660
661 @HasPermissionAllDecorator('hg.admin')
662 def settings_system_update(self):
663 """GET /admin/settings/system/updates: All items in the collection"""
664 # url('admin_settings_system_update')
665 defaults = self._form_defaults()
666 update_url = defaults.get('rhodecode_update_url', '')
667
668 _err = lambda s: '<div style="color:#ff8888; padding:4px 0px">%s</div>' % (s)
669 try:
670 data = self.get_update_data(update_url)
671 except urllib2.URLError as e:
672 log.exception("Exception contacting upgrade server")
673 return _err('Failed to contact upgrade server: %r' % e)
674 except ValueError as e:
675 log.exception("Bad data sent from update server")
676 return _err('Bad data sent from update server')
677
678 latest = data['versions'][0]
679
680 c.update_url = update_url
681 c.latest_data = latest
682 c.latest_ver = latest['version']
683 c.cur_ver = rhodecode.__version__
684 c.should_upgrade = False
685
686 if (packaging.version.Version(c.latest_ver) >
687 packaging.version.Version(c.cur_ver)):
688 c.should_upgrade = True
689 c.important_notices = latest['general']
690
691 return render('admin/settings/settings_system_update.html')
692
542
693 @HasPermissionAllDecorator('hg.admin')
543 @HasPermissionAllDecorator('hg.admin')
694 def settings_supervisor(self):
544 def settings_supervisor(self):
@@ -710,7 +560,7 b' class SettingsController(BaseController)'
710 except Exception as e:
560 except Exception as e:
711 c.connection_error = str(e)
561 c.connection_error = str(e)
712 log.exception("Exception reading supervisor data")
562 log.exception("Exception reading supervisor data")
713 return render('admin/settings/settings.html')
563 return render('admin/settings/settings.mako')
714
564
715 groupid = c.rhodecode_ini.get('supervisor.group_id')
565 groupid = c.rhodecode_ini.get('supervisor.group_id')
716
566
@@ -734,7 +584,7 b' class SettingsController(BaseController)'
734 log.exception("Exception reading supervisor data")
584 log.exception("Exception reading supervisor data")
735 c.supervisor_procs[k] = {'_rhodecode_error': str(e)}
585 c.supervisor_procs[k] = {'_rhodecode_error': str(e)}
736
586
737 return render('admin/settings/settings.html')
587 return render('admin/settings/settings.mako')
738
588
739 @HasPermissionAllDecorator('hg.admin')
589 @HasPermissionAllDecorator('hg.admin')
740 def settings_supervisor_log(self, procid):
590 def settings_supervisor_log(self, procid):
@@ -751,7 +601,7 b' class SettingsController(BaseController)'
751 offset = abs(safe_int(request.GET.get('offset', c.log_size))) * -1
601 offset = abs(safe_int(request.GET.get('offset', c.log_size))) * -1
752 c.log = supervisor.read_process_log(_connection, procid, offset, 0)
602 c.log = supervisor.read_process_log(_connection, procid, offset, 0)
753
603
754 return render('admin/settings/settings.html')
604 return render('admin/settings/settings.mako')
755
605
756 @HasPermissionAllDecorator('hg.admin')
606 @HasPermissionAllDecorator('hg.admin')
757 @auth.CSRFRequired()
607 @auth.CSRFRequired()
@@ -768,7 +618,7 b' class SettingsController(BaseController)'
768 _('Some form inputs contain invalid data.'),
618 _('Some form inputs contain invalid data.'),
769 category='error')
619 category='error')
770 return htmlfill.render(
620 return htmlfill.render(
771 render('admin/settings/settings.html'),
621 render('admin/settings/settings.mako'),
772 defaults=errors.value,
622 defaults=errors.value,
773 errors=errors.error_dict or {},
623 errors=errors.error_dict or {},
774 prefix_error=False,
624 prefix_error=False,
@@ -795,7 +645,7 b' class SettingsController(BaseController)'
795 return redirect(url('admin_settings_labs'))
645 return redirect(url('admin_settings_labs'))
796
646
797 return htmlfill.render(
647 return htmlfill.render(
798 render('admin/settings/settings.html'),
648 render('admin/settings/settings.mako'),
799 defaults=self._form_defaults(),
649 defaults=self._form_defaults(),
800 encoding='UTF-8',
650 encoding='UTF-8',
801 force_defaults=False)
651 force_defaults=False)
@@ -811,7 +661,7 b' class SettingsController(BaseController)'
811 c.lab_settings = _LAB_SETTINGS
661 c.lab_settings = _LAB_SETTINGS
812
662
813 return htmlfill.render(
663 return htmlfill.render(
814 render('admin/settings/settings.html'),
664 render('admin/settings/settings.mako'),
815 defaults=self._form_defaults(),
665 defaults=self._form_defaults(),
816 encoding='UTF-8',
666 encoding='UTF-8',
817 force_defaults=False)
667 force_defaults=False)
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2011-2016 RhodeCode GmbH
3 # Copyright (C) 2011-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
@@ -109,7 +109,7 b' class UserGroupsController(BaseControlle'
109 # url('users_groups')
109 # url('users_groups')
110
110
111 from rhodecode.lib.utils import PartialRenderer
111 from rhodecode.lib.utils import PartialRenderer
112 _render = PartialRenderer('data_table/_dt_elements.html')
112 _render = PartialRenderer('data_table/_dt_elements.mako')
113
113
114 def user_group_name(user_group_id, user_group_name):
114 def user_group_name(user_group_id, user_group_name):
115 return _render("user_group_name", user_group_id, user_group_name)
115 return _render("user_group_name", user_group_id, user_group_name)
@@ -136,7 +136,7 b' class UserGroupsController(BaseControlle'
136 })
136 })
137
137
138 c.data = json.dumps(user_groups_data)
138 c.data = json.dumps(user_groups_data)
139 return render('admin/user_groups/user_groups.html')
139 return render('admin/user_groups/user_groups.mako')
140
140
141 @HasPermissionAnyDecorator('hg.admin', 'hg.usergroup.create.true')
141 @HasPermissionAnyDecorator('hg.admin', 'hg.usergroup.create.true')
142 @auth.CSRFRequired()
142 @auth.CSRFRequired()
@@ -167,7 +167,7 b' class UserGroupsController(BaseControlle'
167 Session().commit()
167 Session().commit()
168 except formencode.Invalid as errors:
168 except formencode.Invalid as errors:
169 return htmlfill.render(
169 return htmlfill.render(
170 render('admin/user_groups/user_group_add.html'),
170 render('admin/user_groups/user_group_add.mako'),
171 defaults=errors.value,
171 defaults=errors.value,
172 errors=errors.error_dict or {},
172 errors=errors.error_dict or {},
173 prefix_error=False,
173 prefix_error=False,
@@ -185,7 +185,7 b' class UserGroupsController(BaseControlle'
185 def new(self):
185 def new(self):
186 """GET /user_groups/new: Form to create a new item"""
186 """GET /user_groups/new: Form to create a new item"""
187 # url('new_users_group')
187 # url('new_users_group')
188 return render('admin/user_groups/user_group_add.html')
188 return render('admin/user_groups/user_group_add.mako')
189
189
190 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
190 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
191 @auth.CSRFRequired()
191 @auth.CSRFRequired()
@@ -224,7 +224,7 b' class UserGroupsController(BaseControlle'
224 e = errors.error_dict or {}
224 e = errors.error_dict or {}
225
225
226 return htmlfill.render(
226 return htmlfill.render(
227 render('admin/user_groups/user_group_edit.html'),
227 render('admin/user_groups/user_group_edit.mako'),
228 defaults=defaults,
228 defaults=defaults,
229 errors=e,
229 errors=e,
230 prefix_error=False,
230 prefix_error=False,
@@ -276,7 +276,7 b' class UserGroupsController(BaseControlle'
276 defaults = self.__load_defaults(user_group_id)
276 defaults = self.__load_defaults(user_group_id)
277
277
278 return htmlfill.render(
278 return htmlfill.render(
279 render('admin/user_groups/user_group_edit.html'),
279 render('admin/user_groups/user_group_edit.mako'),
280 defaults=defaults,
280 defaults=defaults,
281 encoding="UTF-8",
281 encoding="UTF-8",
282 force_defaults=False
282 force_defaults=False
@@ -299,7 +299,7 b' class UserGroupsController(BaseControlle'
299 p.permission.permission_name})
299 p.permission.permission_name})
300
300
301 return htmlfill.render(
301 return htmlfill.render(
302 render('admin/user_groups/user_group_edit.html'),
302 render('admin/user_groups/user_group_edit.mako'),
303 defaults=defaults,
303 defaults=defaults,
304 encoding="UTF-8",
304 encoding="UTF-8",
305 force_defaults=False
305 force_defaults=False
@@ -365,7 +365,7 b' class UserGroupsController(BaseControlle'
365 permissions['repositories_groups'][gr.group.group_name] \
365 permissions['repositories_groups'][gr.group.group_name] \
366 = gr.permission.permission_name
366 = gr.permission.permission_name
367 c.permissions = permissions
367 c.permissions = permissions
368 return render('admin/user_groups/user_group_edit.html')
368 return render('admin/user_groups/user_group_edit.mako')
369
369
370 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
370 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
371 def edit_global_perms(self, user_group_id):
371 def edit_global_perms(self, user_group_id):
@@ -379,7 +379,7 b' class UserGroupsController(BaseControlle'
379 defaults.update(c.user_group.get_default_perms())
379 defaults.update(c.user_group.get_default_perms())
380
380
381 return htmlfill.render(
381 return htmlfill.render(
382 render('admin/user_groups/user_group_edit.html'),
382 render('admin/user_groups/user_group_edit.mako'),
383 defaults=defaults,
383 defaults=defaults,
384 encoding="UTF-8",
384 encoding="UTF-8",
385 force_defaults=False
385 force_defaults=False
@@ -425,7 +425,7 b' class UserGroupsController(BaseControlle'
425 defaults = errors.value
425 defaults = errors.value
426 c.user_group = user_group
426 c.user_group = user_group
427 return htmlfill.render(
427 return htmlfill.render(
428 render('admin/user_groups/user_group_edit.html'),
428 render('admin/user_groups/user_group_edit.mako'),
429 defaults=defaults,
429 defaults=defaults,
430 errors=errors.error_dict or {},
430 errors=errors.error_dict or {},
431 prefix_error=False,
431 prefix_error=False,
@@ -456,7 +456,7 b' class UserGroupsController(BaseControlle'
456 (x.group for x in c.user_group.users_group_repo_group_to_perm),
456 (x.group for x in c.user_group.users_group_repo_group_to_perm),
457 key=lambda u: u.group_name.lower())
457 key=lambda u: u.group_name.lower())
458
458
459 return render('admin/user_groups/user_group_edit.html')
459 return render('admin/user_groups/user_group_edit.mako')
460
460
461 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
461 @HasUserGroupPermissionAnyDecorator('usergroup.admin')
462 @XHRRequired()
462 @XHRRequired()
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -82,7 +82,7 b' class UsersController(BaseController):'
82 # url('users')
82 # url('users')
83
83
84 from rhodecode.lib.utils import PartialRenderer
84 from rhodecode.lib.utils import PartialRenderer
85 _render = PartialRenderer('data_table/_dt_elements.html')
85 _render = PartialRenderer('data_table/_dt_elements.mako')
86
86
87 def username(user_id, username):
87 def username(user_id, username):
88 return _render("user_name", user_id, username)
88 return _render("user_name", user_id, username)
@@ -119,7 +119,7 b' class UsersController(BaseController):'
119
119
120
120
121 c.data = json.dumps(users_data)
121 c.data = json.dumps(users_data)
122 return render('admin/users/users.html')
122 return render('admin/users/users.mako')
123
123
124 def _get_personal_repo_group_template_vars(self):
124 def _get_personal_repo_group_template_vars(self):
125 DummyUser = AttributeDict({
125 DummyUser = AttributeDict({
@@ -156,7 +156,7 b' class UsersController(BaseController):'
156 except formencode.Invalid as errors:
156 except formencode.Invalid as errors:
157 self._get_personal_repo_group_template_vars()
157 self._get_personal_repo_group_template_vars()
158 return htmlfill.render(
158 return htmlfill.render(
159 render('admin/users/user_add.html'),
159 render('admin/users/user_add.mako'),
160 defaults=errors.value,
160 defaults=errors.value,
161 errors=errors.error_dict or {},
161 errors=errors.error_dict or {},
162 prefix_error=False,
162 prefix_error=False,
@@ -176,7 +176,7 b' class UsersController(BaseController):'
176 # url('new_user')
176 # url('new_user')
177 c.default_extern_type = auth_rhodecode.RhodeCodeAuthPlugin.name
177 c.default_extern_type = auth_rhodecode.RhodeCodeAuthPlugin.name
178 self._get_personal_repo_group_template_vars()
178 self._get_personal_repo_group_template_vars()
179 return render('admin/users/user_add.html')
179 return render('admin/users/user_add.mako')
180
180
181 @HasPermissionAllDecorator('hg.admin')
181 @HasPermissionAllDecorator('hg.admin')
182 @auth.CSRFRequired()
182 @auth.CSRFRequired()
@@ -218,7 +218,7 b' class UsersController(BaseController):'
218 e = errors.error_dict or {}
218 e = errors.error_dict or {}
219
219
220 return htmlfill.render(
220 return htmlfill.render(
221 render('admin/users/user_edit.html'),
221 render('admin/users/user_edit.mako'),
222 defaults=defaults,
222 defaults=defaults,
223 errors=e,
223 errors=e,
224 prefix_error=False,
224 prefix_error=False,
@@ -414,7 +414,7 b' class UsersController(BaseController):'
414 defaults = c.user.get_dict()
414 defaults = c.user.get_dict()
415 defaults.update({'language': c.user.user_data.get('language')})
415 defaults.update({'language': c.user.user_data.get('language')})
416 return htmlfill.render(
416 return htmlfill.render(
417 render('admin/users/user_edit.html'),
417 render('admin/users/user_edit.mako'),
418 defaults=defaults,
418 defaults=defaults,
419 encoding="UTF-8",
419 encoding="UTF-8",
420 force_defaults=False)
420 force_defaults=False)
@@ -446,7 +446,7 b' class UsersController(BaseController):'
446 '"inactive" instead of deleting it.') if has_review else ''
446 '"inactive" instead of deleting it.') if has_review else ''
447
447
448 return htmlfill.render(
448 return htmlfill.render(
449 render('admin/users/user_edit.html'),
449 render('admin/users/user_edit.mako'),
450 defaults=defaults,
450 defaults=defaults,
451 encoding="UTF-8",
451 encoding="UTF-8",
452 force_defaults=False)
452 force_defaults=False)
@@ -476,7 +476,7 b' class UsersController(BaseController):'
476 c.user.user_id, show_expired=show_expired)
476 c.user.user_id, show_expired=show_expired)
477 defaults = c.user.get_dict()
477 defaults = c.user.get_dict()
478 return htmlfill.render(
478 return htmlfill.render(
479 render('admin/users/user_edit.html'),
479 render('admin/users/user_edit.mako'),
480 defaults=defaults,
480 defaults=defaults,
481 encoding="UTF-8",
481 encoding="UTF-8",
482 force_defaults=False)
482 force_defaults=False)
@@ -539,7 +539,7 b' class UsersController(BaseController):'
539 defaults.update(c.user.get_default_perms())
539 defaults.update(c.user.get_default_perms())
540
540
541 return htmlfill.render(
541 return htmlfill.render(
542 render('admin/users/user_edit.html'),
542 render('admin/users/user_edit.mako'),
543 defaults=defaults,
543 defaults=defaults,
544 encoding="UTF-8",
544 encoding="UTF-8",
545 force_defaults=False)
545 force_defaults=False)
@@ -584,7 +584,7 b' class UsersController(BaseController):'
584 defaults = errors.value
584 defaults = errors.value
585 c.user = user
585 c.user = user
586 return htmlfill.render(
586 return htmlfill.render(
587 render('admin/users/user_edit.html'),
587 render('admin/users/user_edit.mako'),
588 defaults=defaults,
588 defaults=defaults,
589 errors=errors.error_dict or {},
589 errors=errors.error_dict or {},
590 prefix_error=False,
590 prefix_error=False,
@@ -607,7 +607,7 b' class UsersController(BaseController):'
607 c.active = 'perms_summary'
607 c.active = 'perms_summary'
608 c.perm_user = AuthUser(user_id=user_id, ip_addr=self.ip_addr)
608 c.perm_user = AuthUser(user_id=user_id, ip_addr=self.ip_addr)
609
609
610 return render('admin/users/user_edit.html')
610 return render('admin/users/user_edit.mako')
611
611
612 @HasPermissionAllDecorator('hg.admin')
612 @HasPermissionAllDecorator('hg.admin')
613 def edit_emails(self, user_id):
613 def edit_emails(self, user_id):
@@ -623,7 +623,7 b' class UsersController(BaseController):'
623
623
624 defaults = c.user.get_dict()
624 defaults = c.user.get_dict()
625 return htmlfill.render(
625 return htmlfill.render(
626 render('admin/users/user_edit.html'),
626 render('admin/users/user_edit.mako'),
627 defaults=defaults,
627 defaults=defaults,
628 encoding="UTF-8",
628 encoding="UTF-8",
629 force_defaults=False)
629 force_defaults=False)
@@ -685,7 +685,7 b' class UsersController(BaseController):'
685
685
686 defaults = c.user.get_dict()
686 defaults = c.user.get_dict()
687 return htmlfill.render(
687 return htmlfill.render(
688 render('admin/users/user_edit.html'),
688 render('admin/users/user_edit.mako'),
689 defaults=defaults,
689 defaults=defaults,
690 encoding="UTF-8",
690 encoding="UTF-8",
691 force_defaults=False)
691 force_defaults=False)
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2011-2016 RhodeCode GmbH
3 # Copyright (C) 2011-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
@@ -34,8 +34,8 b' log = logging.getLogger(__name__)'
34
34
35 class BookmarksController(BaseReferencesController):
35 class BookmarksController(BaseReferencesController):
36
36
37 partials_template = 'bookmarks/bookmarks_data.html'
37 partials_template = 'bookmarks/bookmarks_data.mako'
38 template = 'bookmarks/bookmarks.html'
38 template = 'bookmarks/bookmarks.mako'
39
39
40 def __before__(self):
40 def __before__(self):
41 super(BookmarksController, self).__before__()
41 super(BookmarksController, self).__before__()
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -34,8 +34,8 b' log = logging.getLogger(__name__)'
34
34
35 class BranchesController(BaseReferencesController):
35 class BranchesController(BaseReferencesController):
36
36
37 partials_template = 'branches/branches_data.html'
37 partials_template = 'branches/branches_data.mako'
38 template = 'branches/branches.html'
38 template = 'branches/branches.mako'
39
39
40 def __before__(self):
40 def __before__(self):
41 super(BranchesController, self).__before__()
41 super(BranchesController, self).__before__()
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -30,7 +30,8 b' from pylons.i18n.translation import _'
30 from webob.exc import HTTPNotFound, HTTPBadRequest
30 from webob.exc import HTTPNotFound, HTTPBadRequest
31
31
32 import rhodecode.lib.helpers as h
32 import rhodecode.lib.helpers as h
33 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
33 from rhodecode.lib.auth import (
34 LoginRequired, HasRepoPermissionAnyDecorator, XHRRequired)
34 from rhodecode.lib.base import BaseRepoController, render
35 from rhodecode.lib.base import BaseRepoController, render
35 from rhodecode.lib.ext_json import json
36 from rhodecode.lib.ext_json import json
36 from rhodecode.lib.graphmod import _colored, _dagwalker
37 from rhodecode.lib.graphmod import _colored, _dagwalker
@@ -98,7 +99,7 b' class ChangelogController(BaseRepoContro'
98 redirect(h.url('changelog_home', repo_name=repo.repo_name))
99 redirect(h.url('changelog_home', repo_name=repo.repo_name))
99 raise HTTPBadRequest()
100 raise HTTPBadRequest()
100
101
101 def _graph(self, repo, commits):
102 def _graph(self, repo, commits, prev_data=None, next_data=None):
102 """
103 """
103 Generates a DAG graph for repo
104 Generates a DAG graph for repo
104
105
@@ -106,12 +107,30 b' class ChangelogController(BaseRepoContro'
106 :param commits: list of commits
107 :param commits: list of commits
107 """
108 """
108 if not commits:
109 if not commits:
109 c.jsdata = json.dumps([])
110 return json.dumps([])
110 return
111
112 def serialize(commit, parents=True):
113 data = dict(
114 raw_id=commit.raw_id,
115 idx=commit.idx,
116 branch=commit.branch,
117 )
118 if parents:
119 data['parents'] = [
120 serialize(x, parents=False) for x in commit.parents]
121 return data
122
123 prev_data = prev_data or []
124 next_data = next_data or []
125
126 current = [serialize(x) for x in commits]
127 commits = prev_data + current + next_data
111
128
112 dag = _dagwalker(repo, commits)
129 dag = _dagwalker(repo, commits)
113 data = [['', vtx, edges] for vtx, edges in _colored(dag)]
130
114 c.jsdata = json.dumps(data)
131 data = [[commit_id, vtx, edges, branch]
132 for commit_id, vtx, edges, branch in _colored(dag)]
133 return json.dumps(data), json.dumps(current)
115
134
116 def _check_if_valid_branch(self, branch_name, repo_name, f_path):
135 def _check_if_valid_branch(self, branch_name, repo_name, f_path):
117 if branch_name not in c.rhodecode_repo.branches_all:
136 if branch_name not in c.rhodecode_repo.branches_all:
@@ -120,26 +139,37 b' class ChangelogController(BaseRepoContro'
120 redirect(url('changelog_file_home', repo_name=repo_name,
139 redirect(url('changelog_file_home', repo_name=repo_name,
121 revision=branch_name, f_path=f_path or ''))
140 revision=branch_name, f_path=f_path or ''))
122
141
142 def _load_changelog_data(self, collection, page, chunk_size, branch_name=None, dynamic=False):
143 c.total_cs = len(collection)
144 c.showing_commits = min(chunk_size, c.total_cs)
145 c.pagination = RepoPage(collection, page=page, item_count=c.total_cs,
146 items_per_page=chunk_size, branch=branch_name)
147
148 c.next_page = c.pagination.next_page
149 c.prev_page = c.pagination.previous_page
150
151 if dynamic:
152 if request.GET.get('chunk') != 'next':
153 c.next_page = None
154 if request.GET.get('chunk') != 'prev':
155 c.prev_page = None
156
157 page_commit_ids = [x.raw_id for x in c.pagination]
158 c.comments = c.rhodecode_db_repo.get_comments(page_commit_ids)
159 c.statuses = c.rhodecode_db_repo.statuses(page_commit_ids)
160
123 @LoginRequired()
161 @LoginRequired()
124 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
162 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
125 'repository.admin')
163 'repository.admin')
126 def index(self, repo_name, revision=None, f_path=None):
164 def index(self, repo_name, revision=None, f_path=None):
127 commit_id = revision
165 commit_id = revision
128 limit = 100
166 chunk_size = 20
167
168 c.branch_name = branch_name = request.GET.get('branch', None)
169 c.book_name = book_name = request.GET.get('bookmark', None)
129 hist_limit = safe_int(request.GET.get('limit')) or None
170 hist_limit = safe_int(request.GET.get('limit')) or None
130 if request.GET.get('size'):
131 c.size = safe_int(request.GET.get('size'), 1)
132 session['changelog_size'] = c.size
133 session.save()
134 else:
135 c.size = int(session.get('changelog_size', DEFAULT_CHANGELOG_SIZE))
136
137 # min size must be 1 and less than limit
138 c.size = max(c.size, 1) if c.size <= limit else limit
139
171
140 p = safe_int(request.GET.get('page', 1), 1)
172 p = safe_int(request.GET.get('page', 1), 1)
141 c.branch_name = branch_name = request.GET.get('branch', None)
142 c.book_name = book_name = request.GET.get('bookmark', None)
143
173
144 c.selected_name = branch_name or book_name
174 c.selected_name = branch_name or book_name
145 if not commit_id and branch_name:
175 if not commit_id and branch_name:
@@ -147,6 +177,8 b' class ChangelogController(BaseRepoContro'
147
177
148 c.changelog_for_path = f_path
178 c.changelog_for_path = f_path
149 pre_load = ['author', 'branch', 'date', 'message', 'parents']
179 pre_load = ['author', 'branch', 'date', 'message', 'parents']
180 commit_ids = []
181
150 try:
182 try:
151 if f_path:
183 if f_path:
152 log.debug('generating changelog for path %s', f_path)
184 log.debug('generating changelog for path %s', f_path)
@@ -174,13 +206,9 b' class ChangelogController(BaseRepoContro'
174 collection = c.rhodecode_repo.get_commits(
206 collection = c.rhodecode_repo.get_commits(
175 branch_name=branch_name, pre_load=pre_load)
207 branch_name=branch_name, pre_load=pre_load)
176
208
177 c.total_cs = len(collection)
209 self._load_changelog_data(
178 c.showing_commits = min(c.size, c.total_cs)
210 collection, p, chunk_size, c.branch_name, dynamic=f_path)
179 c.pagination = RepoPage(collection, page=p, item_count=c.total_cs,
211
180 items_per_page=c.size, branch=branch_name)
181 page_commit_ids = [x.raw_id for x in c.pagination]
182 c.comments = c.rhodecode_db_repo.get_comments(page_commit_ids)
183 c.statuses = c.rhodecode_db_repo.statuses(page_commit_ids)
184 except EmptyRepositoryError as e:
212 except EmptyRepositoryError as e:
185 h.flash(safe_str(e), category='warning')
213 h.flash(safe_str(e), category='warning')
186 return redirect(url('summary_home', repo_name=repo_name))
214 return redirect(url('summary_home', repo_name=repo_name))
@@ -193,24 +221,64 b' class ChangelogController(BaseRepoContro'
193 if (request.environ.get('HTTP_X_PARTIAL_XHR')
221 if (request.environ.get('HTTP_X_PARTIAL_XHR')
194 or request.environ.get('HTTP_X_PJAX')):
222 or request.environ.get('HTTP_X_PJAX')):
195 # loading from ajax, we don't want the first result, it's popped
223 # loading from ajax, we don't want the first result, it's popped
196 return render('changelog/changelog_file_history.html')
224 return render('changelog/changelog_file_history.mako')
225
226 if not f_path:
227 commit_ids = c.pagination
197
228
198 if f_path:
229 c.graph_data, c.graph_commits = self._graph(
199 revs = []
230 c.rhodecode_repo, commit_ids)
200 else:
201 revs = c.pagination
202 self._graph(c.rhodecode_repo, revs)
203
231
204 return render('changelog/changelog.html')
232 return render('changelog/changelog.mako')
205
233
206 @LoginRequired()
234 @LoginRequired()
207 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
235 @XHRRequired()
208 'repository.admin')
236 @HasRepoPermissionAnyDecorator(
209 def changelog_details(self, commit_id):
237 'repository.read', 'repository.write', 'repository.admin')
210 if request.environ.get('HTTP_X_PARTIAL_XHR'):
238 def changelog_elements(self, repo_name):
211 c.commit = c.rhodecode_repo.get_commit(commit_id=commit_id)
239 commit_id = None
212 return render('changelog/changelog_details.html')
240 chunk_size = 20
213 raise HTTPNotFound()
241
242 def wrap_for_error(err):
243 return '<tr><td colspan="9" class="alert alert-error">ERROR: {}</td></tr>'.format(err)
244
245 c.branch_name = branch_name = request.GET.get('branch', None)
246 c.book_name = book_name = request.GET.get('bookmark', None)
247
248 p = safe_int(request.GET.get('page', 1), 1)
249
250 c.selected_name = branch_name or book_name
251 if not commit_id and branch_name:
252 if branch_name not in c.rhodecode_repo.branches_all:
253 return wrap_for_error(
254 safe_str('Missing branch: {}'.format(branch_name)))
255
256 pre_load = ['author', 'branch', 'date', 'message', 'parents']
257 collection = c.rhodecode_repo.get_commits(
258 branch_name=branch_name, pre_load=pre_load)
259
260 try:
261 self._load_changelog_data(collection, p, chunk_size, dynamic=True)
262 except EmptyRepositoryError as e:
263 return wrap_for_error(safe_str(e))
264 except (RepositoryError, CommitDoesNotExistError, Exception) as e:
265 log.exception('Failed to fetch commits')
266 return wrap_for_error(safe_str(e))
267
268 prev_data = None
269 next_data = None
270
271 prev_graph = json.loads(request.POST.get('graph', ''))
272
273 if request.GET.get('chunk') == 'prev':
274 next_data = prev_graph
275 elif request.GET.get('chunk') == 'next':
276 prev_data = prev_graph
277
278 c.graph_data, c.graph_commits = self._graph(
279 c.rhodecode_repo, c.pagination,
280 prev_data=prev_data, next_data=next_data)
281 return render('changelog/changelog_elements.mako')
214
282
215 @LoginRequired()
283 @LoginRequired()
216 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
284 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
@@ -218,5 +286,5 b' class ChangelogController(BaseRepoContro'
218 def changelog_summary(self, repo_name):
286 def changelog_summary(self, repo_name):
219 if request.environ.get('HTTP_X_PJAX'):
287 if request.environ.get('HTTP_X_PJAX'):
220 _load_changelog_summary()
288 _load_changelog_summary()
221 return render('changelog/changelog_summary_data.html')
289 return render('changelog/changelog_summary_data.mako')
222 raise HTTPNotFound()
290 raise HTTPNotFound()
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -46,7 +46,7 b' from rhodecode.lib.vcs.exceptions import'
46 RepositoryError, CommitDoesNotExistError, NodeDoesNotExistError)
46 RepositoryError, CommitDoesNotExistError, NodeDoesNotExistError)
47 from rhodecode.model.db import ChangesetComment, ChangesetStatus
47 from rhodecode.model.db import ChangesetComment, ChangesetStatus
48 from rhodecode.model.changeset_status import ChangesetStatusModel
48 from rhodecode.model.changeset_status import ChangesetStatusModel
49 from rhodecode.model.comment import ChangesetCommentsModel
49 from rhodecode.model.comment import CommentsModel
50 from rhodecode.model.meta import Session
50 from rhodecode.model.meta import Session
51 from rhodecode.model.repo import RepoModel
51 from rhodecode.model.repo import RepoModel
52
52
@@ -198,15 +198,20 b' class ChangesetController(BaseRepoContro'
198 c.lines_added = 0
198 c.lines_added = 0
199 c.lines_deleted = 0
199 c.lines_deleted = 0
200
200
201 # auto collapse if we have more than limit
202 collapse_limit = diffs.DiffProcessor._collapse_commits_over
203 c.collapse_all_commits = len(c.commit_ranges) > collapse_limit
204
201 c.commit_statuses = ChangesetStatus.STATUSES
205 c.commit_statuses = ChangesetStatus.STATUSES
202 c.inline_comments = []
206 c.inline_comments = []
203 c.files = []
207 c.files = []
204
208
205 c.statuses = []
209 c.statuses = []
206 c.comments = []
210 c.comments = []
211 c.unresolved_comments = []
207 if len(c.commit_ranges) == 1:
212 if len(c.commit_ranges) == 1:
208 commit = c.commit_ranges[0]
213 commit = c.commit_ranges[0]
209 c.comments = ChangesetCommentsModel().get_comments(
214 c.comments = CommentsModel().get_comments(
210 c.rhodecode_db_repo.repo_id,
215 c.rhodecode_db_repo.repo_id,
211 revision=commit.raw_id)
216 revision=commit.raw_id)
212 c.statuses.append(ChangesetStatusModel().get_status(
217 c.statuses.append(ChangesetStatusModel().get_status(
@@ -222,6 +227,9 b' class ChangesetController(BaseRepoContro'
222 for pr in prs:
227 for pr in prs:
223 c.comments.extend(pr.comments)
228 c.comments.extend(pr.comments)
224
229
230 c.unresolved_comments = CommentsModel()\
231 .get_commit_unresolved_todos(commit.raw_id)
232
225 # Iterate over ranges (default commit view is always one commit)
233 # Iterate over ranges (default commit view is always one commit)
226 for commit in c.commit_ranges:
234 for commit in c.commit_ranges:
227 c.changes[commit.raw_id] = []
235 c.changes[commit.raw_id] = []
@@ -251,9 +259,9 b' class ChangesetController(BaseRepoContro'
251 return None
259 return None
252 return get_node
260 return get_node
253
261
254 inline_comments = ChangesetCommentsModel().get_inline_comments(
262 inline_comments = CommentsModel().get_inline_comments(
255 c.rhodecode_db_repo.repo_id, revision=commit.raw_id)
263 c.rhodecode_db_repo.repo_id, revision=commit.raw_id)
256 c.inline_cnt = ChangesetCommentsModel().get_inline_comments_count(
264 c.inline_cnt = CommentsModel().get_inline_comments_count(
257 inline_comments)
265 inline_comments)
258
266
259 diffset = codeblocks.DiffSet(
267 diffset = codeblocks.DiffSet(
@@ -271,7 +279,6 b' class ChangesetController(BaseRepoContro'
271 # sort comments by how they were generated
279 # sort comments by how they were generated
272 c.comments = sorted(c.comments, key=lambda x: x.comment_id)
280 c.comments = sorted(c.comments, key=lambda x: x.comment_id)
273
281
274
275 if len(c.commit_ranges) == 1:
282 if len(c.commit_ranges) == 1:
276 c.commit = c.commit_ranges[0]
283 c.commit = c.commit_ranges[0]
277 c.parent_tmpl = ''.join(
284 c.parent_tmpl = ''.join(
@@ -284,17 +291,17 b' class ChangesetController(BaseRepoContro'
284 elif method == 'patch':
291 elif method == 'patch':
285 response.content_type = 'text/plain'
292 response.content_type = 'text/plain'
286 c.diff = safe_unicode(diff)
293 c.diff = safe_unicode(diff)
287 return render('changeset/patch_changeset.html')
294 return render('changeset/patch_changeset.mako')
288 elif method == 'raw':
295 elif method == 'raw':
289 response.content_type = 'text/plain'
296 response.content_type = 'text/plain'
290 return diff
297 return diff
291 elif method == 'show':
298 elif method == 'show':
292 if len(c.commit_ranges) == 1:
299 if len(c.commit_ranges) == 1:
293 return render('changeset/changeset.html')
300 return render('changeset/changeset.mako')
294 else:
301 else:
295 c.ancestor = None
302 c.ancestor = None
296 c.target_repo = c.rhodecode_db_repo
303 c.target_repo = c.rhodecode_db_repo
297 return render('changeset/changeset_range.html')
304 return render('changeset/changeset_range.mako')
298
305
299 @LoginRequired()
306 @LoginRequired()
300 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
307 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
@@ -330,29 +337,39 b' class ChangesetController(BaseRepoContro'
330 commit_id = revision
337 commit_id = revision
331 status = request.POST.get('changeset_status', None)
338 status = request.POST.get('changeset_status', None)
332 text = request.POST.get('text')
339 text = request.POST.get('text')
340 comment_type = request.POST.get('comment_type')
341 resolves_comment_id = request.POST.get('resolves_comment_id', None)
342
333 if status:
343 if status:
334 text = text or (_('Status change %(transition_icon)s %(status)s')
344 text = text or (_('Status change %(transition_icon)s %(status)s')
335 % {'transition_icon': '>',
345 % {'transition_icon': '>',
336 'status': ChangesetStatus.get_status_lbl(status)})
346 'status': ChangesetStatus.get_status_lbl(status)})
337
347
338 multi_commit_ids = filter(
348 multi_commit_ids = []
339 lambda s: s not in ['', None],
349 for _commit_id in request.POST.get('commit_ids', '').split(','):
340 request.POST.get('commit_ids', '').split(','),)
350 if _commit_id not in ['', None, EmptyCommit.raw_id]:
351 if _commit_id not in multi_commit_ids:
352 multi_commit_ids.append(_commit_id)
341
353
342 commit_ids = multi_commit_ids or [commit_id]
354 commit_ids = multi_commit_ids or [commit_id]
355
343 comment = None
356 comment = None
344 for current_id in filter(None, commit_ids):
357 for current_id in filter(None, commit_ids):
345 c.co = comment = ChangesetCommentsModel().create(
358 c.co = comment = CommentsModel().create(
346 text=text,
359 text=text,
347 repo=c.rhodecode_db_repo.repo_id,
360 repo=c.rhodecode_db_repo.repo_id,
348 user=c.rhodecode_user.user_id,
361 user=c.rhodecode_user.user_id,
349 revision=current_id,
362 commit_id=current_id,
350 f_path=request.POST.get('f_path'),
363 f_path=request.POST.get('f_path'),
351 line_no=request.POST.get('line'),
364 line_no=request.POST.get('line'),
352 status_change=(ChangesetStatus.get_status_lbl(status)
365 status_change=(ChangesetStatus.get_status_lbl(status)
353 if status else None),
366 if status else None),
354 status_change_type=status
367 status_change_type=status,
368 comment_type=comment_type,
369 resolves_comment_id=resolves_comment_id
355 )
370 )
371 c.inline_comment = True if comment.line_no else False
372
356 # get status if set !
373 # get status if set !
357 if status:
374 if status:
358 # if latest status was from pull request and it's closed
375 # if latest status was from pull request and it's closed
@@ -386,7 +403,7 b' class ChangesetController(BaseRepoContro'
386 if comment:
403 if comment:
387 data.update(comment.get_dict())
404 data.update(comment.get_dict())
388 data.update({'rendered_text':
405 data.update({'rendered_text':
389 render('changeset/changeset_comment_block.html')})
406 render('changeset/changeset_comment_block.mako')})
390
407
391 return data
408 return data
392
409
@@ -417,10 +434,15 b' class ChangesetController(BaseRepoContro'
417 @jsonify
434 @jsonify
418 def delete_comment(self, repo_name, comment_id):
435 def delete_comment(self, repo_name, comment_id):
419 comment = ChangesetComment.get(comment_id)
436 comment = ChangesetComment.get(comment_id)
437 if not comment:
438 log.debug('Comment with id:%s not found, skipping', comment_id)
439 # comment already deleted in another call probably
440 return True
441
420 owner = (comment.author.user_id == c.rhodecode_user.user_id)
442 owner = (comment.author.user_id == c.rhodecode_user.user_id)
421 is_repo_admin = h.HasRepoPermissionAny('repository.admin')(c.repo_name)
443 is_repo_admin = h.HasRepoPermissionAny('repository.admin')(c.repo_name)
422 if h.HasPermissionAny('hg.admin')() or is_repo_admin or owner:
444 if h.HasPermissionAny('hg.admin')() or is_repo_admin or owner:
423 ChangesetCommentsModel().delete(comment=comment)
445 CommentsModel().delete(comment=comment)
424 Session().commit()
446 Session().commit()
425 return True
447 return True
426 else:
448 else:
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2012-2016 RhodeCode GmbH
3 # Copyright (C) 2012-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
@@ -79,6 +79,7 b' class CompareController(BaseRepoControll'
79 def index(self, repo_name):
79 def index(self, repo_name):
80 c.compare_home = True
80 c.compare_home = True
81 c.commit_ranges = []
81 c.commit_ranges = []
82 c.collapse_all_commits = False
82 c.diffset = None
83 c.diffset = None
83 c.limited_diff = False
84 c.limited_diff = False
84 source_repo = c.rhodecode_db_repo.repo_name
85 source_repo = c.rhodecode_db_repo.repo_name
@@ -90,7 +91,8 b' class CompareController(BaseRepoControll'
90 c.target_ref_type = ""
91 c.target_ref_type = ""
91 c.commit_statuses = ChangesetStatus.STATUSES
92 c.commit_statuses = ChangesetStatus.STATUSES
92 c.preview_mode = False
93 c.preview_mode = False
93 return render('compare/compare_diff.html')
94 c.file_path = None
95 return render('compare/compare_diff.mako')
94
96
95 @LoginRequired()
97 @LoginRequired()
96 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
98 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
@@ -103,8 +105,10 b' class CompareController(BaseRepoControll'
103
105
104 # target_ref will be evaluated in target_repo
106 # target_ref will be evaluated in target_repo
105 target_repo_name = request.GET.get('target_repo', source_repo_name)
107 target_repo_name = request.GET.get('target_repo', source_repo_name)
106 target_path, target_id = parse_path_ref(target_ref)
108 target_path, target_id = parse_path_ref(
109 target_ref, default_path=request.GET.get('f_path', ''))
107
110
111 c.file_path = target_path
108 c.commit_statuses = ChangesetStatus.STATUSES
112 c.commit_statuses = ChangesetStatus.STATUSES
109
113
110 # if merge is True
114 # if merge is True
@@ -115,7 +119,6 b' class CompareController(BaseRepoControll'
115 # if merge is False
119 # if merge is False
116 # Show a raw diff of source/target refs even if no ancestor exists
120 # Show a raw diff of source/target refs even if no ancestor exists
117
121
118
119 # c.fulldiff disables cut_off_limit
122 # c.fulldiff disables cut_off_limit
120 c.fulldiff = str2bool(request.GET.get('fulldiff'))
123 c.fulldiff = str2bool(request.GET.get('fulldiff'))
121
124
@@ -131,7 +134,8 b' class CompareController(BaseRepoControll'
131 target_repo=source_repo_name,
134 target_repo=source_repo_name,
132 target_ref_type=source_ref_type,
135 target_ref_type=source_ref_type,
133 target_ref=source_ref,
136 target_ref=source_ref,
134 merge=merge and '1' or '')
137 merge=merge and '1' or '',
138 f_path=target_path)
135
139
136 source_repo = Repository.get_by_repo_name(source_repo_name)
140 source_repo = Repository.get_by_repo_name(source_repo_name)
137 target_repo = Repository.get_by_repo_name(target_repo_name)
141 target_repo = Repository.get_by_repo_name(target_repo_name)
@@ -151,8 +155,11 b' class CompareController(BaseRepoControll'
151 h.flash(msg, category='error')
155 h.flash(msg, category='error')
152 return redirect(url('compare_home', repo_name=c.repo_name))
156 return redirect(url('compare_home', repo_name=c.repo_name))
153
157
154 source_alias = source_repo.scm_instance().alias
158 source_scm = source_repo.scm_instance()
155 target_alias = target_repo.scm_instance().alias
159 target_scm = target_repo.scm_instance()
160
161 source_alias = source_scm.alias
162 target_alias = target_scm.alias
156 if source_alias != target_alias:
163 if source_alias != target_alias:
157 msg = _('The comparison of two different kinds of remote repos '
164 msg = _('The comparison of two different kinds of remote repos '
158 'is not available')
165 'is not available')
@@ -175,34 +182,42 b' class CompareController(BaseRepoControll'
175 c.source_ref_type = source_ref_type
182 c.source_ref_type = source_ref_type
176 c.target_ref_type = target_ref_type
183 c.target_ref_type = target_ref_type
177
184
178 source_scm = source_repo.scm_instance()
179 target_scm = target_repo.scm_instance()
180
181 pre_load = ["author", "branch", "date", "message"]
185 pre_load = ["author", "branch", "date", "message"]
182 c.ancestor = None
186 c.ancestor = None
183 try:
187
184 c.commit_ranges = source_scm.compare(
188 if c.file_path:
185 source_commit.raw_id, target_commit.raw_id,
189 if source_commit == target_commit:
186 target_scm, merge, pre_load=pre_load)
190 c.commit_ranges = []
187 if merge:
191 else:
188 c.ancestor = source_scm.get_common_ancestor(
192 c.commit_ranges = [target_commit]
189 source_commit.raw_id, target_commit.raw_id, target_scm)
193 else:
190 except RepositoryRequirementError:
194 try:
191 msg = _('Could not compare repos with different '
195 c.commit_ranges = source_scm.compare(
192 'large file settings')
196 source_commit.raw_id, target_commit.raw_id,
193 log.error(msg)
197 target_scm, merge, pre_load=pre_load)
194 if partial:
198 if merge:
195 return msg
199 c.ancestor = source_scm.get_common_ancestor(
196 h.flash(msg, category='error')
200 source_commit.raw_id, target_commit.raw_id, target_scm)
197 return redirect(url('compare_home', repo_name=c.repo_name))
201 except RepositoryRequirementError:
202 msg = _('Could not compare repos with different '
203 'large file settings')
204 log.error(msg)
205 if partial:
206 return msg
207 h.flash(msg, category='error')
208 return redirect(url('compare_home', repo_name=c.repo_name))
198
209
199 c.statuses = c.rhodecode_db_repo.statuses(
210 c.statuses = c.rhodecode_db_repo.statuses(
200 [x.raw_id for x in c.commit_ranges])
211 [x.raw_id for x in c.commit_ranges])
201
212
202 if partial: # for PR ajax commits loader
213 # auto collapse if we have more than limit
214 collapse_limit = diffs.DiffProcessor._collapse_commits_over
215 c.collapse_all_commits = len(c.commit_ranges) > collapse_limit
216
217 if partial: # for PR ajax commits loader
203 if not c.ancestor:
218 if not c.ancestor:
204 return '' # cannot merge if there is no ancestor
219 return '' # cannot merge if there is no ancestor
205 return render('compare/compare_commits.html')
220 return render('compare/compare_commits.mako')
206
221
207 if c.ancestor:
222 if c.ancestor:
208 # case we want a simple diff without incoming commits,
223 # case we want a simple diff without incoming commits,
@@ -238,7 +253,8 b' class CompareController(BaseRepoControll'
238
253
239 txtdiff = source_repo.scm_instance().get_diff(
254 txtdiff = source_repo.scm_instance().get_diff(
240 commit1=source_commit, commit2=target_commit,
255 commit1=source_commit, commit2=target_commit,
241 path1=source_path, path=target_path)
256 path=target_path, path1=source_path)
257
242 diff_processor = diffs.DiffProcessor(
258 diff_processor = diffs.DiffProcessor(
243 txtdiff, format='newdiff', diff_limit=diff_limit,
259 txtdiff, format='newdiff', diff_limit=diff_limit,
244 file_limit=file_limit, show_full_diff=c.fulldiff)
260 file_limit=file_limit, show_full_diff=c.fulldiff)
@@ -260,5 +276,7 b' class CompareController(BaseRepoControll'
260 ).render_patchset(_parsed, source_ref, target_ref)
276 ).render_patchset(_parsed, source_ref, target_ref)
261
277
262 c.preview_mode = merge
278 c.preview_mode = merge
279 c.source_commit = source_commit
280 c.target_commit = target_commit
263
281
264 return render('compare/compare_diff.html')
282 return render('compare/compare_diff.mako')
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2014-2016 RhodeCode GmbH
3 # Copyright (C) 2014-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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -144,7 +144,7 b' class FilesController(BaseRepoController'
144 log.debug('Generating cached file tree for %s, %s, %s',
144 log.debug('Generating cached file tree for %s, %s, %s',
145 repo_name, commit_id, f_path)
145 repo_name, commit_id, f_path)
146 c.full_load = full_load
146 c.full_load = full_load
147 return render('files/files_browser_tree.html')
147 return render('files/files_browser_tree.mako')
148
148
149 cache_manager = self.__get_tree_cache_manager(
149 cache_manager = self.__get_tree_cache_manager(
150 repo_name, caches.FILE_TREE)
150 repo_name, caches.FILE_TREE)
@@ -255,9 +255,9 b' class FilesController(BaseRepoController'
255 raise HTTPNotFound()
255 raise HTTPNotFound()
256
256
257 if request.environ.get('HTTP_X_PJAX'):
257 if request.environ.get('HTTP_X_PJAX'):
258 return render('files/files_pjax.html')
258 return render('files/files_pjax.mako')
259
259
260 return render('files/files.html')
260 return render('files/files.mako')
261
261
262 @LoginRequired()
262 @LoginRequired()
263 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
263 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
@@ -305,7 +305,7 b' class FilesController(BaseRepoController'
305 c.authors.append((
305 c.authors.append((
306 h.email(author),
306 h.email(author),
307 h.person(author, 'username_or_name_or_email')))
307 h.person(author, 'username_or_name_or_email')))
308 return render('files/file_authors_box.html')
308 return render('files/file_authors_box.mako')
309
309
310 @LoginRequired()
310 @LoginRequired()
311 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
311 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
@@ -465,7 +465,7 b' class FilesController(BaseRepoController'
465 'Deleted file %s via RhodeCode Enterprise') % (f_path)
465 'Deleted file %s via RhodeCode Enterprise') % (f_path)
466 c.f_path = f_path
466 c.f_path = f_path
467
467
468 return render('files/files_delete.html')
468 return render('files/files_delete.mako')
469
469
470 @CSRFRequired()
470 @CSRFRequired()
471 @LoginRequired()
471 @LoginRequired()
@@ -574,7 +574,7 b' class FilesController(BaseRepoController'
574 'Edited file %s via RhodeCode Enterprise') % (f_path)
574 'Edited file %s via RhodeCode Enterprise') % (f_path)
575 c.f_path = f_path
575 c.f_path = f_path
576
576
577 return render('files/files_edit.html')
577 return render('files/files_edit.mako')
578
578
579 def _is_valid_head(self, commit_id, repo):
579 def _is_valid_head(self, commit_id, repo):
580 # check if commit is a branch identifier- basically we cannot
580 # check if commit is a branch identifier- basically we cannot
@@ -700,7 +700,7 b' class FilesController(BaseRepoController'
700 c.default_message = (_('Added file via RhodeCode Enterprise'))
700 c.default_message = (_('Added file via RhodeCode Enterprise'))
701 c.f_path = f_path
701 c.f_path = f_path
702
702
703 return render('files/files_add.html')
703 return render('files/files_add.mako')
704
704
705 @LoginRequired()
705 @LoginRequired()
706 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
706 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
@@ -799,21 +799,15 b' class FilesController(BaseRepoController'
799 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
799 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
800 'repository.admin')
800 'repository.admin')
801 def diff(self, repo_name, f_path):
801 def diff(self, repo_name, f_path):
802 ignore_whitespace = request.GET.get('ignorews') == '1'
802
803 line_context = request.GET.get('context', 3)
803 c.action = request.GET.get('diff')
804 diff1 = request.GET.get('diff1', '')
804 diff1 = request.GET.get('diff1', '')
805 diff2 = request.GET.get('diff2', '')
805
806
806 path1, diff1 = parse_path_ref(diff1, default_path=f_path)
807 path1, diff1 = parse_path_ref(diff1, default_path=f_path)
807
808
808 diff2 = request.GET.get('diff2', '')
809 ignore_whitespace = str2bool(request.GET.get('ignorews'))
809 c.action = request.GET.get('diff')
810 line_context = request.GET.get('context', 3)
810 c.no_changes = diff1 == diff2
811 c.f_path = f_path
812 c.big_diff = False
813 c.ignorews_url = _ignorews_url
814 c.context_url = _context_url
815 c.changes = OrderedDict()
816 c.changes[diff2] = []
817
811
818 if not any((diff1, diff2)):
812 if not any((diff1, diff2)):
819 h.flash(
813 h.flash(
@@ -821,18 +815,16 b' class FilesController(BaseRepoController'
821 category='error')
815 category='error')
822 raise HTTPBadRequest()
816 raise HTTPBadRequest()
823
817
824 # special case if we want a show commit_id only, it's impl here
818 if c.action not in ['download', 'raw']:
825 # to reduce JS and callbacks
819 # redirect to new view if we render diff
826
820 return redirect(
827 if request.GET.get('show_rev') and diff1:
821 url('compare_url', repo_name=repo_name,
828 if str2bool(request.GET.get('annotate', 'False')):
822 source_ref_type='rev',
829 _url = url('files_annotate_home', repo_name=c.repo_name,
823 source_ref=diff1,
830 revision=diff1, f_path=path1)
824 target_repo=c.repo_name,
831 else:
825 target_ref_type='rev',
832 _url = url('files_home', repo_name=c.repo_name,
826 target_ref=diff2,
833 revision=diff1, f_path=path1)
827 f_path=f_path))
834
835 return redirect(_url)
836
828
837 try:
829 try:
838 node1 = self._get_file_node(diff1, path1)
830 node1 = self._get_file_node(diff1, path1)
@@ -877,98 +869,40 b' class FilesController(BaseRepoController'
877 return diff.as_raw()
869 return diff.as_raw()
878
870
879 else:
871 else:
880 fid = h.FID(diff2, node2.path)
872 return redirect(
881 line_context_lcl = get_line_ctx(fid, request.GET)
873 url('compare_url', repo_name=repo_name,
882 ign_whitespace_lcl = get_ignore_ws(fid, request.GET)
874 source_ref_type='rev',
883
875 source_ref=diff1,
884 __, commit1, commit2, diff, st, data = diffs.wrapped_diff(
876 target_repo=c.repo_name,
885 filenode_old=node1,
877 target_ref_type='rev',
886 filenode_new=node2,
878 target_ref=diff2,
887 diff_limit=self.cut_off_limit_diff,
879 f_path=f_path))
888 file_limit=self.cut_off_limit_file,
889 show_full_diff=request.GET.get('fulldiff'),
890 ignore_whitespace=ign_whitespace_lcl,
891 line_context=line_context_lcl,)
892
893 c.lines_added = data['stats']['added'] if data else 0
894 c.lines_deleted = data['stats']['deleted'] if data else 0
895 c.files = [data]
896 c.commit_ranges = [c.commit_1, c.commit_2]
897 c.ancestor = None
898 c.statuses = []
899 c.target_repo = c.rhodecode_db_repo
900 c.filename1 = node1.path
901 c.filename = node2.path
902 c.binary_file = node1.is_binary or node2.is_binary
903 operation = data['operation'] if data else ''
904
905 commit_changes = {
906 # TODO: it's passing the old file to the diff to keep the
907 # standard but this is not being used for this template,
908 # but might need both files in the future or a more standard
909 # way to work with that
910 'fid': [commit1, commit2, operation,
911 c.filename, diff, st, data]
912 }
913
914 c.changes = commit_changes
915
916 return render('files/file_diff.html')
917
880
918 @LoginRequired()
881 @LoginRequired()
919 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
882 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
920 'repository.admin')
883 'repository.admin')
921 def diff_2way(self, repo_name, f_path):
884 def diff_2way(self, repo_name, f_path):
885 """
886 Kept only to make OLD links work
887 """
922 diff1 = request.GET.get('diff1', '')
888 diff1 = request.GET.get('diff1', '')
923 diff2 = request.GET.get('diff2', '')
889 diff2 = request.GET.get('diff2', '')
924
890
925 nodes = []
891 if not any((diff1, diff2)):
926 unknown_commits = []
892 h.flash(
927 for commit in [diff1, diff2]:
893 'Need query parameter "diff1" or "diff2" to generate a diff.',
928 try:
894 category='error')
929 nodes.append(self._get_file_node(commit, f_path))
895 raise HTTPBadRequest()
930 except (RepositoryError, NodeError):
931 log.exception('%(commit)s does not exist' % {'commit': commit})
932 unknown_commits.append(commit)
933 h.flash(h.literal(
934 _('Commit %(commit)s does not exist.') % {'commit': commit}
935 ), category='error')
936
937 if unknown_commits:
938 return redirect(url('files_home', repo_name=c.repo_name,
939 f_path=f_path))
940
941 if all(isinstance(node.commit, EmptyCommit) for node in nodes):
942 raise HTTPNotFound
943
944 node1, node2 = nodes
945
896
946 f_gitdiff = diffs.get_gitdiff(node1, node2, ignore_whitespace=False)
897 return redirect(
947 diff_processor = diffs.DiffProcessor(f_gitdiff, format='gitdiff')
898 url('compare_url', repo_name=repo_name,
948 diff_data = diff_processor.prepare()
899 source_ref_type='rev',
949
900 source_ref=diff1,
950 if not diff_data or diff_data[0]['raw_diff'] == '':
901 target_repo=c.repo_name,
951 h.flash(h.literal(_('%(file_path)s has not changed '
902 target_ref_type='rev',
952 'between %(commit_1)s and %(commit_2)s.') % {
903 target_ref=diff2,
953 'file_path': f_path,
904 f_path=f_path,
954 'commit_1': node1.commit.id,
905 diffmode='sideside'))
955 'commit_2': node2.commit.id
956 }), category='error')
957 return redirect(url('files_home', repo_name=c.repo_name,
958 f_path=f_path))
959
960 c.diff_data = diff_data[0]
961 c.FID = h.FID(diff2, node2.path)
962 # cleanup some unneeded data
963 del c.diff_data['raw_diff']
964 del c.diff_data['chunks']
965
966 c.node1 = node1
967 c.commit_1 = node1.commit
968 c.node2 = node2
969 c.commit_2 = node2.commit
970
971 return render('files/diff_2way.html')
972
906
973 def _get_file_node(self, commit_id, f_path):
907 def _get_file_node(self, commit_id, f_path):
974 if commit_id not in ['', None, 'None', '0' * 12, '0' * 40]:
908 if commit_id not in ['', None, 'None', '0' * 12, '0' * 40]:
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2011-2016 RhodeCode GmbH
3 # Copyright (C) 2011-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
@@ -50,9 +50,9 b' class FollowersController(BaseRepoContro'
50 .order_by(UserFollowing.follows_from)
50 .order_by(UserFollowing.follows_from)
51 c.followers_pager = Page(d, page=p, items_per_page=20)
51 c.followers_pager = Page(d, page=p, items_per_page=20)
52
52
53 c.followers_data = render('/followers/followers_data.html')
53 c.followers_data = render('/followers/followers_data.mako')
54
54
55 if request.environ.get('HTTP_X_PJAX'):
55 if request.environ.get('HTTP_X_PJAX'):
56 return c.followers_data
56 return c.followers_data
57
57
58 return render('/followers/followers.html')
58 return render('/followers/followers.mako')
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2011-2016 RhodeCode GmbH
3 # Copyright (C) 2011-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
@@ -122,12 +122,12 b' class ForksController(BaseRepoController'
122 d.append(r)
122 d.append(r)
123 c.forks_pager = Page(d, page=p, items_per_page=20)
123 c.forks_pager = Page(d, page=p, items_per_page=20)
124
124
125 c.forks_data = render('/forks/forks_data.html')
125 c.forks_data = render('/forks/forks_data.mako')
126
126
127 if request.environ.get('HTTP_X_PJAX'):
127 if request.environ.get('HTTP_X_PJAX'):
128 return c.forks_data
128 return c.forks_data
129
129
130 return render('/forks/forks.html')
130 return render('/forks/forks.mako')
131
131
132 @LoginRequired()
132 @LoginRequired()
133 @NotAnonymous()
133 @NotAnonymous()
@@ -144,7 +144,7 b' class ForksController(BaseRepoController'
144 defaults = self.__load_data(repo_name)
144 defaults = self.__load_data(repo_name)
145
145
146 return htmlfill.render(
146 return htmlfill.render(
147 render('forks/fork.html'),
147 render('forks/fork.mako'),
148 defaults=defaults,
148 defaults=defaults,
149 encoding="UTF-8",
149 encoding="UTF-8",
150 force_defaults=False
150 force_defaults=False
@@ -177,7 +177,7 b' class ForksController(BaseRepoController'
177 except formencode.Invalid as errors:
177 except formencode.Invalid as errors:
178 c.new_repo = errors.value['repo_name']
178 c.new_repo = errors.value['repo_name']
179 return htmlfill.render(
179 return htmlfill.render(
180 render('forks/fork.html'),
180 render('forks/fork.mako'),
181 defaults=errors.value,
181 defaults=errors.value,
182 errors=errors.error_dict or {},
182 errors=errors.error_dict or {},
183 prefix_error=False,
183 prefix_error=False,
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -97,7 +97,7 b' class HomeController(BaseController):'
97 c.repos_data = json.dumps(repo_data)
97 c.repos_data = json.dumps(repo_data)
98 c.repo_groups_data = json.dumps(repo_group_data)
98 c.repo_groups_data = json.dumps(repo_group_data)
99
99
100 return render('/index.html')
100 return render('/index.mako')
101
101
102 @LoginRequired()
102 @LoginRequired()
103 @HasRepoGroupPermissionAnyDecorator('group.read', 'group.write',
103 @HasRepoGroupPermissionAnyDecorator('group.read', 'group.write',
@@ -112,7 +112,7 b' class HomeController(BaseController):'
112 c.repos_data = json.dumps(repo_data)
112 c.repos_data = json.dumps(repo_data)
113 c.repo_groups_data = json.dumps(repo_group_data)
113 c.repo_groups_data = json.dumps(repo_group_data)
114
114
115 return render('index_repo_group.html')
115 return render('index_repo_group.mako')
116
116
117 def _get_repo_list(self, name_contains=None, repo_type=None, limit=20):
117 def _get_repo_list(self, name_contains=None, repo_type=None, limit=20):
118 query = Repository.query()\
118 query = Repository.query()\
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -205,11 +205,11 b' class JournalController(BaseController):'
205 c.journal_pager = Page(journal, page=p, items_per_page=20, url=url_generator)
205 c.journal_pager = Page(journal, page=p, items_per_page=20, url=url_generator)
206 c.journal_day_aggreagate = self._get_daily_aggregate(c.journal_pager)
206 c.journal_day_aggreagate = self._get_daily_aggregate(c.journal_pager)
207
207
208 c.journal_data = render('journal/journal_data.html')
208 c.journal_data = render('journal/journal_data.mako')
209 if request.is_xhr:
209 if request.is_xhr:
210 return c.journal_data
210 return c.journal_data
211
211
212 return render('journal/journal.html')
212 return render('journal/journal.mako')
213
213
214 @LoginRequired(auth_token_access=True)
214 @LoginRequired(auth_token_access=True)
215 @NotAnonymous()
215 @NotAnonymous()
@@ -276,10 +276,10 b' class JournalController(BaseController):'
276
276
277 c.journal_day_aggreagate = self._get_daily_aggregate(c.journal_pager)
277 c.journal_day_aggreagate = self._get_daily_aggregate(c.journal_pager)
278
278
279 c.journal_data = render('journal/journal_data.html')
279 c.journal_data = render('journal/journal_data.mako')
280 if request.is_xhr:
280 if request.is_xhr:
281 return c.journal_data
281 return c.journal_data
282 return render('journal/public_journal.html')
282 return render('journal/public_journal.mako')
283
283
284 @LoginRequired(auth_token_access=True)
284 @LoginRequired(auth_token_access=True)
285 def public_journal_atom(self):
285 def public_journal_atom(self):
This diff has been collapsed as it changes many lines, (530 lines changed) Show them Hide them
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2012-2016 RhodeCode GmbH
3 # Copyright (C) 2012-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
@@ -21,10 +21,12 b''
21 """
21 """
22 pull requests controller for rhodecode for initializing pull requests
22 pull requests controller for rhodecode for initializing pull requests
23 """
23 """
24 import types
24
25
25 import peppercorn
26 import peppercorn
26 import formencode
27 import formencode
27 import logging
28 import logging
29 import collections
28
30
29 from webob.exc import HTTPNotFound, HTTPForbidden, HTTPBadRequest
31 from webob.exc import HTTPNotFound, HTTPForbidden, HTTPBadRequest
30 from pylons import request, tmpl_context as c, url
32 from pylons import request, tmpl_context as c, url
@@ -43,125 +45,31 b' from rhodecode.lib.auth import ('
43 LoginRequired, HasRepoPermissionAnyDecorator, NotAnonymous,
45 LoginRequired, HasRepoPermissionAnyDecorator, NotAnonymous,
44 HasAcceptedRepoType, XHRRequired)
46 HasAcceptedRepoType, XHRRequired)
45 from rhodecode.lib.channelstream import channelstream_request
47 from rhodecode.lib.channelstream import channelstream_request
46 from rhodecode.lib.compat import OrderedDict
47 from rhodecode.lib.utils import jsonify
48 from rhodecode.lib.utils import jsonify
48 from rhodecode.lib.utils2 import safe_int, safe_str, str2bool, safe_unicode
49 from rhodecode.lib.utils2 import (
49 from rhodecode.lib.vcs.backends.base import EmptyCommit, UpdateFailureReason
50 safe_int, safe_str, str2bool, safe_unicode)
51 from rhodecode.lib.vcs.backends.base import (
52 EmptyCommit, UpdateFailureReason, EmptyRepository)
50 from rhodecode.lib.vcs.exceptions import (
53 from rhodecode.lib.vcs.exceptions import (
51 EmptyRepositoryError, CommitDoesNotExistError, RepositoryRequirementError,
54 EmptyRepositoryError, CommitDoesNotExistError, RepositoryRequirementError,
52 NodeDoesNotExistError)
55 NodeDoesNotExistError)
53 from rhodecode.lib.diffs import LimitedDiffContainer
56
54 from rhodecode.model.changeset_status import ChangesetStatusModel
57 from rhodecode.model.changeset_status import ChangesetStatusModel
55 from rhodecode.model.comment import ChangesetCommentsModel
58 from rhodecode.model.comment import CommentsModel
56 from rhodecode.model.db import PullRequest, ChangesetStatus, ChangesetComment, \
59 from rhodecode.model.db import (PullRequest, ChangesetStatus, ChangesetComment,
57 Repository
60 Repository, PullRequestVersion)
58 from rhodecode.model.forms import PullRequestForm
61 from rhodecode.model.forms import PullRequestForm
59 from rhodecode.model.meta import Session
62 from rhodecode.model.meta import Session
60 from rhodecode.model.pull_request import PullRequestModel
63 from rhodecode.model.pull_request import PullRequestModel, MergeCheck
61
64
62 log = logging.getLogger(__name__)
65 log = logging.getLogger(__name__)
63
66
64
67
65 class PullrequestsController(BaseRepoController):
68 class PullrequestsController(BaseRepoController):
69
66 def __before__(self):
70 def __before__(self):
67 super(PullrequestsController, self).__before__()
71 super(PullrequestsController, self).__before__()
68
72
69 def _load_compare_data(self, pull_request, inline_comments, enable_comments=True):
70 """
71 Load context data needed for generating compare diff
72
73 :param pull_request: object related to the request
74 :param enable_comments: flag to determine if comments are included
75 """
76 source_repo = pull_request.source_repo
77 source_ref_id = pull_request.source_ref_parts.commit_id
78
79 target_repo = pull_request.target_repo
80 target_ref_id = pull_request.target_ref_parts.commit_id
81
82 # despite opening commits for bookmarks/branches/tags, we always
83 # convert this to rev to prevent changes after bookmark or branch change
84 c.source_ref_type = 'rev'
85 c.source_ref = source_ref_id
86
87 c.target_ref_type = 'rev'
88 c.target_ref = target_ref_id
89
90 c.source_repo = source_repo
91 c.target_repo = target_repo
92
93 c.fulldiff = bool(request.GET.get('fulldiff'))
94
95 # diff_limit is the old behavior, will cut off the whole diff
96 # if the limit is applied otherwise will just hide the
97 # big files from the front-end
98 diff_limit = self.cut_off_limit_diff
99 file_limit = self.cut_off_limit_file
100
101 pre_load = ["author", "branch", "date", "message"]
102
103 c.commit_ranges = []
104 source_commit = EmptyCommit()
105 target_commit = EmptyCommit()
106 c.missing_requirements = False
107 try:
108 c.commit_ranges = [
109 source_repo.get_commit(commit_id=rev, pre_load=pre_load)
110 for rev in pull_request.revisions]
111
112 c.statuses = source_repo.statuses(
113 [x.raw_id for x in c.commit_ranges])
114
115 target_commit = source_repo.get_commit(
116 commit_id=safe_str(target_ref_id))
117 source_commit = source_repo.get_commit(
118 commit_id=safe_str(source_ref_id))
119 except RepositoryRequirementError:
120 c.missing_requirements = True
121
122 c.changes = {}
123 c.missing_commits = False
124 if (c.missing_requirements or
125 isinstance(source_commit, EmptyCommit) or
126 source_commit == target_commit):
127 _parsed = []
128 c.missing_commits = True
129 else:
130 vcs_diff = PullRequestModel().get_diff(pull_request)
131 diff_processor = diffs.DiffProcessor(
132 vcs_diff, format='newdiff', diff_limit=diff_limit,
133 file_limit=file_limit, show_full_diff=c.fulldiff)
134 _parsed = diff_processor.prepare()
135
136 commit_changes = OrderedDict()
137 _parsed = diff_processor.prepare()
138 c.limited_diff = isinstance(_parsed, diffs.LimitedDiffContainer)
139
140 _parsed = diff_processor.prepare()
141
142 def _node_getter(commit):
143 def get_node(fname):
144 try:
145 return commit.get_node(fname)
146 except NodeDoesNotExistError:
147 return None
148 return get_node
149
150 c.diffset = codeblocks.DiffSet(
151 repo_name=c.repo_name,
152 source_node_getter=_node_getter(target_commit),
153 target_node_getter=_node_getter(source_commit),
154 comments=inline_comments
155 ).render_patchset(_parsed, target_commit.raw_id, source_commit.raw_id)
156
157 c.included_files = []
158 c.deleted_files = []
159
160 for f in _parsed:
161 st = f['stats']
162 fid = h.FID('', f['filename'])
163 c.included_files.append(f['filename'])
164
165 def _extract_ordering(self, request):
73 def _extract_ordering(self, request):
166 column_index = safe_int(request.GET.get('order[0][column]'))
74 column_index = safe_int(request.GET.get('order[0][column]'))
167 order_dir = request.GET.get('order[0][dir]', 'desc')
75 order_dir = request.GET.get('order[0][dir]', 'desc')
@@ -205,7 +113,7 b' class PullrequestsController(BaseRepoCon'
205 if not request.is_xhr:
113 if not request.is_xhr:
206 c.data = json.dumps(data['data'])
114 c.data = json.dumps(data['data'])
207 c.records_total = data['recordsTotal']
115 c.records_total = data['recordsTotal']
208 return render('/pullrequests/pullrequests.html')
116 return render('/pullrequests/pullrequests.mako')
209 else:
117 else:
210 return json.dumps(data)
118 return json.dumps(data)
211
119
@@ -244,10 +152,10 b' class PullrequestsController(BaseRepoCon'
244 opened_by=opened_by)
152 opened_by=opened_by)
245
153
246 from rhodecode.lib.utils import PartialRenderer
154 from rhodecode.lib.utils import PartialRenderer
247 _render = PartialRenderer('data_table/_dt_elements.html')
155 _render = PartialRenderer('data_table/_dt_elements.mako')
248 data = []
156 data = []
249 for pr in pull_requests:
157 for pr in pull_requests:
250 comments = ChangesetCommentsModel().get_all_comments(
158 comments = CommentsModel().get_all_comments(
251 c.rhodecode_db_repo.repo_id, pull_request=pr)
159 c.rhodecode_db_repo.repo_id, pull_request=pr)
252
160
253 data.append({
161 data.append({
@@ -336,7 +244,7 b' class PullrequestsController(BaseRepoCon'
336 }
244 }
337 c.default_source_ref = selected_source_ref
245 c.default_source_ref = selected_source_ref
338
246
339 return render('/pullrequests/pullrequest.html')
247 return render('/pullrequests/pullrequest.mako')
340
248
341 @LoginRequired()
249 @LoginRequired()
342 @NotAnonymous()
250 @NotAnonymous()
@@ -586,14 +494,20 b' class PullrequestsController(BaseRepoCon'
586
494
587 Merge will perform a server-side merge of the specified
495 Merge will perform a server-side merge of the specified
588 pull request, if the pull request is approved and mergeable.
496 pull request, if the pull request is approved and mergeable.
589 After succesfull merging, the pull request is automatically
497 After successful merging, the pull request is automatically
590 closed, with a relevant comment.
498 closed, with a relevant comment.
591 """
499 """
592 pull_request_id = safe_int(pull_request_id)
500 pull_request_id = safe_int(pull_request_id)
593 pull_request = PullRequest.get_or_404(pull_request_id)
501 pull_request = PullRequest.get_or_404(pull_request_id)
594 user = c.rhodecode_user
502 user = c.rhodecode_user
595
503
596 if self._meets_merge_pre_conditions(pull_request, user):
504 check = MergeCheck.validate(pull_request, user)
505 merge_possible = not check.failed
506
507 for err_type, error_msg in check.errors:
508 h.flash(error_msg, category=err_type)
509
510 if merge_possible:
597 log.debug("Pre-conditions checked, trying to merge.")
511 log.debug("Pre-conditions checked, trying to merge.")
598 extras = vcs_operation_context(
512 extras = vcs_operation_context(
599 request.environ, repo_name=pull_request.target_repo.repo_name,
513 request.environ, repo_name=pull_request.target_repo.repo_name,
@@ -606,24 +520,6 b' class PullrequestsController(BaseRepoCon'
606 repo_name=pull_request.target_repo.repo_name,
520 repo_name=pull_request.target_repo.repo_name,
607 pull_request_id=pull_request.pull_request_id))
521 pull_request_id=pull_request.pull_request_id))
608
522
609 def _meets_merge_pre_conditions(self, pull_request, user):
610 if not PullRequestModel().check_user_merge(pull_request, user):
611 raise HTTPForbidden()
612
613 merge_status, msg = PullRequestModel().merge_status(pull_request)
614 if not merge_status:
615 log.debug("Cannot merge, not mergeable.")
616 h.flash(msg, category='error')
617 return False
618
619 if (pull_request.calculated_review_status()
620 is not ChangesetStatus.STATUS_APPROVED):
621 log.debug("Cannot merge, approval is pending.")
622 msg = _('Pull request reviewer approval is pending.')
623 h.flash(msg, category='error')
624 return False
625 return True
626
627 def _merge_pull_request(self, pull_request, user, extras):
523 def _merge_pull_request(self, pull_request, user, extras):
628 merge_resp = PullRequestModel().merge(
524 merge_resp = PullRequestModel().merge(
629 pull_request, user, extras=extras)
525 pull_request, user, extras=extras)
@@ -675,82 +571,295 b' class PullrequestsController(BaseRepoCon'
675 return redirect(url('my_account_pullrequests'))
571 return redirect(url('my_account_pullrequests'))
676 raise HTTPForbidden()
572 raise HTTPForbidden()
677
573
574 def _get_pr_version(self, pull_request_id, version=None):
575 pull_request_id = safe_int(pull_request_id)
576 at_version = None
577
578 if version and version == 'latest':
579 pull_request_ver = PullRequest.get(pull_request_id)
580 pull_request_obj = pull_request_ver
581 _org_pull_request_obj = pull_request_obj
582 at_version = 'latest'
583 elif version:
584 pull_request_ver = PullRequestVersion.get_or_404(version)
585 pull_request_obj = pull_request_ver
586 _org_pull_request_obj = pull_request_ver.pull_request
587 at_version = pull_request_ver.pull_request_version_id
588 else:
589 _org_pull_request_obj = pull_request_obj = PullRequest.get_or_404(pull_request_id)
590
591 pull_request_display_obj = PullRequest.get_pr_display_object(
592 pull_request_obj, _org_pull_request_obj)
593
594 return _org_pull_request_obj, pull_request_obj, \
595 pull_request_display_obj, at_version
596
597 def _get_diffset(
598 self, source_repo, source_ref_id, target_ref_id, target_commit,
599 source_commit, diff_limit, file_limit, display_inline_comments):
600 vcs_diff = PullRequestModel().get_diff(
601 source_repo, source_ref_id, target_ref_id)
602
603 diff_processor = diffs.DiffProcessor(
604 vcs_diff, format='newdiff', diff_limit=diff_limit,
605 file_limit=file_limit, show_full_diff=c.fulldiff)
606
607 _parsed = diff_processor.prepare()
608
609 def _node_getter(commit):
610 def get_node(fname):
611 try:
612 return commit.get_node(fname)
613 except NodeDoesNotExistError:
614 return None
615
616 return get_node
617
618 diffset = codeblocks.DiffSet(
619 repo_name=c.repo_name,
620 source_repo_name=c.source_repo.repo_name,
621 source_node_getter=_node_getter(target_commit),
622 target_node_getter=_node_getter(source_commit),
623 comments=display_inline_comments
624 )
625 diffset = diffset.render_patchset(
626 _parsed, target_commit.raw_id, source_commit.raw_id)
627
628 return diffset
629
678 @LoginRequired()
630 @LoginRequired()
679 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
631 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
680 'repository.admin')
632 'repository.admin')
681 def show(self, repo_name, pull_request_id):
633 def show(self, repo_name, pull_request_id):
682 pull_request_id = safe_int(pull_request_id)
634 pull_request_id = safe_int(pull_request_id)
683 c.pull_request = PullRequest.get_or_404(pull_request_id)
635 version = request.GET.get('version')
636 from_version = request.GET.get('from_version') or version
637 merge_checks = request.GET.get('merge_checks')
638 c.fulldiff = str2bool(request.GET.get('fulldiff'))
639
640 (pull_request_latest,
641 pull_request_at_ver,
642 pull_request_display_obj,
643 at_version) = self._get_pr_version(
644 pull_request_id, version=version)
645 versions = pull_request_display_obj.versions()
684
646
685 c.template_context['pull_request_data']['pull_request_id'] = \
647 c.at_version = at_version
686 pull_request_id
648 c.at_version_num = (at_version
649 if at_version and at_version != 'latest'
650 else None)
651 c.at_version_pos = ChangesetComment.get_index_from_version(
652 c.at_version_num, versions)
653
654 (prev_pull_request_latest,
655 prev_pull_request_at_ver,
656 prev_pull_request_display_obj,
657 prev_at_version) = self._get_pr_version(
658 pull_request_id, version=from_version)
659
660 c.from_version = prev_at_version
661 c.from_version_num = (prev_at_version
662 if prev_at_version and prev_at_version != 'latest'
663 else None)
664 c.from_version_pos = ChangesetComment.get_index_from_version(
665 c.from_version_num, versions)
666
667 # define if we're in COMPARE mode or VIEW at version mode
668 compare = at_version != prev_at_version
687
669
688 # pull_requests repo_name we opened it against
670 # pull_requests repo_name we opened it against
689 # ie. target_repo must match
671 # ie. target_repo must match
690 if repo_name != c.pull_request.target_repo.repo_name:
672 if repo_name != pull_request_at_ver.target_repo.repo_name:
691 raise HTTPNotFound
673 raise HTTPNotFound
692
674
693 c.allowed_to_change_status = PullRequestModel(). \
694 check_user_change_status(c.pull_request, c.rhodecode_user)
695 c.allowed_to_update = PullRequestModel().check_user_update(
696 c.pull_request, c.rhodecode_user) and not c.pull_request.is_closed()
697 c.allowed_to_merge = PullRequestModel().check_user_merge(
698 c.pull_request, c.rhodecode_user) and not c.pull_request.is_closed()
699 c.shadow_clone_url = PullRequestModel().get_shadow_clone_url(
675 c.shadow_clone_url = PullRequestModel().get_shadow_clone_url(
700 c.pull_request)
676 pull_request_at_ver)
701 c.allowed_to_delete = PullRequestModel().check_user_delete(
677
702 c.pull_request, c.rhodecode_user) and not c.pull_request.is_closed()
678 c.ancestor = None # empty ancestor hidden in display
679 c.pull_request = pull_request_display_obj
680 c.pull_request_latest = pull_request_latest
681
682 pr_closed = pull_request_latest.is_closed()
683 if compare or (at_version and not at_version == 'latest'):
684 c.allowed_to_change_status = False
685 c.allowed_to_update = False
686 c.allowed_to_merge = False
687 c.allowed_to_delete = False
688 c.allowed_to_comment = False
689 else:
690 c.allowed_to_change_status = PullRequestModel(). \
691 check_user_change_status(pull_request_at_ver, c.rhodecode_user)
692 c.allowed_to_update = PullRequestModel().check_user_update(
693 pull_request_latest, c.rhodecode_user) and not pr_closed
694 c.allowed_to_merge = PullRequestModel().check_user_merge(
695 pull_request_latest, c.rhodecode_user) and not pr_closed
696 c.allowed_to_delete = PullRequestModel().check_user_delete(
697 pull_request_latest, c.rhodecode_user) and not pr_closed
698 c.allowed_to_comment = not pr_closed
699
700 # check merge capabilities
701 _merge_check = MergeCheck.validate(
702 pull_request_latest, user=c.rhodecode_user)
703 c.pr_merge_errors = _merge_check.error_details
704 c.pr_merge_possible = not _merge_check.failed
705 c.pr_merge_message = _merge_check.merge_msg
706
707 if merge_checks:
708 return render('/pullrequests/pullrequest_merge_checks.mako')
709
710 comments_model = CommentsModel()
711
712 # reviewers and statuses
713 c.pull_request_reviewers = pull_request_at_ver.reviewers_statuses()
714 allowed_reviewers = [x[0].user_id for x in c.pull_request_reviewers]
715 c.pull_request_review_status = pull_request_at_ver.calculated_review_status()
703
716
704 cc_model = ChangesetCommentsModel()
717 # GENERAL COMMENTS with versions #
718 q = comments_model._all_general_comments_of_pull_request(pull_request_latest)
719 q = q.order_by(ChangesetComment.comment_id.asc())
720 general_comments = q.order_by(ChangesetComment.pull_request_version_id.asc())
721
722 # pick comments we want to render at current version
723 c.comment_versions = comments_model.aggregate_comments(
724 general_comments, versions, c.at_version_num)
725 c.comments = c.comment_versions[c.at_version_num]['until']
705
726
706 c.pull_request_reviewers = c.pull_request.reviewers_statuses()
727 # INLINE COMMENTS with versions #
728 q = comments_model._all_inline_comments_of_pull_request(pull_request_latest)
729 q = q.order_by(ChangesetComment.comment_id.asc())
730 inline_comments = q.order_by(ChangesetComment.pull_request_version_id.asc())
731 c.inline_versions = comments_model.aggregate_comments(
732 inline_comments, versions, c.at_version_num, inline=True)
733
734 # inject latest version
735 latest_ver = PullRequest.get_pr_display_object(
736 pull_request_latest, pull_request_latest)
737
738 c.versions = versions + [latest_ver]
707
739
708 c.pull_request_review_status = c.pull_request.calculated_review_status()
740 # if we use version, then do not show later comments
709 c.pr_merge_status, c.pr_merge_msg = PullRequestModel().merge_status(
741 # than current version
710 c.pull_request)
742 display_inline_comments = collections.defaultdict(
711 c.approval_msg = None
743 lambda: collections.defaultdict(list))
712 if c.pull_request_review_status != ChangesetStatus.STATUS_APPROVED:
744 for co in inline_comments:
713 c.approval_msg = _('Reviewer approval is pending.')
745 if c.at_version_num:
714 c.pr_merge_status = False
746 # pick comments that are at least UPTO given version, so we
715 # load compare data into template context
747 # don't render comments for higher version
716 enable_comments = not c.pull_request.is_closed()
748 should_render = co.pull_request_version_id and \
749 co.pull_request_version_id <= c.at_version_num
750 else:
751 # showing all, for 'latest'
752 should_render = True
753
754 if should_render:
755 display_inline_comments[co.f_path][co.line_no].append(co)
756
757 # load diff data into template context, if we use compare mode then
758 # diff is calculated based on changes between versions of PR
759
760 source_repo = pull_request_at_ver.source_repo
761 source_ref_id = pull_request_at_ver.source_ref_parts.commit_id
762
763 target_repo = pull_request_at_ver.target_repo
764 target_ref_id = pull_request_at_ver.target_ref_parts.commit_id
717
765
766 if compare:
767 # in compare switch the diff base to latest commit from prev version
768 target_ref_id = prev_pull_request_display_obj.revisions[0]
718
769
719 # inline comments
770 # despite opening commits for bookmarks/branches/tags, we always
720 c.inline_comments = cc_model.get_inline_comments(
771 # convert this to rev to prevent changes after bookmark or branch change
721 c.rhodecode_db_repo.repo_id,
772 c.source_ref_type = 'rev'
722 pull_request=pull_request_id)
773 c.source_ref = source_ref_id
774
775 c.target_ref_type = 'rev'
776 c.target_ref = target_ref_id
777
778 c.source_repo = source_repo
779 c.target_repo = target_repo
780
781 # diff_limit is the old behavior, will cut off the whole diff
782 # if the limit is applied otherwise will just hide the
783 # big files from the front-end
784 diff_limit = self.cut_off_limit_diff
785 file_limit = self.cut_off_limit_file
723
786
724 c.inline_cnt = cc_model.get_inline_comments_count(c.inline_comments)
787 c.commit_ranges = []
788 source_commit = EmptyCommit()
789 target_commit = EmptyCommit()
790 c.missing_requirements = False
725
791
726 self._load_compare_data(
792 # try first shadow repo, fallback to regular repo
727 c.pull_request, c.inline_comments, enable_comments=enable_comments)
793 try:
794 commits_source_repo = pull_request_latest.get_shadow_repo()
795 except Exception:
796 log.debug('Failed to get shadow repo', exc_info=True)
797 commits_source_repo = source_repo.scm_instance()
798
799 c.commits_source_repo = commits_source_repo
800 commit_cache = {}
801 try:
802 pre_load = ["author", "branch", "date", "message"]
803 show_revs = pull_request_at_ver.revisions
804 for rev in show_revs:
805 comm = commits_source_repo.get_commit(
806 commit_id=rev, pre_load=pre_load)
807 c.commit_ranges.append(comm)
808 commit_cache[comm.raw_id] = comm
728
809
729 # outdated comments
810 target_commit = commits_source_repo.get_commit(
730 c.outdated_comments = {}
811 commit_id=safe_str(target_ref_id))
731 c.outdated_cnt = 0
812 source_commit = commits_source_repo.get_commit(
732 if ChangesetCommentsModel.use_outdated_comments(c.pull_request):
813 commit_id=safe_str(source_ref_id))
733 c.outdated_comments = cc_model.get_outdated_comments(
814 except CommitDoesNotExistError:
734 c.rhodecode_db_repo.repo_id,
815 pass
735 pull_request=c.pull_request)
816 except RepositoryRequirementError:
736 # Count outdated comments and check for deleted files
817 log.warning(
737 for file_name, lines in c.outdated_comments.iteritems():
818 'Failed to get all required data from repo', exc_info=True)
738 for comments in lines.values():
819 c.missing_requirements = True
739 c.outdated_cnt += len(comments)
820
740 if file_name not in c.included_files:
821 c.statuses = source_repo.statuses(
741 c.deleted_files.append(file_name)
822 [x.raw_id for x in c.commit_ranges])
823
824 # auto collapse if we have more than limit
825 collapse_limit = diffs.DiffProcessor._collapse_commits_over
826 c.collapse_all_commits = len(c.commit_ranges) > collapse_limit
827 c.compare_mode = compare
828
829 c.missing_commits = False
830 if (c.missing_requirements or isinstance(source_commit, EmptyCommit)
831 or source_commit == target_commit):
742
832
833 c.missing_commits = True
834 else:
835
836 c.diffset = self._get_diffset(
837 commits_source_repo, source_ref_id, target_ref_id,
838 target_commit, source_commit,
839 diff_limit, file_limit, display_inline_comments)
840
841 c.limited_diff = c.diffset.limited_diff
842
843 # calculate removed files that are bound to comments
844 comment_deleted_files = [
845 fname for fname in display_inline_comments
846 if fname not in c.diffset.file_stats]
847
848 c.deleted_files_comments = collections.defaultdict(dict)
849 for fname, per_line_comments in display_inline_comments.items():
850 if fname in comment_deleted_files:
851 c.deleted_files_comments[fname]['stats'] = 0
852 c.deleted_files_comments[fname]['comments'] = list()
853 for lno, comments in per_line_comments.items():
854 c.deleted_files_comments[fname]['comments'].extend(
855 comments)
743
856
744 # this is a hack to properly display links, when creating PR, the
857 # this is a hack to properly display links, when creating PR, the
745 # compare view and others uses different notation, and
858 # compare view and others uses different notation, and
746 # compare_commits.html renders links based on the target_repo.
859 # compare_commits.mako renders links based on the target_repo.
747 # We need to swap that here to generate it properly on the html side
860 # We need to swap that here to generate it properly on the html side
748 c.target_repo = c.source_repo
861 c.target_repo = c.source_repo
749
862
750 # comments
751 c.comments = cc_model.get_comments(c.rhodecode_db_repo.repo_id,
752 pull_request=pull_request_id)
753
754 if c.allowed_to_update:
863 if c.allowed_to_update:
755 force_close = ('forced_closed', _('Close Pull Request'))
864 force_close = ('forced_closed', _('Close Pull Request'))
756 statuses = ChangesetStatus.STATUSES + [force_close]
865 statuses = ChangesetStatus.STATUSES + [force_close]
@@ -758,14 +867,55 b' class PullrequestsController(BaseRepoCon'
758 statuses = ChangesetStatus.STATUSES
867 statuses = ChangesetStatus.STATUSES
759 c.commit_statuses = statuses
868 c.commit_statuses = statuses
760
869
761 c.ancestor = None # TODO: add ancestor here
870 c.show_version_changes = not pr_closed
871 if c.show_version_changes:
872 cur_obj = pull_request_at_ver
873 prev_obj = prev_pull_request_at_ver
874
875 old_commit_ids = prev_obj.revisions
876 new_commit_ids = cur_obj.revisions
877 commit_changes = PullRequestModel()._calculate_commit_id_changes(
878 old_commit_ids, new_commit_ids)
879 c.commit_changes_summary = commit_changes
880
881 # calculate the diff for commits between versions
882 c.commit_changes = []
883 mark = lambda cs, fw: list(
884 h.itertools.izip_longest([], cs, fillvalue=fw))
885 for c_type, raw_id in mark(commit_changes.added, 'a') \
886 + mark(commit_changes.removed, 'r') \
887 + mark(commit_changes.common, 'c'):
762
888
763 return render('/pullrequests/pullrequest_show.html')
889 if raw_id in commit_cache:
890 commit = commit_cache[raw_id]
891 else:
892 try:
893 commit = commits_source_repo.get_commit(raw_id)
894 except CommitDoesNotExistError:
895 # in case we fail extracting still use "dummy" commit
896 # for display in commit diff
897 commit = h.AttributeDict(
898 {'raw_id': raw_id,
899 'message': 'EMPTY or MISSING COMMIT'})
900 c.commit_changes.append([c_type, commit])
901
902 # current user review statuses for each version
903 c.review_versions = {}
904 if c.rhodecode_user.user_id in allowed_reviewers:
905 for co in general_comments:
906 if co.author.user_id == c.rhodecode_user.user_id:
907 # each comment has a status change
908 status = co.status_change
909 if status:
910 _ver_pr = status[0].comment.pull_request_version_id
911 c.review_versions[_ver_pr] = status[0]
912
913 return render('/pullrequests/pullrequest_show.mako')
764
914
765 @LoginRequired()
915 @LoginRequired()
766 @NotAnonymous()
916 @NotAnonymous()
767 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
917 @HasRepoPermissionAnyDecorator(
768 'repository.admin')
918 'repository.read', 'repository.write', 'repository.admin')
769 @auth.CSRFRequired()
919 @auth.CSRFRequired()
770 @jsonify
920 @jsonify
771 def comment(self, repo_name, pull_request_id):
921 def comment(self, repo_name, pull_request_id):
@@ -778,6 +928,9 b' class PullrequestsController(BaseRepoCon'
778 # as a changeset status, still we want to send it in one value.
928 # as a changeset status, still we want to send it in one value.
779 status = request.POST.get('changeset_status', None)
929 status = request.POST.get('changeset_status', None)
780 text = request.POST.get('text')
930 text = request.POST.get('text')
931 comment_type = request.POST.get('comment_type')
932 resolves_comment_id = request.POST.get('resolves_comment_id', None)
933
781 if status and '_closed' in status:
934 if status and '_closed' in status:
782 close_pr = True
935 close_pr = True
783 status = status.replace('_closed', '')
936 status = status.replace('_closed', '')
@@ -798,7 +951,7 b' class PullrequestsController(BaseRepoCon'
798 if close_pr:
951 if close_pr:
799 message = _('Closing with') + ' ' + message
952 message = _('Closing with') + ' ' + message
800 text = text or message
953 text = text or message
801 comm = ChangesetCommentsModel().create(
954 comm = CommentsModel().create(
802 text=text,
955 text=text,
803 repo=c.rhodecode_db_repo.repo_id,
956 repo=c.rhodecode_db_repo.repo_id,
804 user=c.rhodecode_user.user_id,
957 user=c.rhodecode_user.user_id,
@@ -809,11 +962,11 b' class PullrequestsController(BaseRepoCon'
809 if status and allowed_to_change_status else None),
962 if status and allowed_to_change_status else None),
810 status_change_type=(status
963 status_change_type=(status
811 if status and allowed_to_change_status else None),
964 if status and allowed_to_change_status else None),
812 closing_pr=close_pr
965 closing_pr=close_pr,
966 comment_type=comment_type,
967 resolves_comment_id=resolves_comment_id
813 )
968 )
814
969
815
816
817 if allowed_to_change_status:
970 if allowed_to_change_status:
818 old_calculated_status = pull_request.calculated_review_status()
971 old_calculated_status = pull_request.calculated_review_status()
819 # get status if set !
972 # get status if set !
@@ -863,9 +1016,10 b' class PullrequestsController(BaseRepoCon'
863 }
1016 }
864 if comm:
1017 if comm:
865 c.co = comm
1018 c.co = comm
1019 c.inline_comment = True if comm.line_no else False
866 data.update(comm.get_dict())
1020 data.update(comm.get_dict())
867 data.update({'rendered_text':
1021 data.update({'rendered_text':
868 render('changeset/changeset_comment_block.html')})
1022 render('changeset/changeset_comment_block.mako')})
869
1023
870 return data
1024 return data
871
1025
@@ -889,7 +1043,7 b' class PullrequestsController(BaseRepoCon'
889 is_repo_admin = h.HasRepoPermissionAny('repository.admin')(c.repo_name)
1043 is_repo_admin = h.HasRepoPermissionAny('repository.admin')(c.repo_name)
890 if h.HasPermissionAny('hg.admin')() or is_repo_admin or is_owner:
1044 if h.HasPermissionAny('hg.admin')() or is_repo_admin or is_owner:
891 old_calculated_status = co.pull_request.calculated_review_status()
1045 old_calculated_status = co.pull_request.calculated_review_status()
892 ChangesetCommentsModel().delete(comment=co)
1046 CommentsModel().delete(comment=co)
893 Session().commit()
1047 Session().commit()
894 calculated_status = co.pull_request.calculated_review_status()
1048 calculated_status = co.pull_request.calculated_review_status()
895 if old_calculated_status != calculated_status:
1049 if old_calculated_status != calculated_status:
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -108,4 +108,4 b' class SearchController(BaseRepoControlle'
108 c.cur_query = search_query
108 c.cur_query = search_query
109 c.search_type = search_type
109 c.search_type = search_type
110 # Return a rendered template
110 # Return a rendered template
111 return render('/search/search.html')
111 return render('/search/search.mako')
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -165,7 +165,7 b' class SummaryController(BaseRepoControll'
165 c.repo_name, c.rhodecode_user.user_id)
165 c.repo_name, c.rhodecode_user.user_id)
166
166
167 if c.repository_requirements_missing:
167 if c.repository_requirements_missing:
168 return render('summary/missing_requirements.html')
168 return render('summary/missing_requirements.mako')
169
169
170 c.readme_data, c.readme_file = \
170 c.readme_data, c.readme_file = \
171 self.__get_readme_data(c.rhodecode_db_repo)
171 self.__get_readme_data(c.rhodecode_db_repo)
@@ -173,9 +173,9 b' class SummaryController(BaseRepoControll'
173 _load_changelog_summary()
173 _load_changelog_summary()
174
174
175 if request.is_xhr:
175 if request.is_xhr:
176 return render('changelog/changelog_summary_data.html')
176 return render('changelog/changelog_summary_data.mako')
177
177
178 return render('summary/summary.html')
178 return render('summary/summary.mako')
179
179
180 @LoginRequired()
180 @LoginRequired()
181 @XHRRequired()
181 @XHRRequired()
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -31,8 +31,8 b' log = logging.getLogger(__name__)'
31
31
32 class TagsController(BaseReferencesController):
32 class TagsController(BaseReferencesController):
33
33
34 partials_template = 'tags/tags_data.html'
34 partials_template = 'tags/tags_data.mako'
35 template = 'tags/tags.html'
35 template = 'tags/tags.mako'
36
36
37 def _get_reference_items(self, repo):
37 def _get_reference_items(self, repo):
38 return repo.tags.items()
38 return repo.tags.items()
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -40,4 +40,4 b' class UsersController(BaseController):'
40 raise HTTPNotFound()
40 raise HTTPNotFound()
41
41
42 c.active = 'user_profile'
42 c.active = 'user_profile'
43 return render('users/user.html')
43 return render('users/user.mako')
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -27,6 +27,7 b' Should only contain utilities to be shar'
27 from rhodecode.lib import helpers as h
27 from rhodecode.lib import helpers as h
28 from rhodecode.lib.vcs.exceptions import RepositoryError
28 from rhodecode.lib.vcs.exceptions import RepositoryError
29
29
30
30 def parse_path_ref(ref, default_path=None):
31 def parse_path_ref(ref, default_path=None):
31 """
32 """
32 Parse out a path and reference combination and return both parts of it.
33 Parse out a path and reference combination and return both parts of it.
@@ -76,8 +77,8 b' def get_commit_from_ref_name(repo, ref_n'
76 }
77 }
77
78
78 commit_id = ref_name
79 commit_id = ref_name
79 if repo_scm.alias != 'svn': # pass svn refs straight to backend until
80 if repo_scm.alias != 'svn': # pass svn refs straight to backend until
80 # the branch issue with svn is fixed
81 # the branch issue with svn is fixed
81 if ref_type and ref_type in ref_type_mapping:
82 if ref_type and ref_type in ref_type_mapping:
82 try:
83 try:
83 commit_id = ref_type_mapping[ref_type][ref_name]
84 commit_id = ref_type_mapping[ref_type][ref_name]
@@ -1,4 +1,4 b''
1 # Copyright (C) 2016-2016 RhodeCode GmbH
1 # Copyright (C) 2016-2017 RhodeCode GmbH
2 #
2 #
3 # This program is free software: you can redistribute it and/or modify
3 # This program is free software: you can redistribute it and/or modify
4 # it under the terms of the GNU Affero General Public License, version 3
4 # it under the terms of the GNU Affero General Public License, version 3
@@ -1,4 +1,4 b''
1 # Copyright (C) 2016-2016 RhodeCode GmbH
1 # Copyright (C) 2016-2017 RhodeCode GmbH
2 #
2 #
3 # This program is free software: you can redistribute it and/or modify
3 # This program is free software: you can redistribute it and/or modify
4 # it under the terms of the GNU Affero General Public License, version 3
4 # it under the terms of the GNU Affero General Public License, version 3
@@ -1,4 +1,4 b''
1 # Copyright (C) 2016-2016 RhodeCode GmbH
1 # Copyright (C) 2016-2017 RhodeCode GmbH
2 #
2 #
3 # This program is free software: you can redistribute it and/or modify
3 # This program is free software: you can redistribute it and/or modify
4 # it under the terms of the GNU Affero General Public License, version 3
4 # it under the terms of the GNU Affero General Public License, version 3
@@ -1,4 +1,4 b''
1 # Copyright (C) 2016-2016 RhodeCode GmbH
1 # Copyright (C) 2016-2017 RhodeCode GmbH
2 #
2 #
3 # This program is free software: you can redistribute it and/or modify
3 # This program is free software: you can redistribute it and/or modify
4 # it under the terms of the GNU Affero General Public License, version 3
4 # it under the terms of the GNU Affero General Public License, version 3
@@ -114,7 +114,7 b' class PullRequestCommentEvent(PullReques'
114 self.comment = comment
114 self.comment = comment
115
115
116 def as_dict(self):
116 def as_dict(self):
117 from rhodecode.model.comment import ChangesetCommentsModel
117 from rhodecode.model.comment import CommentsModel
118 data = super(PullRequestCommentEvent, self).as_dict()
118 data = super(PullRequestCommentEvent, self).as_dict()
119
119
120 status = None
120 status = None
@@ -125,7 +125,7 b' class PullRequestCommentEvent(PullReques'
125 'comment': {
125 'comment': {
126 'status': status,
126 'status': status,
127 'text': self.comment.text,
127 'text': self.comment.text,
128 'url': ChangesetCommentsModel().get_url(self.comment)
128 'url': CommentsModel().get_url(self.comment)
129 }
129 }
130 })
130 })
131 return data
131 return data
@@ -1,4 +1,4 b''
1 # Copyright (C) 2016-2016 RhodeCode GmbH
1 # Copyright (C) 2016-2017 RhodeCode GmbH
2 #
2 #
3 # This program is free software: you can redistribute it and/or modify
3 # This program is free software: you can redistribute it and/or modify
4 # it under the terms of the GNU Affero General Public License, version 3
4 # it under the terms of the GNU Affero General Public License, version 3
@@ -1,4 +1,4 b''
1 # Copyright (C) 2016-2016 RhodeCode GmbH
1 # Copyright (C) 2016-2017 RhodeCode GmbH
2 #
2 #
3 # This program is free software: you can redistribute it and/or modify
3 # This program is free software: you can redistribute it and/or modify
4 # it under the terms of the GNU Affero General Public License, version 3
4 # it under the terms of the GNU Affero General Public License, version 3
@@ -1,4 +1,4 b''
1 # Copyright (C) 2016-2016 RhodeCode GmbH
1 # Copyright (C) 2016-2017 RhodeCode GmbH
2 #
2 #
3 # This program is free software: you can redistribute it and/or modify
3 # This program is free software: you can redistribute it and/or modify
4 # it under the terms of the GNU Affero General Public License, version 3
4 # it under the terms of the GNU Affero General Public License, version 3
@@ -1,6 +1,6 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2010-2016 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
@@ -1,5 +1,5 b''
1 # Translations template for rhodecode-enterprise-ce.
1 # Translations template for rhodecode-enterprise-ce.
2 # Copyright (C) 2016 RhodeCode GmbH
2 # Copyright (C) 2017 RhodeCode GmbH
3 # This file is distributed under the same license as the rhodecode-enterprise-ce project.
3 # This file is distributed under the same license as the rhodecode-enterprise-ce project.
4 #
4 #
5 # Translators:
5 # Translators:
@@ -1,5 +1,5 b''
1 # Translations template for rhodecode-enterprise-ce.
1 # Translations template for rhodecode-enterprise-ce.
2 # Copyright (C) 2016 RhodeCode GmbH
2 # Copyright (C) 2017 RhodeCode GmbH
3 # This file is distributed under the same license as the rhodecode-enterprise-ce project.
3 # This file is distributed under the same license as the rhodecode-enterprise-ce project.
4 #
4 #
5 # Translators:
5 # Translators:
@@ -1,5 +1,5 b''
1 # Translations template for rhodecode-enterprise-ce.
1 # Translations template for rhodecode-enterprise-ce.
2 # Copyright (C) 2016 RhodeCode GmbH
2 # Copyright (C) 2017 RhodeCode GmbH
3 # This file is distributed under the same license as the rhodecode-enterprise-ce project.
3 # This file is distributed under the same license as the rhodecode-enterprise-ce project.
4 #
4 #
5 # Translators:
5 # Translators:
@@ -1,5 +1,5 b''
1 # Translations template for rhodecode-enterprise-ce.
1 # Translations template for rhodecode-enterprise-ce.
2 # Copyright (C) 2016 RhodeCode GmbH
2 # Copyright (C) 2017 RhodeCode GmbH
3 # This file is distributed under the same license as the rhodecode-enterprise-ce project.
3 # This file is distributed under the same license as the rhodecode-enterprise-ce project.
4 #
4 #
5 # Translators:
5 # Translators:
@@ -1,5 +1,5 b''
1 # Translations template for rhodecode-enterprise-ce.
1 # Translations template for rhodecode-enterprise-ce.
2 # Copyright (C) 2016 RhodeCode GmbH
2 # Copyright (C) 2017 RhodeCode GmbH
3 # This file is distributed under the same license as the rhodecode-enterprise-ce project.
3 # This file is distributed under the same license as the rhodecode-enterprise-ce project.
4 #
4 #
5 # Translators:
5 # Translators:
@@ -1,9 +1,9 b''
1 # Translations template for rhodecode-enterprise-ce.
1 # Translations template for rhodecode-enterprise-ce.
2 # Copyright (C) 2016 RhodeCode GmbH
2 # Copyright (C) 2017 RhodeCode GmbH
3 # This file is distributed under the same license as the rhodecode-enterprise-ce project.
3 # This file is distributed under the same license as the rhodecode-enterprise-ce project.
4 #
4 #
5 # Translators:
5 # Translators:
6 # Alessandro sauzher Ceglie, 2014-2016
6 # Alessandro sauzher Ceglie, 2014-2017
7 # FIRST AUTHOR <EMAIL@ADDRESS>, 2014
7 # FIRST AUTHOR <EMAIL@ADDRESS>, 2014
8 msgid ""
8 msgid ""
9 msgstr ""
9 msgstr ""
@@ -1,5 +1,5 b''
1 # Translations template for rhodecode-enterprise-ce.
1 # Translations template for rhodecode-enterprise-ce.
2 # Copyright (C) 2016 RhodeCode GmbH
2 # Copyright (C) 2017 RhodeCode GmbH
3 # This file is distributed under the same license as the rhodecode-enterprise-ce project.
3 # This file is distributed under the same license as the rhodecode-enterprise-ce project.
4 #
4 #
5 # Translators:
5 # Translators:
@@ -1,5 +1,5 b''
1 # Translations template for rhodecode-enterprise-ce.
1 # Translations template for rhodecode-enterprise-ce.
2 # Copyright (C) 2016 RhodeCode GmbH
2 # Copyright (C) 2017 RhodeCode GmbH
3 # This file is distributed under the same license as the rhodecode-enterprise-ce project.
3 # This file is distributed under the same license as the rhodecode-enterprise-ce project.
4 #
4 #
5 # Translators:
5 # Translators:
@@ -1,5 +1,5 b''
1 # Translations template for rhodecode-enterprise-ce.
1 # Translations template for rhodecode-enterprise-ce.
2 # Copyright (C) 2016 RhodeCode GmbH
2 # Copyright (C) 2017 RhodeCode GmbH
3 # This file is distributed under the same license as the rhodecode-enterprise-ce project.
3 # This file is distributed under the same license as the rhodecode-enterprise-ce project.
4 #
4 #
5 # Translators:
5 # Translators:
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/admin.html to rhodecode/templates/admin/admin.mako
NO CONTENT: file renamed from rhodecode/templates/admin/admin.html to rhodecode/templates/admin/admin.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/admin_log.html to rhodecode/templates/admin/admin_log.mako
NO CONTENT: file renamed from rhodecode/templates/admin/admin_log.html to rhodecode/templates/admin/admin_log.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/auth/auth_settings.html to rhodecode/templates/admin/auth/auth_settings.mako
NO CONTENT: file renamed from rhodecode/templates/admin/auth/auth_settings.html to rhodecode/templates/admin/auth/auth_settings.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/auth/plugin_settings.html to rhodecode/templates/admin/auth/plugin_settings.mako
NO CONTENT: file renamed from rhodecode/templates/admin/auth/plugin_settings.html to rhodecode/templates/admin/auth/plugin_settings.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/defaults/defaults.html to rhodecode/templates/admin/defaults/defaults.mako
NO CONTENT: file renamed from rhodecode/templates/admin/defaults/defaults.html to rhodecode/templates/admin/defaults/defaults.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/defaults/defaults_repositories.html to rhodecode/templates/admin/defaults/defaults_repositories.mako
NO CONTENT: file renamed from rhodecode/templates/admin/defaults/defaults_repositories.html to rhodecode/templates/admin/defaults/defaults_repositories.mako
1 NO CONTENT: file renamed from rhodecode/templates/admin/gists/edit.html to rhodecode/templates/admin/gists/edit.mako
NO CONTENT: file renamed from rhodecode/templates/admin/gists/edit.html to rhodecode/templates/admin/gists/edit.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/gists/index.html to rhodecode/templates/admin/gists/index.mako
NO CONTENT: file renamed from rhodecode/templates/admin/gists/index.html to rhodecode/templates/admin/gists/index.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/gists/new.html to rhodecode/templates/admin/gists/new.mako
NO CONTENT: file renamed from rhodecode/templates/admin/gists/new.html to rhodecode/templates/admin/gists/new.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/gists/show.html to rhodecode/templates/admin/gists/show.mako
NO CONTENT: file renamed from rhodecode/templates/admin/gists/show.html to rhodecode/templates/admin/gists/show.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/integrations/base.html to rhodecode/templates/admin/integrations/base.mako
NO CONTENT: file renamed from rhodecode/templates/admin/integrations/base.html to rhodecode/templates/admin/integrations/base.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/integrations/form.html to rhodecode/templates/admin/integrations/form.mako
NO CONTENT: file renamed from rhodecode/templates/admin/integrations/form.html to rhodecode/templates/admin/integrations/form.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/integrations/list.html to rhodecode/templates/admin/integrations/list.mako
NO CONTENT: file renamed from rhodecode/templates/admin/integrations/list.html to rhodecode/templates/admin/integrations/list.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/integrations/new.html to rhodecode/templates/admin/integrations/new.mako
NO CONTENT: file renamed from rhodecode/templates/admin/integrations/new.html to rhodecode/templates/admin/integrations/new.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account.html to rhodecode/templates/admin/my_account/my_account.mako
NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account.html to rhodecode/templates/admin/my_account/my_account.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account_auth_tokens.html to rhodecode/templates/admin/my_account/my_account_auth_tokens.mako
NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account_auth_tokens.html to rhodecode/templates/admin/my_account/my_account_auth_tokens.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account_emails.html to rhodecode/templates/admin/my_account/my_account_emails.mako
NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account_emails.html to rhodecode/templates/admin/my_account/my_account_emails.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account_notifications.html to rhodecode/templates/admin/my_account/my_account_notifications.mako
NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account_notifications.html to rhodecode/templates/admin/my_account/my_account_notifications.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account_password.html to rhodecode/templates/admin/my_account/my_account_password.mako
NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account_password.html to rhodecode/templates/admin/my_account/my_account_password.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account_perms.html to rhodecode/templates/admin/my_account/my_account_perms.mako
NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account_perms.html to rhodecode/templates/admin/my_account/my_account_perms.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account_profile.html to rhodecode/templates/admin/my_account/my_account_profile.mako
NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account_profile.html to rhodecode/templates/admin/my_account/my_account_profile.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account_profile_edit.html to rhodecode/templates/admin/my_account/my_account_profile_edit.mako
NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account_profile_edit.html to rhodecode/templates/admin/my_account/my_account_profile_edit.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account_pullrequests.html to rhodecode/templates/admin/my_account/my_account_pullrequests.mako
NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account_pullrequests.html to rhodecode/templates/admin/my_account/my_account_pullrequests.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account_repos.html to rhodecode/templates/admin/my_account/my_account_repos.mako
NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account_repos.html to rhodecode/templates/admin/my_account/my_account_repos.mako
1 NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account_watched.html to rhodecode/templates/admin/my_account/my_account_watched.mako
NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account_watched.html to rhodecode/templates/admin/my_account/my_account_watched.mako
1 NO CONTENT: file renamed from rhodecode/templates/admin/notifications/notifications.html to rhodecode/templates/admin/notifications/notifications.mako
NO CONTENT: file renamed from rhodecode/templates/admin/notifications/notifications.html to rhodecode/templates/admin/notifications/notifications.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/notifications/notifications_data.html to rhodecode/templates/admin/notifications/notifications_data.mako
NO CONTENT: file renamed from rhodecode/templates/admin/notifications/notifications_data.html to rhodecode/templates/admin/notifications/notifications_data.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/notifications/show_notification.html to rhodecode/templates/admin/notifications/show_notification.mako
NO CONTENT: file renamed from rhodecode/templates/admin/notifications/show_notification.html to rhodecode/templates/admin/notifications/show_notification.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/permissions/permissions.html to rhodecode/templates/admin/permissions/permissions.mako
NO CONTENT: file renamed from rhodecode/templates/admin/permissions/permissions.html to rhodecode/templates/admin/permissions/permissions.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/permissions/permissions_application.html to rhodecode/templates/admin/permissions/permissions_application.mako
NO CONTENT: file renamed from rhodecode/templates/admin/permissions/permissions_application.html to rhodecode/templates/admin/permissions/permissions_application.mako
1 NO CONTENT: file renamed from rhodecode/templates/admin/permissions/permissions_global.html to rhodecode/templates/admin/permissions/permissions_global.mako
NO CONTENT: file renamed from rhodecode/templates/admin/permissions/permissions_global.html to rhodecode/templates/admin/permissions/permissions_global.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/permissions/permissions_ips.html to rhodecode/templates/admin/permissions/permissions_ips.mako
NO CONTENT: file renamed from rhodecode/templates/admin/permissions/permissions_ips.html to rhodecode/templates/admin/permissions/permissions_ips.mako
1 NO CONTENT: file renamed from rhodecode/templates/admin/permissions/permissions_objects.html to rhodecode/templates/admin/permissions/permissions_objects.mako
NO CONTENT: file renamed from rhodecode/templates/admin/permissions/permissions_objects.html to rhodecode/templates/admin/permissions/permissions_objects.mako
1 NO CONTENT: file renamed from rhodecode/templates/admin/permissions/permissions_perms.html to rhodecode/templates/admin/permissions/permissions_perms.mako
NO CONTENT: file renamed from rhodecode/templates/admin/permissions/permissions_perms.html to rhodecode/templates/admin/permissions/permissions_perms.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/repo_groups/repo_group_add.html to rhodecode/templates/admin/repo_groups/repo_group_add.mako
NO CONTENT: file renamed from rhodecode/templates/admin/repo_groups/repo_group_add.html to rhodecode/templates/admin/repo_groups/repo_group_add.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/repo_groups/repo_group_edit.html to rhodecode/templates/admin/repo_groups/repo_group_edit.mako
NO CONTENT: file renamed from rhodecode/templates/admin/repo_groups/repo_group_edit.html to rhodecode/templates/admin/repo_groups/repo_group_edit.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/repo_groups/repo_group_edit_advanced.html to rhodecode/templates/admin/repo_groups/repo_group_edit_advanced.mako
NO CONTENT: file renamed from rhodecode/templates/admin/repo_groups/repo_group_edit_advanced.html to rhodecode/templates/admin/repo_groups/repo_group_edit_advanced.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/repo_groups/repo_group_edit_perms.html to rhodecode/templates/admin/repo_groups/repo_group_edit_perms.mako
NO CONTENT: file renamed from rhodecode/templates/admin/repo_groups/repo_group_edit_perms.html to rhodecode/templates/admin/repo_groups/repo_group_edit_perms.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/repo_groups/repo_group_edit_settings.html to rhodecode/templates/admin/repo_groups/repo_group_edit_settings.mako
NO CONTENT: file renamed from rhodecode/templates/admin/repo_groups/repo_group_edit_settings.html to rhodecode/templates/admin/repo_groups/repo_group_edit_settings.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/repo_groups/repo_groups.html to rhodecode/templates/admin/repo_groups/repo_groups.mako
NO CONTENT: file renamed from rhodecode/templates/admin/repo_groups/repo_groups.html to rhodecode/templates/admin/repo_groups/repo_groups.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_add.html to rhodecode/templates/admin/repos/repo_add.mako
NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_add.html to rhodecode/templates/admin/repos/repo_add.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_add_base.html to rhodecode/templates/admin/repos/repo_add_base.mako
NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_add_base.html to rhodecode/templates/admin/repos/repo_add_base.mako
1 NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_creating.html to rhodecode/templates/admin/repos/repo_creating.mako
NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_creating.html to rhodecode/templates/admin/repos/repo_creating.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit.html to rhodecode/templates/admin/repos/repo_edit.mako
NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit.html to rhodecode/templates/admin/repos/repo_edit.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit_advanced.html to rhodecode/templates/admin/repos/repo_edit_advanced.mako
NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit_advanced.html to rhodecode/templates/admin/repos/repo_edit_advanced.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit_caches.html to rhodecode/templates/admin/repos/repo_edit_caches.mako
NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit_caches.html to rhodecode/templates/admin/repos/repo_edit_caches.mako
1 NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit_fields.html to rhodecode/templates/admin/repos/repo_edit_fields.mako
NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit_fields.html to rhodecode/templates/admin/repos/repo_edit_fields.mako
1 NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit_fork.html to rhodecode/templates/admin/repos/repo_edit_fork.mako
NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit_fork.html to rhodecode/templates/admin/repos/repo_edit_fork.mako
1 NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit_issuetracker.html to rhodecode/templates/admin/repos/repo_edit_issuetracker.mako
NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit_issuetracker.html to rhodecode/templates/admin/repos/repo_edit_issuetracker.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit_permissions.html to rhodecode/templates/admin/repos/repo_edit_permissions.mako
NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit_permissions.html to rhodecode/templates/admin/repos/repo_edit_permissions.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit_remote.html to rhodecode/templates/admin/repos/repo_edit_remote.mako
NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit_remote.html to rhodecode/templates/admin/repos/repo_edit_remote.mako
1 NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit_settings.html to rhodecode/templates/admin/repos/repo_edit_settings.mako
NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit_settings.html to rhodecode/templates/admin/repos/repo_edit_settings.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit_statistics.html to rhodecode/templates/admin/repos/repo_edit_statistics.mako
NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit_statistics.html to rhodecode/templates/admin/repos/repo_edit_statistics.mako
1 NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit_vcs.html to rhodecode/templates/admin/repos/repo_edit_vcs.mako
NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit_vcs.html to rhodecode/templates/admin/repos/repo_edit_vcs.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/repos/repos.html to rhodecode/templates/admin/repos/repos.mako
NO CONTENT: file renamed from rhodecode/templates/admin/repos/repos.html to rhodecode/templates/admin/repos/repos.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings.html to rhodecode/templates/admin/settings/settings.mako
NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings.html to rhodecode/templates/admin/settings/settings.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_email.html to rhodecode/templates/admin/settings/settings_email.mako
NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_email.html to rhodecode/templates/admin/settings/settings_email.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_global.html to rhodecode/templates/admin/settings/settings_global.mako
NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_global.html to rhodecode/templates/admin/settings/settings_global.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_hooks.html to rhodecode/templates/admin/settings/settings_hooks.mako
NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_hooks.html to rhodecode/templates/admin/settings/settings_hooks.mako
1 NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_issuetracker.html to rhodecode/templates/admin/settings/settings_issuetracker.mako
NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_issuetracker.html to rhodecode/templates/admin/settings/settings_issuetracker.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_labs.html to rhodecode/templates/admin/settings/settings_labs.mako
NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_labs.html to rhodecode/templates/admin/settings/settings_labs.mako
1 NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_mapping.html to rhodecode/templates/admin/settings/settings_mapping.mako
NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_mapping.html to rhodecode/templates/admin/settings/settings_mapping.mako
1 NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_open_source.html to rhodecode/templates/admin/settings/settings_open_source.mako
NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_open_source.html to rhodecode/templates/admin/settings/settings_open_source.mako
1 NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_search.html to rhodecode/templates/admin/settings/settings_search.mako
NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_search.html to rhodecode/templates/admin/settings/settings_search.mako
1 NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_supervisor.html to rhodecode/templates/admin/settings/settings_supervisor.mako
NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_supervisor.html to rhodecode/templates/admin/settings/settings_supervisor.mako
1 NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_supervisor_tail.html to rhodecode/templates/admin/settings/settings_supervisor_tail.mako
NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_supervisor_tail.html to rhodecode/templates/admin/settings/settings_supervisor_tail.mako
1 NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_system.html to rhodecode/templates/admin/settings/settings_system.mako
NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_system.html to rhodecode/templates/admin/settings/settings_system.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_system_snapshot.html to rhodecode/templates/admin/settings/settings_system_snapshot.mako
NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_system_snapshot.html to rhodecode/templates/admin/settings/settings_system_snapshot.mako
1 NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_system_update.html to rhodecode/templates/admin/settings/settings_system_update.mako
NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_system_update.html to rhodecode/templates/admin/settings/settings_system_update.mako
1 NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_vcs.html to rhodecode/templates/admin/settings/settings_vcs.mako
NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_vcs.html to rhodecode/templates/admin/settings/settings_vcs.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_visual.html to rhodecode/templates/admin/settings/settings_visual.mako
NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_visual.html to rhodecode/templates/admin/settings/settings_visual.mako
1 NO CONTENT: file renamed from rhodecode/templates/admin/user_groups/user_group_add.html to rhodecode/templates/admin/user_groups/user_group_add.mako
NO CONTENT: file renamed from rhodecode/templates/admin/user_groups/user_group_add.html to rhodecode/templates/admin/user_groups/user_group_add.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/user_groups/user_group_edit.html to rhodecode/templates/admin/user_groups/user_group_edit.mako
NO CONTENT: file renamed from rhodecode/templates/admin/user_groups/user_group_edit.html to rhodecode/templates/admin/user_groups/user_group_edit.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/user_groups/user_group_edit_advanced.html to rhodecode/templates/admin/user_groups/user_group_edit_advanced.mako
NO CONTENT: file renamed from rhodecode/templates/admin/user_groups/user_group_edit_advanced.html to rhodecode/templates/admin/user_groups/user_group_edit_advanced.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/user_groups/user_group_edit_global_perms.html to rhodecode/templates/admin/user_groups/user_group_edit_global_perms.mako
NO CONTENT: file renamed from rhodecode/templates/admin/user_groups/user_group_edit_global_perms.html to rhodecode/templates/admin/user_groups/user_group_edit_global_perms.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/user_groups/user_group_edit_perms.html to rhodecode/templates/admin/user_groups/user_group_edit_perms.mako
NO CONTENT: file renamed from rhodecode/templates/admin/user_groups/user_group_edit_perms.html to rhodecode/templates/admin/user_groups/user_group_edit_perms.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/user_groups/user_group_edit_perms_summary.html to rhodecode/templates/admin/user_groups/user_group_edit_perms_summary.mako
NO CONTENT: file renamed from rhodecode/templates/admin/user_groups/user_group_edit_perms_summary.html to rhodecode/templates/admin/user_groups/user_group_edit_perms_summary.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/user_groups/user_group_edit_settings.html to rhodecode/templates/admin/user_groups/user_group_edit_settings.mako
NO CONTENT: file renamed from rhodecode/templates/admin/user_groups/user_group_edit_settings.html to rhodecode/templates/admin/user_groups/user_group_edit_settings.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/user_groups/user_groups.html to rhodecode/templates/admin/user_groups/user_groups.mako
NO CONTENT: file renamed from rhodecode/templates/admin/user_groups/user_groups.html to rhodecode/templates/admin/user_groups/user_groups.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/users/user_add.html to rhodecode/templates/admin/users/user_add.mako
NO CONTENT: file renamed from rhodecode/templates/admin/users/user_add.html to rhodecode/templates/admin/users/user_add.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/users/user_edit.html to rhodecode/templates/admin/users/user_edit.mako
NO CONTENT: file renamed from rhodecode/templates/admin/users/user_edit.html to rhodecode/templates/admin/users/user_edit.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/users/user_edit_advanced.html to rhodecode/templates/admin/users/user_edit_advanced.mako
NO CONTENT: file renamed from rhodecode/templates/admin/users/user_edit_advanced.html to rhodecode/templates/admin/users/user_edit_advanced.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/users/user_edit_auth_tokens.html to rhodecode/templates/admin/users/user_edit_auth_tokens.mako
NO CONTENT: file renamed from rhodecode/templates/admin/users/user_edit_auth_tokens.html to rhodecode/templates/admin/users/user_edit_auth_tokens.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/users/user_edit_emails.html to rhodecode/templates/admin/users/user_edit_emails.mako
NO CONTENT: file renamed from rhodecode/templates/admin/users/user_edit_emails.html to rhodecode/templates/admin/users/user_edit_emails.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/users/user_edit_global_perms.html to rhodecode/templates/admin/users/user_edit_global_perms.mako
NO CONTENT: file renamed from rhodecode/templates/admin/users/user_edit_global_perms.html to rhodecode/templates/admin/users/user_edit_global_perms.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/users/user_edit_ips.html to rhodecode/templates/admin/users/user_edit_ips.mako
NO CONTENT: file renamed from rhodecode/templates/admin/users/user_edit_ips.html to rhodecode/templates/admin/users/user_edit_ips.mako
1 NO CONTENT: file renamed from rhodecode/templates/admin/users/user_edit_perms_summary.html to rhodecode/templates/admin/users/user_edit_perms_summary.mako
NO CONTENT: file renamed from rhodecode/templates/admin/users/user_edit_perms_summary.html to rhodecode/templates/admin/users/user_edit_perms_summary.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/users/user_edit_profile.html to rhodecode/templates/admin/users/user_edit_profile.mako
NO CONTENT: file renamed from rhodecode/templates/admin/users/user_edit_profile.html to rhodecode/templates/admin/users/user_edit_profile.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/admin/users/users.html to rhodecode/templates/admin/users/users.mako
NO CONTENT: file renamed from rhodecode/templates/admin/users/users.html to rhodecode/templates/admin/users/users.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/base/base.html to rhodecode/templates/base/base.mako
NO CONTENT: file renamed from rhodecode/templates/base/base.html to rhodecode/templates/base/base.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/base/default_perms_box.html to rhodecode/templates/base/default_perms_box.mako
NO CONTENT: file renamed from rhodecode/templates/base/default_perms_box.html to rhodecode/templates/base/default_perms_box.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/base/issue_tracker_settings.html to rhodecode/templates/base/issue_tracker_settings.mako
NO CONTENT: file renamed from rhodecode/templates/base/issue_tracker_settings.html to rhodecode/templates/base/issue_tracker_settings.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/base/perms_summary.html to rhodecode/templates/base/perms_summary.mako
NO CONTENT: file renamed from rhodecode/templates/base/perms_summary.html to rhodecode/templates/base/perms_summary.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/base/plugins_base.html to rhodecode/templates/base/plugins_base.mako
NO CONTENT: file renamed from rhodecode/templates/base/plugins_base.html to rhodecode/templates/base/plugins_base.mako
1 NO CONTENT: file renamed from rhodecode/templates/base/root.html to rhodecode/templates/base/root.mako
NO CONTENT: file renamed from rhodecode/templates/base/root.html to rhodecode/templates/base/root.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/base/vcs_settings.html to rhodecode/templates/base/vcs_settings.mako
NO CONTENT: file renamed from rhodecode/templates/base/vcs_settings.html to rhodecode/templates/base/vcs_settings.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/bookmarks/bookmarks.html to rhodecode/templates/bookmarks/bookmarks.mako
NO CONTENT: file renamed from rhodecode/templates/bookmarks/bookmarks.html to rhodecode/templates/bookmarks/bookmarks.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/bookmarks/bookmarks_data.html to rhodecode/templates/bookmarks/bookmarks_data.mako
NO CONTENT: file renamed from rhodecode/templates/bookmarks/bookmarks_data.html to rhodecode/templates/bookmarks/bookmarks_data.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/branches/branches.html to rhodecode/templates/branches/branches.mako
NO CONTENT: file renamed from rhodecode/templates/branches/branches.html to rhodecode/templates/branches/branches.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/branches/branches_data.html to rhodecode/templates/branches/branches_data.mako
NO CONTENT: file renamed from rhodecode/templates/branches/branches_data.html to rhodecode/templates/branches/branches_data.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/changelog/changelog.html to rhodecode/templates/changelog/changelog.mako
NO CONTENT: file renamed from rhodecode/templates/changelog/changelog.html to rhodecode/templates/changelog/changelog.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/changelog/changelog_details.html to rhodecode/templates/changelog/changelog_elements.mako
NO CONTENT: file renamed from rhodecode/templates/changelog/changelog_details.html to rhodecode/templates/changelog/changelog_elements.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/changelog/changelog_file_history.html to rhodecode/templates/changelog/changelog_file_history.mako
NO CONTENT: file renamed from rhodecode/templates/changelog/changelog_file_history.html to rhodecode/templates/changelog/changelog_file_history.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/changelog/changelog_summary_data.html to rhodecode/templates/changelog/changelog_summary_data.mako
NO CONTENT: file renamed from rhodecode/templates/changelog/changelog_summary_data.html to rhodecode/templates/changelog/changelog_summary_data.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/changeset/changeset.html to rhodecode/templates/changeset/changeset.mako
NO CONTENT: file renamed from rhodecode/templates/changeset/changeset.html to rhodecode/templates/changeset/changeset.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/changeset/changeset_comment_block.html to rhodecode/templates/changeset/changeset_comment_block.mako
NO CONTENT: file renamed from rhodecode/templates/changeset/changeset_comment_block.html to rhodecode/templates/changeset/changeset_comment_block.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/changeset/changeset_file_comment.html to rhodecode/templates/changeset/changeset_file_comment.mako
NO CONTENT: file renamed from rhodecode/templates/changeset/changeset_file_comment.html to rhodecode/templates/changeset/changeset_file_comment.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/changeset/changeset_range.html to rhodecode/templates/changeset/changeset_range.mako
NO CONTENT: file renamed from rhodecode/templates/changeset/changeset_range.html to rhodecode/templates/changeset/changeset_range.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/changeset/diff_block.html to rhodecode/templates/changeset/diff_block.mako
NO CONTENT: file renamed from rhodecode/templates/changeset/diff_block.html to rhodecode/templates/changeset/diff_block.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/changeset/patch_changeset.html to rhodecode/templates/changeset/patch_changeset.mako
NO CONTENT: file renamed from rhodecode/templates/changeset/patch_changeset.html to rhodecode/templates/changeset/patch_changeset.mako
1 NO CONTENT: file renamed from rhodecode/templates/channelstream/plugin_init.html to rhodecode/templates/channelstream/plugin_init.mako
NO CONTENT: file renamed from rhodecode/templates/channelstream/plugin_init.html to rhodecode/templates/channelstream/plugin_init.mako
1 NO CONTENT: file renamed from rhodecode/templates/codeblocks/diffs.html to rhodecode/templates/codeblocks/diffs.mako
NO CONTENT: file renamed from rhodecode/templates/codeblocks/diffs.html to rhodecode/templates/codeblocks/diffs.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/codeblocks/source.html to rhodecode/templates/codeblocks/source.mako
NO CONTENT: file renamed from rhodecode/templates/codeblocks/source.html to rhodecode/templates/codeblocks/source.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/compare/compare_commits.html to rhodecode/templates/compare/compare_commits.mako
NO CONTENT: file renamed from rhodecode/templates/compare/compare_commits.html to rhodecode/templates/compare/compare_commits.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/compare/compare_diff.html to rhodecode/templates/compare/compare_diff.mako
NO CONTENT: file renamed from rhodecode/templates/compare/compare_diff.html to rhodecode/templates/compare/compare_diff.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/data_table/_dt_elements.html to rhodecode/templates/data_table/_dt_elements.mako
NO CONTENT: file renamed from rhodecode/templates/data_table/_dt_elements.html to rhodecode/templates/data_table/_dt_elements.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/errors/error_document.html to rhodecode/templates/errors/error_document.mako
NO CONTENT: file renamed from rhodecode/templates/errors/error_document.html to rhodecode/templates/errors/error_document.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/files/base.html to rhodecode/templates/files/base.mako
NO CONTENT: file renamed from rhodecode/templates/files/base.html to rhodecode/templates/files/base.mako
1 NO CONTENT: file renamed from rhodecode/templates/files/file_authors_box.html to rhodecode/templates/files/file_authors_box.mako
NO CONTENT: file renamed from rhodecode/templates/files/file_authors_box.html to rhodecode/templates/files/file_authors_box.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/files/file_tree_author_box.html to rhodecode/templates/files/file_tree_author_box.mako
NO CONTENT: file renamed from rhodecode/templates/files/file_tree_author_box.html to rhodecode/templates/files/file_tree_author_box.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/files/file_tree_detail.html to rhodecode/templates/files/file_tree_detail.mako
NO CONTENT: file renamed from rhodecode/templates/files/file_tree_detail.html to rhodecode/templates/files/file_tree_detail.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/files/files.html to rhodecode/templates/files/files.mako
NO CONTENT: file renamed from rhodecode/templates/files/files.html to rhodecode/templates/files/files.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/files/files_add.html to rhodecode/templates/files/files_add.mako
NO CONTENT: file renamed from rhodecode/templates/files/files_add.html to rhodecode/templates/files/files_add.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/files/files_browser.html to rhodecode/templates/files/files_browser.mako
NO CONTENT: file renamed from rhodecode/templates/files/files_browser.html to rhodecode/templates/files/files_browser.mako
1 NO CONTENT: file renamed from rhodecode/templates/files/files_browser_tree.html to rhodecode/templates/files/files_browser_tree.mako
NO CONTENT: file renamed from rhodecode/templates/files/files_browser_tree.html to rhodecode/templates/files/files_browser_tree.mako
1 NO CONTENT: file renamed from rhodecode/templates/files/files_delete.html to rhodecode/templates/files/files_delete.mako
NO CONTENT: file renamed from rhodecode/templates/files/files_delete.html to rhodecode/templates/files/files_delete.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/files/files_detail.html to rhodecode/templates/files/files_detail.mako
NO CONTENT: file renamed from rhodecode/templates/files/files_detail.html to rhodecode/templates/files/files_detail.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/files/files_edit.html to rhodecode/templates/files/files_edit.mako
NO CONTENT: file renamed from rhodecode/templates/files/files_edit.html to rhodecode/templates/files/files_edit.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/files/files_pjax.html to rhodecode/templates/files/files_pjax.mako
NO CONTENT: file renamed from rhodecode/templates/files/files_pjax.html to rhodecode/templates/files/files_pjax.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/files/files_source.html to rhodecode/templates/files/files_source.mako
NO CONTENT: file renamed from rhodecode/templates/files/files_source.html to rhodecode/templates/files/files_source.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/followers/followers.html to rhodecode/templates/followers/followers.mako
NO CONTENT: file renamed from rhodecode/templates/followers/followers.html to rhodecode/templates/followers/followers.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/followers/followers_data.html to rhodecode/templates/followers/followers_data.mako
NO CONTENT: file renamed from rhodecode/templates/followers/followers_data.html to rhodecode/templates/followers/followers_data.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/forks/fork.html to rhodecode/templates/forks/fork.mako
NO CONTENT: file renamed from rhodecode/templates/forks/fork.html to rhodecode/templates/forks/fork.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/forks/forks.html to rhodecode/templates/forks/forks.mako
NO CONTENT: file renamed from rhodecode/templates/forks/forks.html to rhodecode/templates/forks/forks.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/forks/forks_data.html to rhodecode/templates/forks/forks_data.mako
NO CONTENT: file renamed from rhodecode/templates/forks/forks_data.html to rhodecode/templates/forks/forks_data.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/index.html to rhodecode/templates/index.mako
NO CONTENT: file renamed from rhodecode/templates/index.html to rhodecode/templates/index.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/index_base.html to rhodecode/templates/index_base.mako
NO CONTENT: file renamed from rhodecode/templates/index_base.html to rhodecode/templates/index_base.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/index_repo_group.html to rhodecode/templates/index_repo_group.mako
NO CONTENT: file renamed from rhodecode/templates/index_repo_group.html to rhodecode/templates/index_repo_group.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/journal/journal.html to rhodecode/templates/journal/journal.mako
NO CONTENT: file renamed from rhodecode/templates/journal/journal.html to rhodecode/templates/journal/journal.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/journal/journal_data.html to rhodecode/templates/journal/journal_data.mako
NO CONTENT: file renamed from rhodecode/templates/journal/journal_data.html to rhodecode/templates/journal/journal_data.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/journal/public_journal.html to rhodecode/templates/journal/public_journal.mako
NO CONTENT: file renamed from rhodecode/templates/journal/public_journal.html to rhodecode/templates/journal/public_journal.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/login.html to rhodecode/templates/login.mako
NO CONTENT: file renamed from rhodecode/templates/login.html to rhodecode/templates/login.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/password_reset.html to rhodecode/templates/password_reset.mako
NO CONTENT: file renamed from rhodecode/templates/password_reset.html to rhodecode/templates/password_reset.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/pullrequests/pullrequest.html to rhodecode/templates/pullrequests/pullrequest.mako
NO CONTENT: file renamed from rhodecode/templates/pullrequests/pullrequest.html to rhodecode/templates/pullrequests/pullrequest.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/pullrequests/pullrequest_show.html to rhodecode/templates/pullrequests/pullrequest_show.mako
NO CONTENT: file renamed from rhodecode/templates/pullrequests/pullrequest_show.html to rhodecode/templates/pullrequests/pullrequest_show.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/pullrequests/pullrequests.html to rhodecode/templates/pullrequests/pullrequests.mako
NO CONTENT: file renamed from rhodecode/templates/pullrequests/pullrequests.html to rhodecode/templates/pullrequests/pullrequests.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/register.html to rhodecode/templates/register.mako
NO CONTENT: file renamed from rhodecode/templates/register.html to rhodecode/templates/register.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/search/search.html to rhodecode/templates/search/search.mako
NO CONTENT: file renamed from rhodecode/templates/search/search.html to rhodecode/templates/search/search.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/search/search_commit.html to rhodecode/templates/search/search_commit.mako
NO CONTENT: file renamed from rhodecode/templates/search/search_commit.html to rhodecode/templates/search/search_commit.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/search/search_content.html to rhodecode/templates/search/search_content.mako
NO CONTENT: file renamed from rhodecode/templates/search/search_content.html to rhodecode/templates/search/search_content.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/search/search_path.html to rhodecode/templates/search/search_path.mako
NO CONTENT: file renamed from rhodecode/templates/search/search_path.html to rhodecode/templates/search/search_path.mako
1 NO CONTENT: file renamed from rhodecode/templates/search/search_repository.html to rhodecode/templates/search/search_repository.mako
NO CONTENT: file renamed from rhodecode/templates/search/search_repository.html to rhodecode/templates/search/search_repository.mako
1 NO CONTENT: file renamed from rhodecode/templates/summary/base.html to rhodecode/templates/summary/base.mako
NO CONTENT: file renamed from rhodecode/templates/summary/base.html to rhodecode/templates/summary/base.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/summary/components.html to rhodecode/templates/summary/components.mako
NO CONTENT: file renamed from rhodecode/templates/summary/components.html to rhodecode/templates/summary/components.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/summary/missing_requirements.html to rhodecode/templates/summary/missing_requirements.mako
NO CONTENT: file renamed from rhodecode/templates/summary/missing_requirements.html to rhodecode/templates/summary/missing_requirements.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/summary/summary.html to rhodecode/templates/summary/summary.mako
NO CONTENT: file renamed from rhodecode/templates/summary/summary.html to rhodecode/templates/summary/summary.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/tags/tags.html to rhodecode/templates/tags/tags.mako
NO CONTENT: file renamed from rhodecode/templates/tags/tags.html to rhodecode/templates/tags/tags.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/tags/tags_data.html to rhodecode/templates/tags/tags_data.mako
NO CONTENT: file renamed from rhodecode/templates/tags/tags_data.html to rhodecode/templates/tags/tags_data.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/users/user.html to rhodecode/templates/users/user.mako
NO CONTENT: file renamed from rhodecode/templates/users/user.html to rhodecode/templates/users/user.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/users/user_profile.html to rhodecode/templates/users/user_profile.mako
NO CONTENT: file renamed from rhodecode/templates/users/user_profile.html to rhodecode/templates/users/user_profile.mako
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file renamed from rhodecode/templates/widgets.html to rhodecode/templates/widgets.mako
NO CONTENT: file renamed from rhodecode/templates/widgets.html to rhodecode/templates/widgets.mako
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: file was removed
NO CONTENT: file was removed
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now