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 | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | 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 | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | 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 | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | 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 | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | 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 | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | 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 | 1 | [bumpversion] |
|
2 |
current_version = 4. |
|
|
2 | current_version = 4.6.0 | |
|
3 | 3 | message = release: Bump version {current_version} to {new_version} |
|
4 | 4 | |
|
5 | 5 | [bumpversion:file:rhodecode/VERSION] |
@@ -4,26 +4,21 b' done = false' | |||
|
4 | 4 | [task:bump_version] |
|
5 | 5 | done = true |
|
6 | 6 | |
|
7 | [task:rc_tools_pinned] | |
|
8 | done = true | |
|
9 | ||
|
10 | 7 | [task:fixes_on_stable] |
|
11 | done = true | |
|
12 | 8 | |
|
13 | 9 | [task:pip2nix_generated] |
|
14 | done = true | |
|
15 | 10 | |
|
16 | 11 | [task:changelog_updated] |
|
17 | done = true | |
|
18 | 12 | |
|
19 | 13 | [task:generate_api_docs] |
|
20 | done = true | |
|
14 | ||
|
15 | [task:updated_translation] | |
|
21 | 16 | |
|
22 | 17 | [release] |
|
23 |
state = |
|
|
24 |
version = 4. |
|
|
18 | state = in_progress | |
|
19 | version = 4.6.0 | |
|
25 | 20 | |
|
26 | [task:updated_translation] | |
|
21 | [task:rc_tools_pinned] | |
|
27 | 22 | |
|
28 | 23 | [task:generate_js_routes] |
|
29 | 24 |
@@ -29,8 +29,6 b' recursive-include rhodecode *.mako' | |||
|
29 | 29 | # 502 page |
|
30 | 30 | include rhodecode/public/502.html |
|
31 | 31 | |
|
32 | # 502 page | |
|
33 | include rhodecode/public/502.html | |
|
34 | 32 | |
|
35 | 33 | # images, css |
|
36 | 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 | 4 | WEBPACK=./node_modules/webpack/bin/webpack.js |
|
3 | 5 | GRUNT=grunt |
|
4 | 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 | 24 | docs: |
|
11 | 25 | (cd docs; nix-build default.nix -o result; make clean html) |
@@ -13,27 +27,9 b' docs:' | |||
|
13 | 27 | docs-clean: |
|
14 | 28 | (cd docs; make clean) |
|
15 | 29 | |
|
16 | ci-docs: docs; | |
|
17 | ||
|
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/ | |
|
30 | docs-cleanup: | |
|
31 | (cd docs; make cleanup) | |
|
29 | 32 | |
|
30 | 33 | web-build: |
|
31 | 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 | 416 | ## channelstream enables persistent connections and live notification |
|
417 | 417 | ## in the system. It's also used by the chat system |
|
418 | channelstream.enabled = false | |
|
418 | 419 | |
|
419 | channelstream.enabled = false | |
|
420 | ## location of channelstream server on the backend | |
|
420 | ## server address for channelstream server on the backend | |
|
421 | 421 | channelstream.server = 127.0.0.1:9800 |
|
422 | ||
|
422 | 423 | ## location of the channelstream server from outside world |
|
423 | ## most likely this would be an http server special backend URL, that handles | |
|
424 | ## websocket connections see nginx example for config | |
|
425 | # channelstream.ws_url = ws://rhodecode.yourserver.com/_channelstream | |
|
426 | ## proxy path that can be used by http daemons for exposing channelstream | |
|
427 | # channelstream.proxy_path = /_channelstream | |
|
424 | ## use ws:// for http or wss:// for https. This address needs to be handled | |
|
425 | ## by external HTTP server such as Nginx or Apache | |
|
426 | ## see nginx/apache configuration examples in our docs | |
|
427 | channelstream.ws_url = ws://rhodecode.yourserver.com/_channelstream | |
|
428 | 428 | channelstream.secret = secret |
|
429 | 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 | 437 | ## APPENLIGHT CONFIG ## |
@@ -501,9 +505,9 b' appenlight.log_namespace_blacklist =' | |||
|
501 | 505 | ############## |
|
502 | 506 | debug_style = true |
|
503 | 507 | |
|
504 |
########################################### |
|
|
505 | ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ### | |
|
506 |
########################################### |
|
|
508 | ########################################### | |
|
509 | ### MAIN RHODECODE DATABASE CONFIG ### | |
|
510 | ########################################### | |
|
507 | 511 | #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db?timeout=30 |
|
508 | 512 | #sqlalchemy.db1.url = postgresql://postgres:qweqwe@localhost/rhodecode |
|
509 | 513 | #sqlalchemy.db1.url = mysql://root:qweqwe@localhost/rhodecode |
@@ -586,12 +590,16 b' svn.proxy.location_root = /' | |||
|
586 | 590 | ## be killed. Setting it to zero means no timeout. Defaults to 10 seconds. |
|
587 | 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 | 599 | ### LOGGING CONFIGURATION #### |
|
592 | 600 | ################################ |
|
593 | 601 | [loggers] |
|
594 |
keys = root, routes, rhodecode, sqlalchemy, beaker, |
|
|
602 | keys = root, routes, rhodecode, sqlalchemy, beaker, templates | |
|
595 | 603 | |
|
596 | 604 | [handlers] |
|
597 | 605 | keys = console, console_sql |
@@ -619,12 +627,6 b' handlers =' | |||
|
619 | 627 | qualname = beaker.container |
|
620 | 628 | propagate = 1 |
|
621 | 629 | |
|
622 | [logger_pyro4] | |
|
623 | level = DEBUG | |
|
624 | handlers = | |
|
625 | qualname = Pyro4 | |
|
626 | propagate = 1 | |
|
627 | ||
|
628 | 630 | [logger_templates] |
|
629 | 631 | level = INFO |
|
630 | 632 | handlers = |
@@ -649,13 +651,13 b' propagate = 0' | |||
|
649 | 651 | |
|
650 | 652 | [handler_console] |
|
651 | 653 | class = StreamHandler |
|
652 | args = (sys.stderr,) | |
|
654 | args = (sys.stderr, ) | |
|
653 | 655 | level = DEBUG |
|
654 | 656 | formatter = color_formatter |
|
655 | 657 | |
|
656 | 658 | [handler_console_sql] |
|
657 | 659 | class = StreamHandler |
|
658 | args = (sys.stderr,) | |
|
660 | args = (sys.stderr, ) | |
|
659 | 661 | level = DEBUG |
|
660 | 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 | 16 | import multiprocessing |
|
4 | 17 | import sys |
@@ -6,50 +19,31 b' import threading' | |||
|
6 | 19 | import traceback |
|
7 | 20 | |
|
8 | 21 | |
|
9 |
# GLOBAL |
|
|
22 | # GLOBAL | |
|
10 | 23 | errorlog = '-' |
|
11 | 24 | accesslog = '-' |
|
12 | 25 | loglevel = 'debug' |
|
13 | 26 | |
|
14 |
# SECURITY |
|
|
27 | # SECURITY | |
|
15 | 28 | limit_request_line = 4094 |
|
16 | 29 | limit_request_fields = 100 |
|
17 | 30 | limit_request_field_size = 8190 |
|
18 | 31 | |
|
19 |
# SERVER MECHANICS |
|
|
20 |
# None == system temp dir |
|
|
32 | # SERVER MECHANICS | |
|
33 | # None == system temp dir | |
|
21 | 34 | worker_tmp_dir = None |
|
22 | 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, # | |
|
36 | # could prevent memory leaks # | |
|
37 | #max_requests = 1000 | |
|
38 | #max_requests_jitter = 30 | |
|
39 | ||
|
37 | # Custom log format | |
|
38 | access_log_format = ( | |
|
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"') | |
|
40 | 40 | |
|
41 | # If a worker does not notify the master process in this # | |
|
42 | # number of seconds it is killed and a new worker is spawned # | |
|
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"') | |
|
41 | # self adjust workers based on CPU count | |
|
42 | # workers = multiprocessing.cpu_count() * 2 + 1 | |
|
49 | 43 | |
|
50 | 44 | |
|
51 | 45 | def post_fork(server, worker): |
|
52 |
server.log.info("[<% |
|
|
46 | server.log.info("[<%-10s>] WORKER spawned", worker.pid) | |
|
53 | 47 | |
|
54 | 48 | |
|
55 | 49 | def pre_fork(server, worker): |
@@ -67,7 +61,7 b' def when_ready(server):' | |||
|
67 | 61 | def worker_int(worker): |
|
68 | 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 | 65 | id2name = dict([(th.ident, th.name) for th in threading.enumerate()]) |
|
72 | 66 | code = [] |
|
73 | 67 | for thread_id, stack in sys._current_frames().items(): |
@@ -389,19 +389,23 b' search.location = %(here)s/data/index' | |||
|
389 | 389 | ######################################## |
|
390 | 390 | ## channelstream enables persistent connections and live notification |
|
391 | 391 | ## in the system. It's also used by the chat system |
|
392 | channelstream.enabled = false | |
|
392 | 393 | |
|
393 | channelstream.enabled = false | |
|
394 | ## location of channelstream server on the backend | |
|
394 | ## server address for channelstream server on the backend | |
|
395 | 395 | channelstream.server = 127.0.0.1:9800 |
|
396 | ||
|
396 | 397 | ## location of the channelstream server from outside world |
|
397 | ## most likely this would be an http server special backend URL, that handles | |
|
398 | ## websocket connections see nginx example for config | |
|
399 | # channelstream.ws_url = ws://rhodecode.yourserver.com/_channelstream | |
|
400 | ## proxy path that can be used by http daemons for exposing channelstream | |
|
401 | # channelstream.proxy_path = /_channelstream | |
|
398 | ## use ws:// for http or wss:// for https. This address needs to be handled | |
|
399 | ## by external HTTP server such as Nginx or Apache | |
|
400 | ## see nginx/apache configuration examples in our docs | |
|
401 | channelstream.ws_url = ws://rhodecode.yourserver.com/_channelstream | |
|
402 | 402 | channelstream.secret = secret |
|
403 | 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 | 411 | ## APPENLIGHT CONFIG ## |
@@ -470,9 +474,9 b' appenlight.log_namespace_blacklist =' | |||
|
470 | 474 | set debug = false |
|
471 | 475 | |
|
472 | 476 | |
|
473 |
########################################### |
|
|
474 | ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ### | |
|
475 |
########################################### |
|
|
477 | ########################################### | |
|
478 | ### MAIN RHODECODE DATABASE CONFIG ### | |
|
479 | ########################################### | |
|
476 | 480 | #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db?timeout=30 |
|
477 | 481 | #sqlalchemy.db1.url = postgresql://postgres:qweqwe@localhost/rhodecode |
|
478 | 482 | #sqlalchemy.db1.url = mysql://root:qweqwe@localhost/rhodecode |
@@ -555,12 +559,16 b' svn.proxy.location_root = /' | |||
|
555 | 559 | ## be killed. Setting it to zero means no timeout. Defaults to 10 seconds. |
|
556 | 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 | 568 | ### LOGGING CONFIGURATION #### |
|
561 | 569 | ################################ |
|
562 | 570 | [loggers] |
|
563 |
keys = root, routes, rhodecode, sqlalchemy, beaker, |
|
|
571 | keys = root, routes, rhodecode, sqlalchemy, beaker, templates | |
|
564 | 572 | |
|
565 | 573 | [handlers] |
|
566 | 574 | keys = console, console_sql |
@@ -588,12 +596,6 b' handlers =' | |||
|
588 | 596 | qualname = beaker.container |
|
589 | 597 | propagate = 1 |
|
590 | 598 | |
|
591 | [logger_pyro4] | |
|
592 | level = DEBUG | |
|
593 | handlers = | |
|
594 | qualname = Pyro4 | |
|
595 | propagate = 1 | |
|
596 | ||
|
597 | 599 | [logger_templates] |
|
598 | 600 | level = INFO |
|
599 | 601 | handlers = |
@@ -618,13 +620,13 b' propagate = 0' | |||
|
618 | 620 | |
|
619 | 621 | [handler_console] |
|
620 | 622 | class = StreamHandler |
|
621 | args = (sys.stderr,) | |
|
623 | args = (sys.stderr, ) | |
|
622 | 624 | level = INFO |
|
623 | 625 | formatter = generic |
|
624 | 626 | |
|
625 | 627 | [handler_console_sql] |
|
626 | 628 | class = StreamHandler |
|
627 | args = (sys.stderr,) | |
|
629 | args = (sys.stderr, ) | |
|
628 | 630 | level = WARN |
|
629 | 631 | formatter = generic |
|
630 | 632 |
@@ -135,6 +135,8 b' let' | |||
|
135 | 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 | 140 | propagatedBuildInputs = attrs.propagatedBuildInputs ++ (with self; [ |
|
139 | 141 | rhodecode-tools |
|
140 | 142 | ]); |
@@ -49,6 +49,12 b' help:' | |||
|
49 | 49 | clean: |
|
50 | 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 | 58 | html: |
|
53 | 59 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html |
|
54 | 60 | @echo |
@@ -1,32 +1,68 b'' | |||
|
1 | 1 | .. _apache-conf-eg: |
|
2 | 2 | |
|
3 |
Apache Configuration Example |
|
|
4 |
---------------------------- |
|
|
3 | Apache Configuration Example | |
|
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 | |
|
7 | file. | |
|
15 | .. code-block:: bash | |
|
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 | 28 | .. code-block:: apache |
|
10 | 29 | |
|
30 | ## HTTP to HTTPS rewrite | |
|
11 | 31 | <VirtualHost *:80> |
|
12 |
|
|
|
13 | ServerAlias hg.myserver.com | |
|
32 | ServerName rhodecode.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 | 52 | <Proxy *> |
|
16 | 53 | Order allow,deny |
|
17 | 54 | Allow from all |
|
18 | 55 | </Proxy> |
|
19 | 56 | |
|
20 | # important ! | |
|
21 | # Directive to properly generate url (clone url) for pylons | |
|
22 | ||
|
57 | # Directive to properly generate url (clone url) for RhodeCode | |
|
23 | 58 | ProxyPreserveHost On |
|
24 | 59 | |
|
25 | #rhodecode instance | |
|
26 | ProxyPass / http://127.0.0.1:5000/ | |
|
27 |
ProxyPass |
|
|
60 | # Url to running RhodeCode instance. This is shown as `- URL:` when | |
|
61 | # running rccontrol status. | |
|
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 | 66 | Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload" |
|
31 | 67 | |
|
32 | 68 | # Set x-frame options |
@@ -35,80 +71,17 b' file.' | |||
|
35 | 71 | # To enable https use line below |
|
36 | 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 | 79 | SSLProtocol all -SSLv2 -SSLv3 |
|
40 | 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 | 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 | 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 | 9 | .. toctree:: |
|
10 | 10 | |
|
11 | 11 | apache-diffie-hellman |
|
12 |
apache-conf-example |
|
|
12 | apache-conf-example | |
|
13 | 13 | apache-subdirectory |
|
14 | apache-reverse-proxy | |
|
15 | 14 | apache-wsgi-coding |
@@ -7,7 +7,8 b' Use the following example to configure A' | |||
|
7 | 7 | |
|
8 | 8 | .. code-block:: apache |
|
9 | 9 | |
|
10 |
|
|
|
10 | # Change someprefix into your chosen prefix | |
|
11 | <Location /someprefix > | |
|
11 | 12 | ProxyPreserveHost On |
|
12 | 13 | ProxyPass "http://127.0.0.1:5000/" |
|
13 | 14 | ProxyPassReverse "http://127.0.0.1:5000/" |
@@ -3,6 +3,7 b' Nginx Configuration Example' | |||
|
3 | 3 | |
|
4 | 4 | Use the following example to configure Nginx as a your web server. |
|
5 | 5 | |
|
6 | ||
|
6 | 7 | .. code-block:: nginx |
|
7 | 8 | |
|
8 | 9 | log_format log_custom '$remote_addr - $remote_user [$time_local] ' |
@@ -10,8 +11,10 b' Use the following example to configure N' | |||
|
10 | 11 | '"$http_referer" "$http_user_agent" ' |
|
11 | 12 | '$request_time $upstream_response_time $pipe'; |
|
12 | 13 | |
|
14 | ## define upstream (local RhodeCode instance) to connect to | |
|
13 | 15 | upstream rc { |
|
14 | ||
|
16 | # Url to running RhodeCode instance. | |
|
17 | # This is shown as `- URL:` in output from rccontrol status. | |
|
15 | 18 | server 127.0.0.1:10002; |
|
16 | 19 | |
|
17 | 20 | # add more instances for load balancing |
@@ -19,8 +22,17 b' Use the following example to configure N' | |||
|
19 | 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 | 36 | server { |
|
25 | 37 | listen 443; |
|
26 | 38 | server_name gist.myserver.com; |
@@ -37,6 +49,7 b' Use the following example to configure N' | |||
|
37 | 49 | ssl_prefer_server_ciphers on; |
|
38 | 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 | 53 | add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;"; |
|
41 | 54 | |
|
42 | 55 | # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits |
@@ -46,15 +59,6 b' Use the following example to configure N' | |||
|
46 | 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 | 63 | ## MAIN SSL enabled server |
|
60 | 64 | server { |
@@ -79,14 +83,15 b' Use the following example to configure N' | |||
|
79 | 83 | |
|
80 | 84 | include /etc/nginx/proxy.conf; |
|
81 | 85 | |
|
82 |
## serve static files by |
|
|
86 | ## serve static files by Nginx, recommended for performance | |
|
83 | 87 | # location /_static/rhodecode { |
|
84 | 88 | # alias /path/to/.rccontrol/enterprise-1/static; |
|
85 | 89 | # } |
|
86 | 90 | |
|
87 |
## channel |
|
|
91 | ## channelstream websocket handling | |
|
88 | 92 | location /_channelstream { |
|
89 | 93 | rewrite /_channelstream/(.*) /$1 break; |
|
94 | ||
|
90 | 95 | proxy_pass http://127.0.0.1:9800; |
|
91 | 96 | |
|
92 | 97 | proxy_connect_timeout 10; |
@@ -1,7 +1,7 b'' | |||
|
1 | 1 | .. _nginx-ws-ref: |
|
2 | 2 | |
|
3 | Nginx Configuration | |
|
4 | =================== | |
|
3 | Nginx HTTP Server Configuration | |
|
4 | ------------------------------- | |
|
5 | 5 | |
|
6 | 6 | To set up your Nginx Web Server for optimal performance and security, use |
|
7 | 7 | the information in the following sections. |
@@ -12,6 +12,7 b' it somehow becomes unavailable you can u' | |||
|
12 | 12 | Logging into the |RCE| database with ``iShell`` should only be done by an |
|
13 | 13 | experienced and knowledgeable database administrator. |
|
14 | 14 | |
|
15 | ||
|
15 | 16 | Reset Admin Account Privileges |
|
16 | 17 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
|
17 | 18 | |
@@ -22,8 +23,7 b' account permissions.' | |||
|
22 | 23 | .. code-block:: bash |
|
23 | 24 | |
|
24 | 25 | # Open iShell from the terminal |
|
25 |
$ |
|
|
26 | ishell .rccontrol/enterprise-1/rhodecode.ini | |
|
26 | $ rccontrol ishell enterprise-1 | |
|
27 | 27 | |
|
28 | 28 | .. code-block:: mysql |
|
29 | 29 | |
@@ -33,6 +33,7 b' account permissions.' | |||
|
33 | 33 | In [3]: Session().add(adminuser);Session().commit() |
|
34 | 34 | In [4]: exit() |
|
35 | 35 | |
|
36 | ||
|
36 | 37 | Set to read global ``.hgrc`` file |
|
37 | 38 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
|
38 | 39 | |
@@ -46,8 +47,7 b' following example to make changes to thi' | |||
|
46 | 47 | .. code-block:: bash |
|
47 | 48 | |
|
48 | 49 | # Open iShell from the terminal |
|
49 | $ .rccontrol/enterprise-5/profile/bin/paster \ | |
|
50 | ishell.rccontrol/enterprise-5/rhodecode.ini | |
|
50 | $ rccontrol ishell enterprise-1 | |
|
51 | 51 | |
|
52 | 52 | .. code-block:: mysql |
|
53 | 53 | |
@@ -59,6 +59,7 b' following example to make changes to thi' | |||
|
59 | 59 | In [5]: Session().add(new_option);Session().commit() |
|
60 | 60 | In [6]: exit() |
|
61 | 61 | |
|
62 | ||
|
62 | 63 | Manually Reset Password |
|
63 | 64 | ^^^^^^^^^^^^^^^^^^^^^^^ |
|
64 | 65 | |
@@ -73,8 +74,7 b' Use the following code example to carry ' | |||
|
73 | 74 | .. code-block:: bash |
|
74 | 75 | |
|
75 | 76 | # starts the ishell interactive prompt |
|
76 |
$ |
|
|
77 | ishell .rccontrol/enterprise-1/rhodecode.ini | |
|
77 | $ rccontrol ishell enterprise-1 | |
|
78 | 78 | |
|
79 | 79 | .. code-block:: mysql |
|
80 | 80 | |
@@ -91,7 +91,6 b' Use the following code example to carry ' | |||
|
91 | 91 | In [8]: exit() |
|
92 | 92 | |
|
93 | 93 | |
|
94 | ||
|
95 | 94 | Change user details |
|
96 | 95 | ^^^^^^^^^^^^^^^^^^^ |
|
97 | 96 | |
@@ -106,8 +105,7 b' Use the following code example to carry ' | |||
|
106 | 105 | .. code-block:: bash |
|
107 | 106 | |
|
108 | 107 | # starts the ishell interactive prompt |
|
109 |
$ |
|
|
110 | ishell .rccontrol/enterprise-1/rhodecode.ini | |
|
108 | $ rccontrol ishell enterprise-1 | |
|
111 | 109 | |
|
112 | 110 | .. code-block:: mysql |
|
113 | 111 | |
@@ -117,3 +115,37 b' Use the following code example to carry ' | |||
|
117 | 115 | In [3]: my_user.username = 'SomeUser' |
|
118 | 116 | In [4]: Session().add(my_user);Session().commit() |
|
119 | 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 | 28 | $ sudo a2enmod dav_svn |
|
29 | 29 | $ sudo a2enmod headers |
|
30 | $ sudo a2enmod authn_anon | |
|
30 | 31 | |
|
31 | 32 | |
|
32 | 33 | Configuring Apache Setup |
@@ -55,7 +56,7 b' permission issues could occur. To do thi' | |||
|
55 | 56 | export APACHE_RUN_GROUP=rhodecode |
|
56 | 57 | |
|
57 | 58 | 1. To configure Apache, create and edit a virtual hosts file, for example |
|
58 |
:file:`/etc/apache2/sites- |
|
|
59 | :file:`/etc/apache2/sites-enabled/default.conf`. Below is an example | |
|
59 | 60 | how to use one with auto-generated config ```mod_dav_svn.conf``` |
|
60 | 61 | from configured |RCE| instance. |
|
61 | 62 |
@@ -13,7 +13,7 b' 1. Open ishell from the terminal and use' | |||
|
13 | 13 | .. code-block:: bash |
|
14 | 14 | |
|
15 | 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 | 18 | 2. Run the following commands, and ensure that |RCE| has write access to the |
|
19 | 19 | new directory: |
@@ -3,21 +3,6 b'' | |||
|
3 | 3 | Increase Database Performance |
|
4 | 4 | ----------------------------- |
|
5 | 5 | |
|
6 | To increase database performance switch to database-based user sessions. | |
|
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. | |
|
6 | For tuning PostgreSQL we recommend reading: http://www.revsys.com/writings/postgresql-performance.html | |
|
12 | 7 | |
|
13 | To switch to database-based user sessions uncomment the following section in | |
|
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 | |
|
8 | For tuning MySQL we recommend reading: http://www.tecmint.com/mysql-mariadb-performance-tuning-and-optimization/ No newline at end of file |
@@ -34,8 +34,8 b' performance boost.' | |||
|
34 | 34 | |
|
35 | 35 | .. code-block:: bash |
|
36 | 36 | |
|
37 |
# mount tmp to memory with 2GB limit and 7 |
|
|
38 |
mount -t tmpfs -o size=2G,mode= |
|
|
37 | # mount tmp to memory with 2GB limit and 1777 write permissions | |
|
38 | mount -t tmpfs -o size=2G,mode=1777 tmpfs /tmp | |
|
39 | 39 | |
|
40 | 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 | 11 | tuning-gunicorn |
|
12 | 12 | tuning-vcs-memory-cache |
|
13 | tuning-user-sessions-performance | |
|
13 | 14 | tuning-increase-db-performance |
|
14 | 15 | tuning-scale-horizontally |
|
15 | 16 | tuning-increase-cache-size |
@@ -36,7 +36,7 b' close_pull_request' | |||
|
36 | 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 | 41 | Comment on the pull request specified with the `pullrequestid`, |
|
42 | 42 | in the |repo| specified by the `repoid`, and optionally change the |
@@ -48,15 +48,18 b' comment_pull_request' | |||
|
48 | 48 | :type repoid: str or int |
|
49 | 49 | :param pullrequestid: The pull request ID. |
|
50 | 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 | 55 | :param message: The text content of the comment. |
|
52 | 56 | :type message: str |
|
53 | 57 | :param status: (**Optional**) Set the approval status of the pull |
|
54 | request. Valid options are: | |
|
55 |
|
|
|
56 | * approved | |
|
57 | * rejected | |
|
58 | * under_review | |
|
58 | request. One of: 'not_reviewed', 'approved', 'rejected', | |
|
59 | 'under_review' | |
|
59 | 60 | :type status: str |
|
61 | :param comment_type: Comment type, one of: 'note', 'todo' | |
|
62 | :type comment_type: Optional(str), default: 'note' | |
|
60 | 63 | :param userid: Comment on the pull request as this user |
|
61 | 64 | :type userid: Optional(str or int) |
|
62 | 65 | |
@@ -68,7 +71,9 b' comment_pull_request' | |||
|
68 | 71 | result : |
|
69 | 72 | { |
|
70 | 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 | 78 | error : null |
|
74 | 79 |
@@ -28,7 +28,7 b' add_field_to_repo' | |||
|
28 | 28 | comment_commit |
|
29 | 29 | -------------- |
|
30 | 30 | |
|
31 |
.. py:function:: comment_commit(apiuser, repoid, commit_id, message, userid=<Optional:<OptionalAttr:apiuser> |
|
|
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 | 33 | Set a commit comment, and optionally change the status of the commit. |
|
34 | 34 | |
@@ -40,15 +40,17 b' comment_commit' | |||
|
40 | 40 | :type commit_id: str |
|
41 | 41 | :param message: The comment text. |
|
42 | 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 | 48 | :param userid: Set the user name of the comment creator. |
|
44 | 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 | 51 | Example error output: |
|
50 | 52 | |
|
51 |
.. code-block:: |
|
|
53 | .. code-block:: bash | |
|
52 | 54 | |
|
53 | 55 | { |
|
54 | 56 | "id" : <id_given_in_input>, |
@@ -539,7 +541,7 b' get_repo_settings' | |||
|
539 | 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 | 546 | Lists all existing repositories. |
|
545 | 547 | |
@@ -548,6 +550,14 b' get_repos' | |||
|
548 | 550 | |
|
549 | 551 | :param apiuser: This is filled automatically from the |authtoken|. |
|
550 | 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 | 562 | Example output: |
|
553 | 563 |
@@ -3,6 +3,49 b'' | |||
|
3 | 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 | 49 | get_ip |
|
7 | 50 | ------ |
|
8 | 51 |
@@ -47,6 +47,17 b' Followed by::' | |||
|
47 | 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 | 61 | Clone the required repositories |
|
51 | 62 | ------------------------------- |
|
52 | 63 | |
@@ -64,6 +75,21 b' To do this, use the following example::' | |||
|
64 | 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 | 94 | Enter the Development Shell |
|
69 | 95 | --------------------------- |
@@ -9,6 +9,7 b' Release Notes' | |||
|
9 | 9 | .. toctree:: |
|
10 | 10 | :maxdepth: 1 |
|
11 | 11 | |
|
12 | release-notes-4.6.0.rst | |
|
12 | 13 | release-notes-4.5.2.rst |
|
13 | 14 | release-notes-4.5.1.rst |
|
14 | 15 | release-notes-4.5.0.rst |
@@ -68,6 +68,7 b'' | |||
|
68 | 68 | "<%= dirs.js.src %>/rhodecode/utils/os.js", |
|
69 | 69 | "<%= dirs.js.src %>/rhodecode/utils/topics.js", |
|
70 | 70 | "<%= dirs.js.src %>/rhodecode/init.js", |
|
71 | "<%= dirs.js.src %>/rhodecode/changelog.js", | |
|
71 | 72 | "<%= dirs.js.src %>/rhodecode/codemirror.js", |
|
72 | 73 | "<%= dirs.js.src %>/rhodecode/comments.js", |
|
73 | 74 | "<%= dirs.js.src %>/rhodecode/constants.js", |
@@ -100,11 +100,7 b' self: super: {' | |||
|
100 | 100 | }); |
|
101 | 101 | |
|
102 | 102 | py-gfm = super.py-gfm.override { |
|
103 | src = pkgs.fetchgit { | |
|
104 | url = "https://code.rhodecode.com/upstream/py-gfm"; | |
|
105 | rev = "0d66a19bc16e3d49de273c0f797d4e4781e8c0f2"; | |
|
106 | sha256 = "0ryp74jyihd3ckszq31bml5jr3bciimhfp7va7kw6ld92930ksv3"; | |
|
107 | }; | |
|
103 | name = "py-gfm-0.1.3.rhodecode-upstream1"; | |
|
108 | 104 | }; |
|
109 | 105 | |
|
110 | 106 | pycurl = super.pycurl.override (attrs: { |
@@ -123,12 +119,7 b' self: super: {' | |||
|
123 | 119 | }); |
|
124 | 120 | |
|
125 | 121 | Pylons = super.Pylons.override (attrs: { |
|
126 |
name = "Pylons-1.0. |
|
|
127 | src = pkgs.fetchgit { | |
|
128 | url = "https://code.rhodecode.com/upstream/pylons"; | |
|
129 | rev = "707354ee4261b9c10450404fc9852ccea4fd667d"; | |
|
130 | sha256 = "b2763274c2780523a335f83a1df65be22ebe4ff413a7bc9e9288d23c1f62032e"; | |
|
131 | }; | |
|
122 | name = "Pylons-1.0.2.rhodecode-patch1"; | |
|
132 | 123 | }); |
|
133 | 124 | |
|
134 | 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 | 143 | pysqlite = super.pysqlite.override (attrs: { |
|
163 | 144 | propagatedBuildInputs = [ |
|
164 | 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 | 186 | URLObject = super.URLObject.override (attrs: { |
|
212 | 187 | meta = { |
|
213 | 188 | license = { |
@@ -81,26 +81,26 b'' | |||
|
81 | 81 | }; |
|
82 | 82 | }; |
|
83 | 83 | Mako = super.buildPythonPackage { |
|
84 |
name = "Mako-1.0. |
|
|
84 | name = "Mako-1.0.6"; | |
|
85 | 85 | buildInputs = with self; []; |
|
86 | 86 | doCheck = false; |
|
87 | 87 | propagatedBuildInputs = with self; [MarkupSafe]; |
|
88 | 88 | src = fetchurl { |
|
89 | url = "https://pypi.python.org/packages/8e/a4/aa56533ecaa5f22ca92428f74e074d0c9337282933c722391902c8f9e0f8/Mako-1.0.1.tar.gz"; | |
|
90 | md5 = "9f0aafd177b039ef67b90ea350497a54"; | |
|
89 | url = "https://pypi.python.org/packages/56/4b/cb75836863a6382199aefb3d3809937e21fa4cb0db15a4f4ba0ecc2e7e8e/Mako-1.0.6.tar.gz"; | |
|
90 | md5 = "a28e22a339080316b2acc352b9ee631c"; | |
|
91 | 91 | }; |
|
92 | 92 | meta = { |
|
93 | 93 | license = [ pkgs.lib.licenses.mit ]; |
|
94 | 94 | }; |
|
95 | 95 | }; |
|
96 | 96 | Markdown = super.buildPythonPackage { |
|
97 |
name = "Markdown-2.6. |
|
|
97 | name = "Markdown-2.6.7"; | |
|
98 | 98 | buildInputs = with self; []; |
|
99 | 99 | doCheck = false; |
|
100 | 100 | propagatedBuildInputs = with self; []; |
|
101 | 101 | src = fetchurl { |
|
102 |
url = "https://pypi.python.org/packages/62 |
|
|
103 | md5 = "256d19afcc564dc4ce4c229bb762f7ae"; | |
|
102 | url = "https://pypi.python.org/packages/48/a4/fc6b002789c2239ac620ca963694c95b8f74e4747769cdf6021276939e74/Markdown-2.6.7.zip"; | |
|
103 | md5 = "632710a7474bbb74a82084392251061f"; | |
|
104 | 104 | }; |
|
105 | 105 | meta = { |
|
106 | 106 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
@@ -133,13 +133,13 b'' | |||
|
133 | 133 | }; |
|
134 | 134 | }; |
|
135 | 135 | Paste = super.buildPythonPackage { |
|
136 |
name = "Paste-2.0. |
|
|
136 | name = "Paste-2.0.3"; | |
|
137 | 137 | buildInputs = with self; []; |
|
138 | 138 | doCheck = false; |
|
139 | 139 | propagatedBuildInputs = with self; [six]; |
|
140 | 140 | src = fetchurl { |
|
141 | url = "https://pypi.python.org/packages/d5/8d/0f8ac40687b97ff3e07ebd1369be20bdb3f93864d2dc3c2ff542edb4ce50/Paste-2.0.2.tar.gz"; | |
|
142 | md5 = "4bfc8a7eaf858f6309d2ac0f40fc951c"; | |
|
141 | url = "https://pypi.python.org/packages/30/c3/5c2f7c7a02e4f58d4454353fa1c32c94f79fa4e36d07a67c0ac295ea369e/Paste-2.0.3.tar.gz"; | |
|
142 | md5 = "1231e14eae62fa7ed76e9130b04bc61e"; | |
|
143 | 143 | }; |
|
144 | 144 | meta = { |
|
145 | 145 | license = [ pkgs.lib.licenses.mit ]; |
@@ -172,26 +172,26 b'' | |||
|
172 | 172 | }; |
|
173 | 173 | }; |
|
174 | 174 | Pygments = super.buildPythonPackage { |
|
175 |
name = "Pygments-2. |
|
|
175 | name = "Pygments-2.2.0"; | |
|
176 | 176 | buildInputs = with self; []; |
|
177 | 177 | doCheck = false; |
|
178 | 178 | propagatedBuildInputs = with self; []; |
|
179 | 179 | src = fetchurl { |
|
180 |
url = "https://pypi.python.org/packages/ |
|
|
181 | md5 = "ed3fba2467c8afcda4d317e4ef2c6150"; | |
|
180 | url = "https://pypi.python.org/packages/71/2a/2e4e77803a8bd6408a2903340ac498cb0a2181811af7c9ec92cb70b0308a/Pygments-2.2.0.tar.gz"; | |
|
181 | md5 = "13037baca42f16917cbd5ad2fab50844"; | |
|
182 | 182 | }; |
|
183 | 183 | meta = { |
|
184 | 184 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
|
185 | 185 | }; |
|
186 | 186 | }; |
|
187 | 187 | Pylons = super.buildPythonPackage { |
|
188 | name = "Pylons-1.0.1"; | |
|
188 | name = "Pylons-1.0.2.dev20161213"; | |
|
189 | 189 | buildInputs = with self; []; |
|
190 | 190 | doCheck = false; |
|
191 | 191 | propagatedBuildInputs = with self; [Routes WebHelpers Beaker Paste PasteDeploy PasteScript FormEncode simplejson decorator nose Mako WebError WebTest Tempita MarkupSafe WebOb]; |
|
192 | 192 | src = fetchurl { |
|
193 | url = "https://pypi.python.org/packages/a2/69/b835a6bad00acbfeed3f33c6e44fa3f936efc998c795bfb15c61a79ecf62/Pylons-1.0.1.tar.gz"; | |
|
194 | md5 = "6cb880d75fa81213192142b07a6e4915"; | |
|
193 | url = "https://code.rhodecode.com/upstream/pylons/archive/707354ee4261b9c10450404fc9852ccea4fd667d.tar.gz?md5=f26633726fa2cd3a340316ee6a5d218f"; | |
|
194 | md5 = "f26633726fa2cd3a340316ee6a5d218f"; | |
|
195 | 195 | }; |
|
196 | 196 | meta = { |
|
197 | 197 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
@@ -341,13 +341,13 b'' | |||
|
341 | 341 | }; |
|
342 | 342 | }; |
|
343 | 343 | Whoosh = super.buildPythonPackage { |
|
344 |
name = "Whoosh-2.7. |
|
|
344 | name = "Whoosh-2.7.4"; | |
|
345 | 345 | buildInputs = with self; []; |
|
346 | 346 | doCheck = false; |
|
347 | 347 | propagatedBuildInputs = with self; []; |
|
348 | 348 | src = fetchurl { |
|
349 |
url = "https://pypi.python.org/packages/1 |
|
|
350 | md5 = "7abfd970f16fadc7311960f3fa0bc7a9"; | |
|
349 | url = "https://pypi.python.org/packages/25/2b/6beed2107b148edc1321da0d489afc4617b9ed317ef7b72d4993cad9b684/Whoosh-2.7.4.tar.gz"; | |
|
350 | md5 = "c2710105f20b3e29936bd2357383c325"; | |
|
351 | 351 | }; |
|
352 | 352 | meta = { |
|
353 | 353 | license = [ pkgs.lib.licenses.bsdOriginal pkgs.lib.licenses.bsd2 ]; |
@@ -639,19 +639,6 b'' | |||
|
639 | 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 | 642 | ecdsa = super.buildPythonPackage { |
|
656 | 643 | name = "ecdsa-0.11"; |
|
657 | 644 | buildInputs = with self; []; |
@@ -679,13 +666,13 b'' | |||
|
679 | 666 | }; |
|
680 | 667 | }; |
|
681 | 668 | elasticsearch-dsl = super.buildPythonPackage { |
|
682 |
name = "elasticsearch-dsl-2. |
|
|
669 | name = "elasticsearch-dsl-2.2.0"; | |
|
683 | 670 | buildInputs = with self; []; |
|
684 | 671 | doCheck = false; |
|
685 | 672 | propagatedBuildInputs = with self; [six python-dateutil elasticsearch]; |
|
686 | 673 | src = fetchurl { |
|
687 |
url = "https://pypi.python.org/packages/ |
|
|
688 | md5 = "4cdfec81bb35383dd3b7d02d7dc5ee68"; | |
|
674 | url = "https://pypi.python.org/packages/66/2f/52a086968788e58461641570f45c3207a52d46ebbe9b77dc22b6a8ffda66/elasticsearch-dsl-2.2.0.tar.gz"; | |
|
675 | md5 = "fa6bd3c87ea3caa8f0f051bc37c53221"; | |
|
689 | 676 | }; |
|
690 | 677 | meta = { |
|
691 | 678 | license = [ pkgs.lib.licenses.asl20 ]; |
@@ -731,13 +718,13 b'' | |||
|
731 | 718 | }; |
|
732 | 719 | }; |
|
733 | 720 | gevent = super.buildPythonPackage { |
|
734 |
name = "gevent-1.1. |
|
|
721 | name = "gevent-1.1.2"; | |
|
735 | 722 | buildInputs = with self; []; |
|
736 | 723 | doCheck = false; |
|
737 | 724 | propagatedBuildInputs = with self; [greenlet]; |
|
738 | 725 | src = fetchurl { |
|
739 |
url = "https://pypi.python.org/packages/ |
|
|
740 | md5 = "1532f5396ab4d07a231f1935483be7c3"; | |
|
726 | url = "https://pypi.python.org/packages/43/8f/cb3224a0e6ab663547f45c10d0651cfd52633fde4283bf68d627084df8cc/gevent-1.1.2.tar.gz"; | |
|
727 | md5 = "bb32a2f852a4997138014d5007215c6e"; | |
|
741 | 728 | }; |
|
742 | 729 | meta = { |
|
743 | 730 | license = [ pkgs.lib.licenses.mit ]; |
@@ -757,26 +744,26 b'' | |||
|
757 | 744 | }; |
|
758 | 745 | }; |
|
759 | 746 | gprof2dot = super.buildPythonPackage { |
|
760 |
name = "gprof2dot-201 |
|
|
747 | name = "gprof2dot-2016.10.13"; | |
|
761 | 748 | buildInputs = with self; []; |
|
762 | 749 | doCheck = false; |
|
763 | 750 | propagatedBuildInputs = with self; []; |
|
764 | 751 | src = fetchurl { |
|
765 |
url = "https://pypi.python.org/packages/ |
|
|
766 | md5 = "e23bf4e2f94db032750c193384b4165b"; | |
|
752 | url = "https://pypi.python.org/packages/a0/e0/73c71baed306f0402a00a94ffc7b2be94ad1296dfcb8b46912655b93154c/gprof2dot-2016.10.13.tar.gz"; | |
|
753 | md5 = "0125401f15fd2afe1df686a76c64a4fd"; | |
|
767 | 754 | }; |
|
768 | 755 | meta = { |
|
769 | 756 | license = [ { fullName = "LGPL"; } ]; |
|
770 | 757 | }; |
|
771 | 758 | }; |
|
772 | 759 | greenlet = super.buildPythonPackage { |
|
773 |
name = "greenlet-0.4. |
|
|
760 | name = "greenlet-0.4.10"; | |
|
774 | 761 | buildInputs = with self; []; |
|
775 | 762 | doCheck = false; |
|
776 | 763 | propagatedBuildInputs = with self; []; |
|
777 | 764 | src = fetchurl { |
|
778 | url = "https://pypi.python.org/packages/4e/3d/9d421539b74e33608b245092870156b2e171fb49f2b51390aa4641eecb4a/greenlet-0.4.9.zip"; | |
|
779 | md5 = "c6659cdb2a5e591723e629d2eef22e82"; | |
|
765 | url = "https://pypi.python.org/packages/67/62/ca2a95648666eaa2ffeb6a9b3964f21d419ae27f82f2e66b53da5b943fc4/greenlet-0.4.10.zip"; | |
|
766 | md5 = "bed0c4b3b896702131f4d5c72f87c41d"; | |
|
780 | 767 | }; |
|
781 | 768 | meta = { |
|
782 | 769 | license = [ pkgs.lib.licenses.mit ]; |
@@ -939,13 +926,13 b'' | |||
|
939 | 926 | }; |
|
940 | 927 | }; |
|
941 | 928 | msgpack-python = super.buildPythonPackage { |
|
942 |
name = "msgpack-python-0.4. |
|
|
929 | name = "msgpack-python-0.4.8"; | |
|
943 | 930 | buildInputs = with self; []; |
|
944 | 931 | doCheck = false; |
|
945 | 932 | propagatedBuildInputs = with self; []; |
|
946 | 933 | src = fetchurl { |
|
947 |
url = "https://pypi.python.org/packages/15 |
|
|
948 | md5 = "8b317669314cf1bc881716cccdaccb30"; | |
|
934 | url = "https://pypi.python.org/packages/21/27/8a1d82041c7a2a51fcc73675875a5f9ea06c2663e02fcfeb708be1d081a0/msgpack-python-0.4.8.tar.gz"; | |
|
935 | md5 = "dcd854fb41ee7584ebbf35e049e6be98"; | |
|
949 | 936 | }; |
|
950 | 937 | meta = { |
|
951 | 938 | license = [ pkgs.lib.licenses.asl20 ]; |
@@ -1108,13 +1095,13 b'' | |||
|
1108 | 1095 | }; |
|
1109 | 1096 | }; |
|
1110 | 1097 | py = super.buildPythonPackage { |
|
1111 |
name = "py-1.4. |
|
|
1098 | name = "py-1.4.31"; | |
|
1112 | 1099 | buildInputs = with self; []; |
|
1113 | 1100 | doCheck = false; |
|
1114 | 1101 | propagatedBuildInputs = with self; []; |
|
1115 | 1102 | src = fetchurl { |
|
1116 | url = "https://pypi.python.org/packages/2a/bc/a1a4a332ac10069b8e5e25136a35e08a03f01fd6ab03d819889d79a1fd65/py-1.4.29.tar.gz"; | |
|
1117 | md5 = "c28e0accba523a29b35a48bb703fb96c"; | |
|
1103 | url = "https://pypi.python.org/packages/f4/9a/8dfda23f36600dd701c6722316ba8a3ab4b990261f83e7d3ffc6dfedf7ef/py-1.4.31.tar.gz"; | |
|
1104 | md5 = "5d2c63c56dc3f2115ec35c066ecd582b"; | |
|
1118 | 1105 | }; |
|
1119 | 1106 | meta = { |
|
1120 | 1107 | license = [ pkgs.lib.licenses.mit ]; |
@@ -1139,8 +1126,8 b'' | |||
|
1139 | 1126 | doCheck = false; |
|
1140 | 1127 | propagatedBuildInputs = with self; [setuptools Markdown]; |
|
1141 | 1128 | src = fetchurl { |
|
1142 | url = "https://pypi.python.org/packages/12/e4/6b3d8678da04f97d7490d8264d8de51c2dc9fb91209ccee9c515c95e14c5/py-gfm-0.1.3.tar.gz"; | |
|
1143 | md5 = "e588d9e69640a241b97e2c59c22527a6"; | |
|
1129 | url = "https://code.rhodecode.com/upstream/py-gfm/archive/0d66a19bc16e3d49de273c0f797d4e4781e8c0f2.tar.gz?md5=0d0d5385bfb629eea636a80b9c2bfd16"; | |
|
1130 | md5 = "0d0d5385bfb629eea636a80b9c2bfd16"; | |
|
1144 | 1131 | }; |
|
1145 | 1132 | meta = { |
|
1146 | 1133 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
@@ -1290,13 +1277,13 b'' | |||
|
1290 | 1277 | }; |
|
1291 | 1278 | }; |
|
1292 | 1279 | pytest = super.buildPythonPackage { |
|
1293 |
name = "pytest- |
|
|
1280 | name = "pytest-3.0.5"; | |
|
1294 | 1281 | buildInputs = with self; []; |
|
1295 | 1282 | doCheck = false; |
|
1296 | 1283 | propagatedBuildInputs = with self; [py]; |
|
1297 | 1284 | src = fetchurl { |
|
1298 | url = "https://pypi.python.org/packages/b1/3d/d7ea9b0c51e0cacded856e49859f0a13452747491e842c236bbab3714afe/pytest-2.8.5.zip"; | |
|
1299 | md5 = "8493b06f700862f1294298d6c1b715a9"; | |
|
1285 | url = "https://pypi.python.org/packages/a8/87/b7ca49efe52d2b4169f2bfc49aa5e384173c4619ea8e635f123a0dac5b75/pytest-3.0.5.tar.gz"; | |
|
1286 | md5 = "cefd527b59332688bf5db4a10aa8a7cb"; | |
|
1300 | 1287 | }; |
|
1301 | 1288 | meta = { |
|
1302 | 1289 | license = [ pkgs.lib.licenses.mit ]; |
@@ -1316,52 +1303,65 b'' | |||
|
1316 | 1303 | }; |
|
1317 | 1304 | }; |
|
1318 | 1305 | pytest-cov = super.buildPythonPackage { |
|
1319 |
name = "pytest-cov- |
|
|
1306 | name = "pytest-cov-2.4.0"; | |
|
1320 | 1307 | buildInputs = with self; []; |
|
1321 | 1308 | doCheck = false; |
|
1322 |
propagatedBuildInputs = with self; [ |
|
|
1309 | propagatedBuildInputs = with self; [pytest coverage]; | |
|
1323 | 1310 | src = fetchurl { |
|
1324 | url = "https://pypi.python.org/packages/11/4b/b04646e97f1721878eb21e9f779102d84dd044d324382263b1770a3e4838/pytest-cov-1.8.1.tar.gz"; | |
|
1325 | md5 = "76c778afa2494088270348be42d759fc"; | |
|
1311 | url = "https://pypi.python.org/packages/00/c0/2bfd1fcdb9d407b8ac8185b1cb5ff458105c6b207a9a7f0e13032de9828f/pytest-cov-2.4.0.tar.gz"; | |
|
1312 | md5 = "2fda09677d232acc99ec1b3c5831e33f"; | |
|
1326 | 1313 | }; |
|
1327 | 1314 | meta = { |
|
1328 | license = [ pkgs.lib.licenses.mit ]; | |
|
1315 | license = [ pkgs.lib.licenses.bsdOriginal pkgs.lib.licenses.mit ]; | |
|
1329 | 1316 | }; |
|
1330 | 1317 | }; |
|
1331 | 1318 | pytest-profiling = super.buildPythonPackage { |
|
1332 |
name = "pytest-profiling-1. |
|
|
1319 | name = "pytest-profiling-1.2.2"; | |
|
1333 | 1320 | buildInputs = with self; []; |
|
1334 | 1321 | doCheck = false; |
|
1335 | 1322 | propagatedBuildInputs = with self; [six pytest gprof2dot]; |
|
1336 | 1323 | src = fetchurl { |
|
1337 |
url = "https://pypi.python.org/packages/ |
|
|
1338 | md5 = "354404eb5b3fd4dc5eb7fffbb3d9b68b"; | |
|
1324 | url = "https://pypi.python.org/packages/73/e8/804681323bac0bc45c520ec34185ba8469008942266d0074699b204835c1/pytest-profiling-1.2.2.tar.gz"; | |
|
1325 | md5 = "0a16d7dda2d23b91e9730fa4558cf728"; | |
|
1339 | 1326 | }; |
|
1340 | 1327 | meta = { |
|
1341 | 1328 | license = [ pkgs.lib.licenses.mit ]; |
|
1342 | 1329 | }; |
|
1343 | 1330 | }; |
|
1344 | 1331 | pytest-runner = super.buildPythonPackage { |
|
1345 |
name = "pytest-runner-2. |
|
|
1332 | name = "pytest-runner-2.9"; | |
|
1346 | 1333 | buildInputs = with self; []; |
|
1347 | 1334 | doCheck = false; |
|
1348 | 1335 | propagatedBuildInputs = with self; []; |
|
1349 | 1336 | src = fetchurl { |
|
1350 |
url = "https://pypi.python.org/packages/ |
|
|
1351 | md5 = "e56f0bc8d79a6bd91772b44ef4215c7e"; | |
|
1337 | url = "https://pypi.python.org/packages/11/d4/c335ddf94463e451109e3494e909765c3e5205787b772e3b25ee8601b86a/pytest-runner-2.9.tar.gz"; | |
|
1338 | md5 = "2212a2e34404b0960b2fdc2c469247b2"; | |
|
1352 | 1339 | }; |
|
1353 | 1340 | meta = { |
|
1354 | 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 | 1357 | pytest-timeout = super.buildPythonPackage { |
|
1358 |
name = "pytest-timeout-0 |
|
|
1358 | name = "pytest-timeout-1.2.0"; | |
|
1359 | 1359 | buildInputs = with self; []; |
|
1360 | 1360 | doCheck = false; |
|
1361 | 1361 | propagatedBuildInputs = with self; [pytest]; |
|
1362 | 1362 | src = fetchurl { |
|
1363 |
url = "https://pypi.python.org/packages/2 |
|
|
1364 | md5 = "03b28aff69cbbfb959ed35ade5fde262"; | |
|
1363 | url = "https://pypi.python.org/packages/cc/b7/b2a61365ea6b6d2e8881360ae7ed8dad0327ad2df89f2f0be4a02304deb2/pytest-timeout-1.2.0.tar.gz"; | |
|
1364 | md5 = "83607d91aa163562c7ee835da57d061d"; | |
|
1365 | 1365 | }; |
|
1366 | 1366 | meta = { |
|
1367 | 1367 | license = [ pkgs.lib.licenses.mit { fullName = "DFSG approved"; } ]; |
@@ -1498,36 +1498,36 b'' | |||
|
1498 | 1498 | }; |
|
1499 | 1499 | }; |
|
1500 | 1500 | rhodecode-enterprise-ce = super.buildPythonPackage { |
|
1501 |
name = "rhodecode-enterprise-ce-4. |
|
|
1502 | buildInputs = with self; [WebTest configobj cssselect lxml mock pytest pytest-cov pytest-runner pytest-sugar]; | |
|
1501 | name = "rhodecode-enterprise-ce-4.6.0"; | |
|
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 | 1503 | doCheck = true; |
|
1504 | 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 | 1505 | src = ./.; |
|
1506 | 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 | 1510 | rhodecode-tools = super.buildPythonPackage { |
|
1511 |
name = "rhodecode-tools-0.10 |
|
|
1511 | name = "rhodecode-tools-0.11.0"; | |
|
1512 | 1512 | buildInputs = with self; []; |
|
1513 | 1513 | doCheck = false; |
|
1514 |
propagatedBuildInputs = with self; [click future six Mako MarkupSafe requests |
|
|
1514 | propagatedBuildInputs = with self; [click future six Mako MarkupSafe requests elasticsearch elasticsearch-dsl urllib3 Whoosh]; | |
|
1515 | 1515 | src = fetchurl { |
|
1516 |
url = "https://code.rhodecode.com/rhodecode-tools-ce/archive/v0.10. |
|
|
1517 | md5 = "d2af3985a1a32a678944d4d48870cb04"; | |
|
1516 | url = "https://code.rhodecode.com/rhodecode-tools-ce/archive/v0.11.0.tar.gz?md5=e5fd0a8363af08a0ced71b50ca9cce15"; | |
|
1517 | md5 = "e5fd0a8363af08a0ced71b50ca9cce15"; | |
|
1518 | 1518 | }; |
|
1519 | 1519 | meta = { |
|
1520 | 1520 | license = [ { fullName = "AGPLv3 and Proprietary"; } ]; |
|
1521 | 1521 | }; |
|
1522 | 1522 | }; |
|
1523 | 1523 | serpent = super.buildPythonPackage { |
|
1524 |
name = "serpent-1.1 |
|
|
1524 | name = "serpent-1.15"; | |
|
1525 | 1525 | buildInputs = with self; []; |
|
1526 | 1526 | doCheck = false; |
|
1527 | 1527 | propagatedBuildInputs = with self; []; |
|
1528 | 1528 | src = fetchurl { |
|
1529 |
url = "https://pypi.python.org/packages/ |
|
|
1530 | md5 = "05869ac7b062828b34f8f927f0457b65"; | |
|
1529 | url = "https://pypi.python.org/packages/7b/38/b2b27673a882ff2ea5871bb3e3e6b496ebbaafd1612e51990ffb158b9254/serpent-1.15.tar.gz"; | |
|
1530 | md5 = "e27b1aad5c218e16442f52abb7c7053a"; | |
|
1531 | 1531 | }; |
|
1532 | 1532 | meta = { |
|
1533 | 1533 | license = [ pkgs.lib.licenses.mit ]; |
@@ -1547,26 +1547,26 b'' | |||
|
1547 | 1547 | }; |
|
1548 | 1548 | }; |
|
1549 | 1549 | setuptools = super.buildPythonPackage { |
|
1550 |
name = "setuptools- |
|
|
1550 | name = "setuptools-30.1.0"; | |
|
1551 | 1551 | buildInputs = with self; []; |
|
1552 | 1552 | doCheck = false; |
|
1553 | 1553 | propagatedBuildInputs = with self; []; |
|
1554 | 1554 | src = fetchurl { |
|
1555 | url = "https://pypi.python.org/packages/c4/19/c1bdc88b53da654df43770f941079dbab4e4788c2dcb5658fb86259894c7/setuptools-20.8.1.zip"; | |
|
1556 | md5 = "fe58a5cac0df20bb83942b252a4b0543"; | |
|
1555 | url = "https://pypi.python.org/packages/1e/43/002c8616db9a3e7be23c2556e39b90a32bb40ba0dc652de1999d5334d372/setuptools-30.1.0.tar.gz"; | |
|
1556 | md5 = "cac497f42e5096ac8df29e38d3f81c3e"; | |
|
1557 | 1557 | }; |
|
1558 | 1558 | meta = { |
|
1559 | 1559 | license = [ pkgs.lib.licenses.mit ]; |
|
1560 | 1560 | }; |
|
1561 | 1561 | }; |
|
1562 | 1562 | setuptools-scm = super.buildPythonPackage { |
|
1563 |
name = "setuptools-scm-1.1 |
|
|
1563 | name = "setuptools-scm-1.15.0"; | |
|
1564 | 1564 | buildInputs = with self; []; |
|
1565 | 1565 | doCheck = false; |
|
1566 | 1566 | propagatedBuildInputs = with self; []; |
|
1567 | 1567 | src = fetchurl { |
|
1568 |
url = "https://pypi.python.org/packages/ |
|
|
1569 | md5 = "4c5c896ba52e134bbc3507bac6400087"; | |
|
1568 | url = "https://pypi.python.org/packages/80/b7/31b6ae5fcb188e37f7e31abe75f9be90490a5456a72860fa6e643f8a3cbc/setuptools_scm-1.15.0.tar.gz"; | |
|
1569 | md5 = "b6916c78ed6253d6602444fad4279c5b"; | |
|
1570 | 1570 | }; |
|
1571 | 1571 | meta = { |
|
1572 | 1572 | license = [ pkgs.lib.licenses.mit ]; |
@@ -1625,18 +1625,31 b'' | |||
|
1625 | 1625 | }; |
|
1626 | 1626 | }; |
|
1627 | 1627 | supervisor = super.buildPythonPackage { |
|
1628 |
name = "supervisor-3.3. |
|
|
1628 | name = "supervisor-3.3.1"; | |
|
1629 | 1629 | buildInputs = with self; []; |
|
1630 | 1630 | doCheck = false; |
|
1631 | 1631 | propagatedBuildInputs = with self; [meld3]; |
|
1632 | 1632 | src = fetchurl { |
|
1633 |
url = "https://pypi.python.org/packages/ |
|
|
1634 | md5 = "46bac00378d1eddb616752b990c67416"; | |
|
1633 | url = "https://pypi.python.org/packages/80/37/964c0d53cbd328796b1aeb7abea4c0f7b0e8c7197ea9b0b9967b7d004def/supervisor-3.3.1.tar.gz"; | |
|
1634 | md5 = "202f760f9bf4930ec06557bac73e5cf2"; | |
|
1635 | 1635 | }; |
|
1636 | 1636 | meta = { |
|
1637 | 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 | 1653 | traitlets = super.buildPythonPackage { |
|
1641 | 1654 | name = "traitlets-4.3.1"; |
|
1642 | 1655 | buildInputs = with self; []; |
@@ -1729,13 +1742,13 b'' | |||
|
1729 | 1742 | }; |
|
1730 | 1743 | }; |
|
1731 | 1744 | waitress = super.buildPythonPackage { |
|
1732 |
name = "waitress-0. |
|
|
1745 | name = "waitress-1.0.1"; | |
|
1733 | 1746 | buildInputs = with self; []; |
|
1734 | 1747 | doCheck = false; |
|
1735 |
propagatedBuildInputs = with self; [ |
|
|
1748 | propagatedBuildInputs = with self; []; | |
|
1736 | 1749 | src = fetchurl { |
|
1737 |
url = "https://pypi.python.org/packages/ |
|
|
1738 | md5 = "da3f2e62b3676be5dd630703a68e2a04"; | |
|
1750 | url = "https://pypi.python.org/packages/78/7d/84d11b96c3f60164dec3bef4a859a03aeae0231aa93f57fbe0d05fa4ff36/waitress-1.0.1.tar.gz"; | |
|
1751 | md5 = "dda92358a7569669086155923a46e57c"; | |
|
1739 | 1752 | }; |
|
1740 | 1753 | meta = { |
|
1741 | 1754 | license = [ pkgs.lib.licenses.zpt21 ]; |
@@ -1835,30 +1848,5 b'' | |||
|
1835 | 1848 | |
|
1836 | 1849 | ### Test requirements |
|
1837 | 1850 | |
|
1838 | pytest-sugar = super.buildPythonPackage { | |
|
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 | }; | |
|
1851 | ||
|
1864 | 1852 | } |
@@ -1,150 +1,131 b'' | |||
|
1 | Babel==1.3 | |
|
2 | Beaker==1.7.0 | |
|
3 | Chameleon==2.24 | |
|
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 | |
|
1 | ## core | |
|
2 | setuptools==30.1.0 | |
|
3 | setuptools-scm==1.15.0 | |
|
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 | 5 | amqplib==1.0.2 |
|
46 | 6 | anyjson==0.3.3 |
|
47 | appenlight-client==0.6.14 | |
|
48 | authomatic==0.1.0.post1; | |
|
7 | authomatic==0.1.0.post1 | |
|
8 | Babel==1.3 | |
|
49 | 9 | backport-ipaddress==0.1 |
|
50 | bottle==0.12.8 | |
|
51 | bumpversion==0.5.3 | |
|
10 | Beaker==1.7.0 | |
|
52 | 11 | celery==2.2.10 |
|
12 | Chameleon==2.24 | |
|
53 | 13 | channelstream==0.5.2 |
|
54 | 14 | click==5.1 |
|
55 | 15 | colander==1.2 |
|
56 | 16 | configobj==5.0.6 |
|
57 | cov-core==1.15.0 | |
|
58 | coverage==3.7.1 | |
|
59 | cssselect==0.9.1 | |
|
60 | 17 | decorator==3.4.2 |
|
61 | 18 | deform==2.0a2 |
|
62 | 19 | docutils==0.12 |
|
63 | 20 | dogpile.cache==0.6.1 |
|
64 | 21 | dogpile.core==0.4.1 |
|
65 | dulwich==0.12.0 | |
|
66 | 22 | ecdsa==0.11 |
|
23 | FormEncode==1.2.4 | |
|
67 | 24 | future==0.14.3 |
|
68 | 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 | 26 | gnureadline==6.3.3 |
|
79 | 27 | infrae.cache==1.0.1 |
|
80 | invoke==0.13.0 | |
|
81 | ipdb==0.10.1 | |
|
82 | ipython==5.1.0 | |
|
83 | 28 | iso8601==0.1.11 |
|
84 | 29 | itsdangerous==0.24 |
|
30 | Jinja2==2.7.3 | |
|
85 | 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 | 35 | meld3==1.0.2 |
|
88 | mock==1.0.1 | |
|
89 | msgpack-python==0.4.6 | |
|
36 | msgpack-python==0.4.8 | |
|
37 | MySQL-python==1.2.5 | |
|
90 | 38 | nose==1.3.6 |
|
91 | 39 | objgraph==2.0.0 |
|
92 | 40 | packaging==15.2 |
|
93 | 41 | paramiko==1.15.1 |
|
42 | Paste==2.0.3 | |
|
43 | PasteDeploy==1.5.2 | |
|
44 | PasteScript==1.7.5 | |
|
94 | 45 | psutil==4.3.1 |
|
95 | 46 | psycopg2==2.6.1 |
|
96 | py==1.4.29 | |
|
97 | 47 | py-bcrypt==0.4 |
|
98 | py-gfm==0.1.3 | |
|
99 | 48 | pycrypto==2.6.1 |
|
100 | 49 | pycurl==7.19.5 |
|
101 | 50 | pyflakes==0.8.1 |
|
51 | pygments-markdown-lexer==0.1.0.dev39 | |
|
52 | Pygments==2.2.0 | |
|
102 | 53 | pyparsing==1.5.7 |
|
103 | pyramid==1.6.1 | |
|
104 | 54 | pyramid-beaker==0.8 |
|
105 | 55 | pyramid-debugtoolbar==2.4.2 |
|
106 | 56 | pyramid-jinja2==2.5 |
|
107 | 57 | pyramid-mako==1.0.2 |
|
58 | pyramid==1.6.1 | |
|
108 | 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 | 60 | python-dateutil==1.5 |
|
116 | 61 | python-ldap==2.4.19 |
|
117 | 62 | python-memcached==1.57 |
|
118 | 63 | python-pam==1.8.2 |
|
119 | 64 | pytz==2015.4 |
|
120 | 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 | 66 | recaptcha-client==1.0.6 |
|
129 | 67 | repoze.lru==0.6 |
|
130 | 68 | requests==2.9.1 |
|
131 | serpent==1.12 | |
|
69 | Routes==1.13 | |
|
132 | 70 | setproctitle==1.1.8 |
|
133 | setuptools==20.8.1 | |
|
134 | setuptools-scm==1.11.0 | |
|
135 | 71 | simplejson==3.7.2 |
|
136 | 72 | six==1.9.0 |
|
73 | Sphinx==1.2.2 | |
|
74 | SQLAlchemy==0.9.9 | |
|
137 | 75 | subprocess32==3.2.6 |
|
138 |
supervisor==3.3. |
|
|
139 | transifex-client==0.10 | |
|
76 | supervisor==3.3.1 | |
|
77 | Tempita==0.5.2 | |
|
140 | 78 | translationstring==1.3 |
|
141 | 79 | trollius==1.0.4 |
|
142 | uWSGI==2.0.11.2 | |
|
143 | 80 | urllib3==1.16 |
|
81 | URLObject==2.4.0 | |
|
144 | 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 | 88 | wsgiref==0.1.2 |
|
147 | 89 | zope.cachedescriptors==4.0.0 |
|
148 | 90 | zope.deprecation==4.1.2 |
|
149 | 91 | zope.event==4.0.3 |
|
150 | 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,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -51,11 +51,11 b' PYRAMID_SETTINGS = {}' | |||
|
51 | 51 | EXTENSIONS = {} |
|
52 | 52 | |
|
53 | 53 | __version__ = ('.'.join((str(each) for each in VERSION[:3]))) |
|
54 |
__dbversion__ = 6 |
|
|
54 | __dbversion__ = 64 # defines current db version for migrations | |
|
55 | 55 | __platform__ = platform.system() |
|
56 | 56 | __license__ = 'AGPLv3, and Commercial License' |
|
57 | 57 | __author__ = 'RhodeCode GmbH' |
|
58 | __url__ = 'http://rhodecode.com' | |
|
58 | __url__ = 'https://code.rhodecode.com' | |
|
59 | 59 | |
|
60 | 60 | is_windows = __platform__ in ['Windows'] |
|
61 | 61 | is_unix = not is_windows |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -39,5 +39,19 b' def includeme(config):' | |||
|
39 | 39 | name='admin_settings_vcs_svn_generate_cfg', |
|
40 | 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 | 56 | # Scan module for configuration decorators. |
|
43 | 57 | config.scan() |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -66,6 +66,15 b' class NavEntry(object):' | |||
|
66 | 66 | else: |
|
67 | 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 | 79 | @implementer(IAdminNavigationRegistry) |
|
71 | 80 | class NavigationRegistry(object): |
@@ -80,18 +89,22 b' class NavigationRegistry(object):' | |||
|
80 | 89 | NavEntry('email', _('Email'), 'admin_settings_email'), |
|
81 | 90 | NavEntry('hooks', _('Hooks'), 'admin_settings_hooks'), |
|
82 | 91 | NavEntry('search', _('Full Text Search'), 'admin_settings_search'), |
|
92 | ||
|
83 | 93 | NavEntry('integrations', _('Integrations'), |
|
84 | 94 | 'global_integrations_home', pyramid=True), |
|
85 |
NavEntry('system', _('System Info'), |
|
|
95 | NavEntry('system', _('System Info'), | |
|
96 | 'admin_settings_system', pyramid=True), | |
|
97 | NavEntry('sessions', _('User Sessions'), | |
|
98 | 'admin_settings_sessions', pyramid=True), | |
|
86 | 99 | NavEntry('open_source', _('Open Source Licenses'), |
|
87 | 100 | 'admin_settings_open_source', pyramid=True), |
|
101 | ||
|
88 | 102 | # TODO: marcink: we disable supervisor now until the supervisor stats |
|
89 | 103 | # page is fixed in the nix configuration |
|
90 | 104 | # NavEntry('supervisor', _('Supervisor'), 'admin_settings_supervisor'), |
|
91 | 105 | ] |
|
92 | 106 | |
|
93 | _labs_entry = NavEntry('labs', _('Labs'), | |
|
94 | 'admin_settings_labs') | |
|
107 | _labs_entry = NavEntry('labs', _('Labs'), 'admin_settings_labs') | |
|
95 | 108 | |
|
96 | 109 | def __init__(self, labs_active=False): |
|
97 | 110 | self._registered_entries = collections.OrderedDict([ |
@@ -105,7 +118,8 b' class NavigationRegistry(object):' | |||
|
105 | 118 | self._registered_entries[entry.key] = entry |
|
106 | 119 | |
|
107 | 120 | def get_navlist(self, request): |
|
108 |
navlist = [NavListEntry(i.key, i. |
|
|
121 | navlist = [NavListEntry(i.key, i.get_localized_name(request), | |
|
122 | i.generate_url(request)) | |
|
109 | 123 | for i in self._registered_entries.values()] |
|
110 | 124 | return navlist |
|
111 | 125 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -132,7 +132,7 b' def exception_view(exc, request):' | |||
|
132 | 132 | log.debug('json-rpc error rpc_id:%s "%s"', rpc_id, fault_message) |
|
133 | 133 | elif isinstance(exc, JSONRPCValidationError): |
|
134 | 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 | 136 | fault_message = colander_exc.asdict() |
|
137 | 137 | log.debug('json-rpc error rpc_id:%s "%s"', rpc_id, fault_message) |
|
138 | 138 | elif isinstance(exc, JSONRPCForbidden): |
@@ -240,7 +240,7 b' def request_view(request):' | |||
|
240 | 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 | 244 | for k in request.rpc_params.keys()[:]: |
|
245 | 245 | if k not in func_kwargs: |
|
246 | 246 | del request.rpc_params[k] |
@@ -256,7 +256,7 b' def request_view(request):' | |||
|
256 | 256 | except JSONRPCBaseError: |
|
257 | 257 | raise |
|
258 | 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 | 260 | return jsonrpc_error(request, retid=request.rpc_id, |
|
261 | 261 | message='Internal server error') |
|
262 | 262 | |
@@ -269,9 +269,10 b' def setup_request(request):' | |||
|
269 | 269 | We need to raise JSONRPCError here if we want to return some errors back to |
|
270 | 270 | user. |
|
271 | 271 | """ |
|
272 | ||
|
272 | 273 | log.debug('Executing setup request: %r', request) |
|
273 | 274 | request.rpc_ip_addr = get_ip_addr(request.environ) |
|
274 |
# TODO |
|
|
275 | # TODO(marcink): deprecate GET at some point | |
|
275 | 276 | if request.method not in ['POST', 'GET']: |
|
276 | 277 | log.debug('unsupported request method "%s"', request.method) |
|
277 | 278 | raise JSONRPCError( |
@@ -308,6 +309,8 b' def setup_request(request):' | |||
|
308 | 309 | if not api_key: |
|
309 | 310 | raise KeyError('api_key or auth_token') |
|
310 | 311 | |
|
312 | # TODO(marcink): support passing in token in request header | |
|
313 | ||
|
311 | 314 | request.rpc_api_key = api_key |
|
312 | 315 | request.rpc_id = json_body['id'] |
|
313 | 316 | request.rpc_method = json_body['method'] |
@@ -485,8 +488,7 b' def includeme(config):' | |||
|
485 | 488 | config.registry.jsonrpc_methods = OrderedDict() |
|
486 | 489 | |
|
487 | 490 | # match filter by given method only |
|
488 | config.add_view_predicate( | |
|
489 | 'jsonrpc_method', MethodPredicate) | |
|
491 | config.add_view_predicate('jsonrpc_method', MethodPredicate) | |
|
490 | 492 | |
|
491 | 493 | config.add_renderer(DEFAULT_RENDERER, ExtJsonRenderer( |
|
492 | 494 | serializer=json.dumps, indent=4)) |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -20,7 +20,7 b'' | |||
|
20 | 20 | |
|
21 | 21 | import pytest |
|
22 | 22 | |
|
23 |
from rhodecode.model.comment import |
|
|
23 | from rhodecode.model.comment import CommentsModel | |
|
24 | 24 | from rhodecode.model.db import UserLog |
|
25 | 25 | from rhodecode.model.pull_request import PullRequestModel |
|
26 | 26 | from rhodecode.tests import TEST_USER_ADMIN_LOGIN |
@@ -52,13 +52,13 b' class TestCommentPullRequest(object):' | |||
|
52 | 52 | response = api_call(self.app, params) |
|
53 | 53 | pull_request = PullRequestModel().get(pull_request.pull_request_id) |
|
54 | 54 | |
|
55 |
comments = |
|
|
55 | comments = CommentsModel().get_comments( | |
|
56 | 56 | pull_request.target_repo.repo_id, pull_request=pull_request) |
|
57 | 57 | |
|
58 | 58 | expected = { |
|
59 | 59 | 'pull_request_id': pull_request.pull_request_id, |
|
60 | 60 | 'comment_id': comments[-1].comment_id, |
|
61 | 'status': None | |
|
61 | 'status': {'given': None, 'was_changed': None} | |
|
62 | 62 | } |
|
63 | 63 | assert_ok(id_, expected, response.body) |
|
64 | 64 | |
@@ -83,12 +83,61 b' class TestCommentPullRequest(object):' | |||
|
83 | 83 | response = api_call(self.app, params) |
|
84 | 84 | pull_request = PullRequestModel().get(pull_request_id) |
|
85 | 85 | |
|
86 |
comments = |
|
|
86 | comments = CommentsModel().get_comments( | |
|
87 | 87 | pull_request.target_repo.repo_id, pull_request=pull_request) |
|
88 | 88 | expected = { |
|
89 | 89 | 'pull_request_id': pull_request.pull_request_id, |
|
90 | 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 | 142 | assert_ok(id_, expected, response.body) |
|
94 | 143 | |
@@ -103,7 +152,7 b' class TestCommentPullRequest(object):' | |||
|
103 | 152 | pullrequestid=pull_request_id) |
|
104 | 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 | 156 | assert_error(id_, expected, given=response.body) |
|
108 | 157 | |
|
109 | 158 | @pytest.mark.backends("git", "hg") |
@@ -118,7 +167,7 b' class TestCommentPullRequest(object):' | |||
|
118 | 167 | status='42') |
|
119 | 168 | response = api_call(self.app, params) |
|
120 | 169 | |
|
121 |
expected = ' |
|
|
170 | expected = 'Unknown comment status: `42`' | |
|
122 | 171 | assert_error(id_, expected, given=response.body) |
|
123 | 172 | |
|
124 | 173 | @pytest.mark.backends("git", "hg") |
@@ -144,3 +193,17 b' class TestCommentPullRequest(object):' | |||
|
144 | 193 | |
|
145 | 194 | expected = 'userid is not the same as your user' |
|
146 | 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 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -22,7 +22,8 b'' | |||
|
22 | 22 | import pytest |
|
23 | 23 | |
|
24 | 24 | from rhodecode.model.repo import RepoModel |
|
25 |
from rhodecode.api.tests.utils import |
|
|
25 | from rhodecode.api.tests.utils import ( | |
|
26 | build_data, api_call, assert_ok, assert_error, jsonify) | |
|
26 | 27 | from rhodecode.model.db import User |
|
27 | 28 | |
|
28 | 29 | |
@@ -40,6 +41,76 b' class TestGetRepos(object):' | |||
|
40 | 41 | expected = ret |
|
41 | 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 | 114 | def test_api_get_repos_non_admin(self): |
|
44 | 115 | id_, params = build_data(self.apikey_regular, 'get_repos') |
|
45 | 116 | response = api_call(self.app, params) |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -20,18 +20,17 b'' | |||
|
20 | 20 | |
|
21 | 21 | import pytest |
|
22 | 22 | |
|
23 | from rhodecode.model.db import UserLog | |
|
23 | from rhodecode.model.db import UserLog, PullRequest | |
|
24 | 24 | from rhodecode.model.meta import Session |
|
25 | from rhodecode.model.pull_request import PullRequestModel | |
|
26 | 25 | from rhodecode.tests import TEST_USER_ADMIN_LOGIN |
|
27 | 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 | 30 | @pytest.mark.usefixtures("testuser_api", "app") |
|
32 | 31 | class TestMergePullRequest(object): |
|
33 | 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 | 34 | pull_request = pr_util.create_pull_request(mergeable=True) |
|
36 | 35 | author = pull_request.user_id |
|
37 | 36 | repo = pull_request.target_repo.repo_id |
@@ -51,6 +50,41 b' class TestMergePullRequest(object):' | |||
|
51 | 50 | # it. |
|
52 | 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 | 88 | expected = { |
|
55 | 89 | 'executed': True, |
|
56 | 90 | 'failure_reason': 0, |
@@ -59,8 +93,7 b' class TestMergePullRequest(object):' | |||
|
59 | 93 | 'merge_ref': pull_request.shadow_merge_ref._asdict() |
|
60 | 94 | } |
|
61 | 95 | |
|
62 | response_json = response.json['result'] | |
|
63 | assert response_json == expected | |
|
96 | assert_ok(id_, expected, response.body) | |
|
64 | 97 | |
|
65 | 98 | action = 'user_merged_pull_request:%d' % (pull_request_id, ) |
|
66 | 99 | journal = UserLog.query()\ |
@@ -75,8 +108,7 b' class TestMergePullRequest(object):' | |||
|
75 | 108 | repoid=pull_request_repo, pullrequestid=pull_request_id) |
|
76 | 109 | response = api_call(self.app, params) |
|
77 | 110 | |
|
78 |
expected = ' |
|
|
79 | pull_request_id) | |
|
111 | expected = 'merge not possible for following reasons: This pull request is closed.' | |
|
80 | 112 | assert_error(id_, expected, given=response.body) |
|
81 | 113 | |
|
82 | 114 | @pytest.mark.backends("git", "hg") |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -24,7 +24,8 b' from rhodecode.lib.vcs.nodes import File' | |||
|
24 | 24 | from rhodecode.model.db import User |
|
25 | 25 | from rhodecode.model.pull_request import PullRequestModel |
|
26 | 26 | from rhodecode.tests import TEST_USER_ADMIN_LOGIN |
|
27 |
from rhodecode.api.tests.utils import ( |
|
|
27 | from rhodecode.api.tests.utils import ( | |
|
28 | build_data, api_call, assert_ok, assert_error) | |
|
28 | 29 | |
|
29 | 30 | |
|
30 | 31 | @pytest.mark.usefixtures("testuser_api", "app") |
@@ -74,8 +75,7 b' class TestUpdatePullRequest(object):' | |||
|
74 | 75 | expected = 'pull request `{}` update failed, pull request ' \ |
|
75 | 76 | 'is closed'.format(pull_request.pull_request_id) |
|
76 | 77 | |
|
77 | response_json = response.json['error'] | |
|
78 | assert response_json == expected | |
|
78 | assert_error(id_, expected, response.body) | |
|
79 | 79 | |
|
80 | 80 | @pytest.mark.backends("git", "hg") |
|
81 | 81 | def test_api_update_update_commits( |
@@ -90,9 +90,11 b' class TestUpdatePullRequest(object):' | |||
|
90 | 90 | pr_util.update_source_repository(head='c') |
|
91 | 91 | repo = pull_request.source_repo.scm_instance() |
|
92 | 92 | commits = [x for x in repo.get_commits()] |
|
93 | print commits | |
|
93 | 94 | |
|
94 | 95 | added_commit_id = commits[-1].raw_id # c commit |
|
95 |
common_commit |
|
|
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 | 99 | id_, params = build_data( |
|
98 | 100 | self.apikey, 'update_pull_request', |
@@ -107,12 +109,13 b' class TestUpdatePullRequest(object):' | |||
|
107 | 109 | pull_request.pull_request_id), |
|
108 | 110 | "pull_request": response.json['result']['pull_request'], |
|
109 | 111 | "updated_commits": {"added": [added_commit_id], |
|
110 |
"common": [common_commit |
|
|
112 | "common": [common_commit_id], | |
|
113 | "total": total_commits, | |
|
114 | "removed": []}, | |
|
111 | 115 | "updated_reviewers": {"added": [], "removed": []}, |
|
112 | 116 | } |
|
113 | 117 | |
|
114 | response_json = response.json['result'] | |
|
115 | assert response_json == expected | |
|
118 | assert_ok(id_, expected, response.body) | |
|
116 | 119 | |
|
117 | 120 | @pytest.mark.backends("git", "hg") |
|
118 | 121 | def test_api_update_change_reviewers( |
@@ -139,8 +142,7 b' class TestUpdatePullRequest(object):' | |||
|
139 | 142 | "updated_reviewers": {"added": added, "removed": removed}, |
|
140 | 143 | } |
|
141 | 144 | |
|
142 | response_json = response.json['result'] | |
|
143 | assert response_json == expected | |
|
145 | assert_ok(id_, expected, response.body) | |
|
144 | 146 | |
|
145 | 147 | @pytest.mark.backends("git", "hg") |
|
146 | 148 | def test_api_update_bad_user_in_reviewers(self, pr_util): |
@@ -155,8 +157,7 b' class TestUpdatePullRequest(object):' | |||
|
155 | 157 | |
|
156 | 158 | expected = 'user `bad_name` does not exist' |
|
157 | 159 | |
|
158 | response_json = response.json['error'] | |
|
159 | assert response_json == expected | |
|
160 | assert_error(id_, expected, response.body) | |
|
160 | 161 | |
|
161 | 162 | @pytest.mark.backends("git", "hg") |
|
162 | 163 | def test_api_update_repo_error(self, pr_util): |
@@ -184,9 +185,7 b' class TestUpdatePullRequest(object):' | |||
|
184 | 185 | response = api_call(self.app, params) |
|
185 | 186 | |
|
186 | 187 | expected = 'pull request `999999` does not exist' |
|
187 | ||
|
188 | response_json = response.json['error'] | |
|
189 | assert response_json == expected | |
|
188 | assert_error(id_, expected, response.body) | |
|
190 | 189 | |
|
191 | 190 | @pytest.mark.backends("git", "hg") |
|
192 | 191 | def test_api_update_pull_request_no_perms_to_update( |
@@ -203,5 +202,4 b' class TestUpdatePullRequest(object):' | |||
|
203 | 202 | expected = ('pull request `%s` update failed, ' |
|
204 | 203 | 'no permission to update.') % pull_request.pull_request_id |
|
205 | 204 | |
|
206 | response_json = response.json['error'] | |
|
207 | assert response_json == expected | |
|
205 | assert_error(id_, expected, response.body) |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2014-201 |
|
|
3 | # Copyright (C) 2014-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -26,11 +26,12 b' import collections' | |||
|
26 | 26 | import logging |
|
27 | 27 | |
|
28 | 28 | from rhodecode.api.exc import JSONRPCError |
|
29 | from rhodecode.lib.auth import HasPermissionAnyApi, HasRepoPermissionAnyApi, \ | |
|
30 | HasRepoGroupPermissionAnyApi | |
|
29 | from rhodecode.lib.auth import ( | |
|
30 | HasPermissionAnyApi, HasRepoPermissionAnyApi, HasRepoGroupPermissionAnyApi) | |
|
31 | 31 | from rhodecode.lib.utils import safe_unicode |
|
32 | from rhodecode.lib.vcs.exceptions import RepositoryError | |
|
32 | 33 | from rhodecode.controllers.utils import get_commit_from_ref_name |
|
33 |
from rhodecode.lib. |
|
|
34 | from rhodecode.lib.utils2 import str2bool | |
|
34 | 35 | |
|
35 | 36 | log = logging.getLogger(__name__) |
|
36 | 37 | |
@@ -92,7 +93,7 b' class Optional(object):' | |||
|
92 | 93 | return self.type_ |
|
93 | 94 | |
|
94 | 95 | @classmethod |
|
95 | def extract(cls, val, evaluate_locals=None): | |
|
96 | def extract(cls, val, evaluate_locals=None, binary=None): | |
|
96 | 97 | """ |
|
97 | 98 | Extracts value from Optional() instance |
|
98 | 99 | |
@@ -101,7 +102,11 b' class Optional(object):' | |||
|
101 | 102 | value of instance |
|
102 | 103 | """ |
|
103 | 104 | if isinstance(val, cls): |
|
104 |
|
|
|
105 | val = val.getval(evaluate_locals) | |
|
106 | ||
|
107 | if binary: | |
|
108 | val = str2bool(val) | |
|
109 | ||
|
105 | 110 | return val |
|
106 | 111 | |
|
107 | 112 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2015-201 |
|
|
3 | # Copyright (C) 2015-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -30,9 +30,9 b' from rhodecode.lib.auth import (HasRepoP' | |||
|
30 | 30 | from rhodecode.lib.base import vcs_operation_context |
|
31 | 31 | from rhodecode.lib.utils2 import str2bool |
|
32 | 32 | from rhodecode.model.changeset_status import ChangesetStatusModel |
|
33 |
from rhodecode.model.comment import |
|
|
34 | from rhodecode.model.db import Session, ChangesetStatus | |
|
35 | from rhodecode.model.pull_request import PullRequestModel | |
|
33 | from rhodecode.model.comment import CommentsModel | |
|
34 | from rhodecode.model.db import Session, ChangesetStatus, ChangesetComment | |
|
35 | from rhodecode.model.pull_request import PullRequestModel, MergeCheck | |
|
36 | 36 | from rhodecode.model.settings import SettingsModel |
|
37 | 37 | |
|
38 | 38 | log = logging.getLogger(__name__) |
@@ -270,13 +270,14 b' def merge_pull_request(request, apiuser,' | |||
|
270 | 270 | raise JSONRPCError('userid is not the same as your user') |
|
271 | 271 | |
|
272 | 272 | pull_request = get_pull_request_or_error(pullrequestid) |
|
273 | if not PullRequestModel().check_user_merge( | |
|
274 | pull_request, apiuser, api=True): | |
|
275 | raise JSONRPCError('repository `%s` does not exist' % (repoid,)) | |
|
276 | if pull_request.is_closed(): | |
|
273 | ||
|
274 | check = MergeCheck.validate(pull_request, user=apiuser) | |
|
275 | merge_possible = not check.failed | |
|
276 | ||
|
277 | if not merge_possible: | |
|
278 | reasons = ','.join([msg for _e, msg in check.errors]) | |
|
277 | 279 | raise JSONRPCError( |
|
278 | 'pull request `%s` merge failed, pull request is closed' % ( | |
|
279 | pullrequestid,)) | |
|
280 | 'merge not possible for following reasons: {}'.format(reasons)) | |
|
280 | 281 | |
|
281 | 282 | target_repo = pull_request.target_repo |
|
282 | 283 | extras = vcs_operation_context( |
@@ -359,9 +360,12 b' def close_pull_request(request, apiuser,' | |||
|
359 | 360 | |
|
360 | 361 | |
|
361 | 362 | @jsonrpc_method() |
|
362 | def comment_pull_request(request, apiuser, repoid, pullrequestid, | |
|
363 | message=Optional(None), status=Optional(None), | |
|
364 | userid=Optional(OAttr('apiuser'))): | |
|
363 | def comment_pull_request( | |
|
364 | request, apiuser, repoid, pullrequestid, message=Optional(None), | |
|
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 | 370 | Comment on the pull request specified with the `pullrequestid`, |
|
367 | 371 | in the |repo| specified by the `repoid`, and optionally change the |
@@ -373,15 +377,18 b' def comment_pull_request(request, apiuse' | |||
|
373 | 377 | :type repoid: str or int |
|
374 | 378 | :param pullrequestid: The pull request ID. |
|
375 | 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 | 384 | :param message: The text content of the comment. |
|
377 | 385 | :type message: str |
|
378 | 386 | :param status: (**Optional**) Set the approval status of the pull |
|
379 | request. Valid options are: | |
|
380 |
|
|
|
381 | * approved | |
|
382 | * rejected | |
|
383 | * under_review | |
|
387 | request. One of: 'not_reviewed', 'approved', 'rejected', | |
|
388 | 'under_review' | |
|
384 | 389 | :type status: str |
|
390 | :param comment_type: Comment type, one of: 'note', 'todo' | |
|
391 | :type comment_type: Optional(str), default: 'note' | |
|
385 | 392 | :param userid: Comment on the pull request as this user |
|
386 | 393 | :type userid: Optional(str or int) |
|
387 | 394 | |
@@ -393,7 +400,9 b' def comment_pull_request(request, apiuse' | |||
|
393 | 400 | result : |
|
394 | 401 | { |
|
395 | 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 | 407 | error : null |
|
399 | 408 | """ |
@@ -412,37 +421,68 b' def comment_pull_request(request, apiuse' | |||
|
412 | 421 | raise JSONRPCError('repository `%s` does not exist' % (repoid,)) |
|
413 | 422 | message = Optional.extract(message) |
|
414 | 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 | 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 | 433 | if (status not in (st[0] for st in ChangesetStatus.STATUSES) and |
|
419 | 434 | status is not None): |
|
420 |
raise JSONRPCError(' |
|
|
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 | 441 | allowed_to_change_status = PullRequestModel().check_user_change_status( |
|
423 | 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 | 462 | text = message |
|
463 | status_label = ChangesetStatus.get_status_lbl(status) | |
|
425 | 464 | if status and allowed_to_change_status: |
|
426 |
st_message = ( |
|
|
427 | % {'transition_icon': '>', | |
|
428 | 'status': ChangesetStatus.get_status_lbl(status)}) | |
|
465 | st_message = ('Status change %(transition_icon)s %(status)s' | |
|
466 | % {'transition_icon': '>', 'status': status_label}) | |
|
429 | 467 | text = message or st_message |
|
430 | 468 | |
|
431 | 469 | rc_config = SettingsModel().get_all_settings() |
|
432 | 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 | 474 | text=text, |
|
435 | 475 | repo=pull_request.target_repo.repo_id, |
|
436 | 476 | user=apiuser.user_id, |
|
437 | 477 | pull_request=pull_request.pull_request_id, |
|
438 | 478 | f_path=None, |
|
439 | 479 | line_no=None, |
|
440 |
status_change=( |
|
|
441 | if status and allowed_to_change_status else None), | |
|
442 | status_change_type=(status | |
|
443 | if status and allowed_to_change_status else None), | |
|
480 | status_change=(status_label if status_change else None), | |
|
481 | status_change_type=(status if status_change else None), | |
|
444 | 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 | 488 | if allowed_to_change_status and status: |
@@ -458,8 +498,8 b' def comment_pull_request(request, apiuse' | |||
|
458 | 498 | Session().commit() |
|
459 | 499 | data = { |
|
460 | 500 | 'pull_request_id': pull_request.pull_request_id, |
|
461 | 'comment_id': comment.comment_id, | |
|
462 | 'status': status | |
|
501 | 'comment_id': comment.comment_id if comment else None, | |
|
502 | 'status': {'given': status, 'was_changed': status_change}, | |
|
463 | 503 | } |
|
464 | 504 | return data |
|
465 | 505 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -34,9 +34,10 b' from rhodecode.lib.exceptions import Sta' | |||
|
34 | 34 | from rhodecode.lib.utils2 import str2bool, time_to_datetime |
|
35 | 35 | from rhodecode.lib.ext_json import json |
|
36 | 36 | from rhodecode.model.changeset_status import ChangesetStatusModel |
|
37 |
from rhodecode.model.comment import |
|
|
37 | from rhodecode.model.comment import CommentsModel | |
|
38 | 38 | from rhodecode.model.db import ( |
|
39 |
Session, ChangesetStatus, RepositoryField, Repository |
|
|
39 | Session, ChangesetStatus, RepositoryField, Repository, RepoGroup, | |
|
40 | ChangesetComment) | |
|
40 | 41 | from rhodecode.model.repo import RepoModel |
|
41 | 42 | from rhodecode.model.scm import ScmModel, RepoList |
|
42 | 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 | 220 | @jsonrpc_method() |
|
220 | def get_repos(request, apiuser): | |
|
221 | def get_repos(request, apiuser, root=Optional(None), traverse=Optional(True)): | |
|
221 | 222 | """ |
|
222 | 223 | Lists all existing repositories. |
|
223 | 224 | |
@@ -226,6 +227,14 b' def get_repos(request, apiuser):' | |||
|
226 | 227 | |
|
227 | 228 | :param apiuser: This is filled automatically from the |authtoken|. |
|
228 | 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 | 239 | Example output: |
|
231 | 240 | |
@@ -257,8 +266,28 b' def get_repos(request, apiuser):' | |||
|
257 | 266 | _perms = ('repository.read', 'repository.write', 'repository.admin',) |
|
258 | 267 | extras = {'user': apiuser} |
|
259 | 268 | |
|
260 | repo_list = RepoList( | |
|
261 | RepoModel().get_all(), perm_set=_perms, extra_kwargs=extras) | |
|
269 | root = Optional.extract(root) | |
|
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 | 291 | return [repo.get_api_data(include_secrets=include_secrets) |
|
263 | 292 | for repo in repo_list] |
|
264 | 293 | |
@@ -1354,8 +1383,10 b' def lock(request, apiuser, repoid, locke' | |||
|
1354 | 1383 | |
|
1355 | 1384 | @jsonrpc_method() |
|
1356 | 1385 | def comment_commit( |
|
1357 | request, apiuser, repoid, commit_id, message, | |
|
1358 | userid=Optional(OAttr('apiuser')), status=Optional(None)): | |
|
1386 | request, apiuser, repoid, commit_id, message, 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 | 1391 | Set a commit comment, and optionally change the status of the commit. |
|
1361 | 1392 | |
@@ -1367,15 +1398,17 b' def comment_commit(' | |||
|
1367 | 1398 | :type commit_id: str |
|
1368 | 1399 | :param message: The comment text. |
|
1369 | 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 | 1406 | :param userid: Set the user name of the comment creator. |
|
1371 | 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 | 1409 | Example error output: |
|
1377 | 1410 | |
|
1378 |
.. code-block:: |
|
|
1411 | .. code-block:: bash | |
|
1379 | 1412 | |
|
1380 | 1413 | { |
|
1381 | 1414 | "id" : <id_given_in_input>, |
@@ -1398,21 +1431,37 b' def comment_commit(' | |||
|
1398 | 1431 | |
|
1399 | 1432 | user = get_user_or_error(userid) |
|
1400 | 1433 | status = Optional.extract(status) |
|
1434 | comment_type = Optional.extract(comment_type) | |
|
1435 | resolves_comment_id = Optional.extract(resolves_comment_id) | |
|
1401 | 1436 | |
|
1402 | 1437 | allowed_statuses = [x[0] for x in ChangesetStatus.STATUSES] |
|
1403 | 1438 | if status and status not in allowed_statuses: |
|
1404 | 1439 | raise JSONRPCError('Bad status, must be on ' |
|
1405 | 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 | 1453 | try: |
|
1408 | 1454 | rc_config = SettingsModel().get_all_settings() |
|
1409 | 1455 | renderer = rc_config.get('rhodecode_markup_renderer', 'rst') |
|
1410 | 1456 | status_change_label = ChangesetStatus.get_status_lbl(status) |
|
1411 |
comm = |
|
|
1412 |
message, repo, user, |
|
|
1457 | comm = CommentsModel().create( | |
|
1458 | message, repo, user, commit_id=commit_id, | |
|
1413 | 1459 | status_change=status_change_label, |
|
1414 | 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 | 1465 | if status: |
|
1417 | 1466 | # also do a status change |
|
1418 | 1467 | try: |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -26,6 +26,8 b' from rhodecode.api import jsonrpc_method' | |||
|
26 | 26 | from rhodecode.api.utils import ( |
|
27 | 27 | Optional, OAttr, has_superadmin_permission, get_user_or_error) |
|
28 | 28 | from rhodecode.lib.utils import repo2db_mapper |
|
29 | from rhodecode.lib import system_info | |
|
30 | from rhodecode.lib import user_sessions | |
|
29 | 31 | from rhodecode.model.db import UserIpMap |
|
30 | 32 | from rhodecode.model.scm import ScmModel |
|
31 | 33 | |
@@ -176,3 +178,67 b' def rescan_repos(request, apiuser, remov' | |||
|
176 | 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 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2012-201 |
|
|
3 | # Copyright (C) 2012-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2012-201 |
|
|
3 | # Copyright (C) 2012-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2012-201 |
|
|
3 | # Copyright (C) 2012-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -197,14 +197,14 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||
|
197 | 197 | config.add_view( |
|
198 | 198 | 'rhodecode.authentication.views.AuthnPluginViewBase', |
|
199 | 199 | attr='settings_get', |
|
200 |
renderer='rhodecode:templates/admin/auth/plugin_settings. |
|
|
200 | renderer='rhodecode:templates/admin/auth/plugin_settings.mako', | |
|
201 | 201 | request_method='GET', |
|
202 | 202 | route_name='auth_home', |
|
203 | 203 | context=CrowdAuthnResource) |
|
204 | 204 | config.add_view( |
|
205 | 205 | 'rhodecode.authentication.views.AuthnPluginViewBase', |
|
206 | 206 | attr='settings_post', |
|
207 |
renderer='rhodecode:templates/admin/auth/plugin_settings. |
|
|
207 | renderer='rhodecode:templates/admin/auth/plugin_settings.mako', | |
|
208 | 208 | request_method='POST', |
|
209 | 209 | route_name='auth_home', |
|
210 | 210 | context=CrowdAuthnResource) |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2012-201 |
|
|
3 | # Copyright (C) 2012-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -83,14 +83,14 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||
|
83 | 83 | config.add_view( |
|
84 | 84 | 'rhodecode.authentication.views.AuthnPluginViewBase', |
|
85 | 85 | attr='settings_get', |
|
86 |
renderer='rhodecode:templates/admin/auth/plugin_settings. |
|
|
86 | renderer='rhodecode:templates/admin/auth/plugin_settings.mako', | |
|
87 | 87 | request_method='GET', |
|
88 | 88 | route_name='auth_home', |
|
89 | 89 | context=HeadersAuthnResource) |
|
90 | 90 | config.add_view( |
|
91 | 91 | 'rhodecode.authentication.views.AuthnPluginViewBase', |
|
92 | 92 | attr='settings_post', |
|
93 |
renderer='rhodecode:templates/admin/auth/plugin_settings. |
|
|
93 | renderer='rhodecode:templates/admin/auth/plugin_settings.mako', | |
|
94 | 94 | request_method='POST', |
|
95 | 95 | route_name='auth_home', |
|
96 | 96 | context=HeadersAuthnResource) |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2012-201 |
|
|
3 | # Copyright (C) 2012-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -74,14 +74,14 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||
|
74 | 74 | config.add_view( |
|
75 | 75 | 'rhodecode.authentication.views.AuthnPluginViewBase', |
|
76 | 76 | attr='settings_get', |
|
77 |
renderer='rhodecode:templates/admin/auth/plugin_settings. |
|
|
77 | renderer='rhodecode:templates/admin/auth/plugin_settings.mako', | |
|
78 | 78 | request_method='GET', |
|
79 | 79 | route_name='auth_home', |
|
80 | 80 | context=JasigCasAuthnResource) |
|
81 | 81 | config.add_view( |
|
82 | 82 | 'rhodecode.authentication.views.AuthnPluginViewBase', |
|
83 | 83 | attr='settings_post', |
|
84 |
renderer='rhodecode:templates/admin/auth/plugin_settings. |
|
|
84 | renderer='rhodecode:templates/admin/auth/plugin_settings.mako', | |
|
85 | 85 | request_method='POST', |
|
86 | 86 | route_name='auth_home', |
|
87 | 87 | context=JasigCasAuthnResource) |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -332,14 +332,14 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||
|
332 | 332 | config.add_view( |
|
333 | 333 | 'rhodecode.authentication.views.AuthnPluginViewBase', |
|
334 | 334 | attr='settings_get', |
|
335 |
renderer='rhodecode:templates/admin/auth/plugin_settings. |
|
|
335 | renderer='rhodecode:templates/admin/auth/plugin_settings.mako', | |
|
336 | 336 | request_method='GET', |
|
337 | 337 | route_name='auth_home', |
|
338 | 338 | context=LdapAuthnResource) |
|
339 | 339 | config.add_view( |
|
340 | 340 | 'rhodecode.authentication.views.AuthnPluginViewBase', |
|
341 | 341 | attr='settings_post', |
|
342 |
renderer='rhodecode:templates/admin/auth/plugin_settings. |
|
|
342 | renderer='rhodecode:templates/admin/auth/plugin_settings.mako', | |
|
343 | 343 | request_method='POST', |
|
344 | 344 | route_name='auth_home', |
|
345 | 345 | context=LdapAuthnResource) |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2012-201 |
|
|
3 | # Copyright (C) 2012-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -82,14 +82,14 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||
|
82 | 82 | config.add_view( |
|
83 | 83 | 'rhodecode.authentication.views.AuthnPluginViewBase', |
|
84 | 84 | attr='settings_get', |
|
85 |
renderer='rhodecode:templates/admin/auth/plugin_settings. |
|
|
85 | renderer='rhodecode:templates/admin/auth/plugin_settings.mako', | |
|
86 | 86 | request_method='GET', |
|
87 | 87 | route_name='auth_home', |
|
88 | 88 | context=PamAuthnResource) |
|
89 | 89 | config.add_view( |
|
90 | 90 | 'rhodecode.authentication.views.AuthnPluginViewBase', |
|
91 | 91 | attr='settings_post', |
|
92 |
renderer='rhodecode:templates/admin/auth/plugin_settings. |
|
|
92 | renderer='rhodecode:templates/admin/auth/plugin_settings.mako', | |
|
93 | 93 | request_method='POST', |
|
94 | 94 | route_name='auth_home', |
|
95 | 95 | context=PamAuthnResource) |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2012-201 |
|
|
3 | # Copyright (C) 2012-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -52,14 +52,14 b' class RhodeCodeAuthPlugin(RhodeCodeAuthP' | |||
|
52 | 52 | config.add_view( |
|
53 | 53 | 'rhodecode.authentication.views.AuthnPluginViewBase', |
|
54 | 54 | attr='settings_get', |
|
55 |
renderer='rhodecode:templates/admin/auth/plugin_settings. |
|
|
55 | renderer='rhodecode:templates/admin/auth/plugin_settings.mako', | |
|
56 | 56 | request_method='GET', |
|
57 | 57 | route_name='auth_home', |
|
58 | 58 | context=RhodecodeAuthnResource) |
|
59 | 59 | config.add_view( |
|
60 | 60 | 'rhodecode.authentication.views.AuthnPluginViewBase', |
|
61 | 61 | attr='settings_post', |
|
62 |
renderer='rhodecode:templates/admin/auth/plugin_settings. |
|
|
62 | renderer='rhodecode:templates/admin/auth/plugin_settings.mako', | |
|
63 | 63 | request_method='POST', |
|
64 | 64 | route_name='auth_home', |
|
65 | 65 | context=RhodecodeAuthnResource) |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -55,14 +55,14 b' class RhodeCodeAuthPlugin(RhodeCodeAuthP' | |||
|
55 | 55 | config.add_view( |
|
56 | 56 | 'rhodecode.authentication.views.AuthnPluginViewBase', |
|
57 | 57 | attr='settings_get', |
|
58 |
renderer='rhodecode:templates/admin/auth/plugin_settings. |
|
|
58 | renderer='rhodecode:templates/admin/auth/plugin_settings.mako', | |
|
59 | 59 | request_method='GET', |
|
60 | 60 | route_name='auth_home', |
|
61 | 61 | context=RhodecodeAuthnResource) |
|
62 | 62 | config.add_view( |
|
63 | 63 | 'rhodecode.authentication.views.AuthnPluginViewBase', |
|
64 | 64 | attr='settings_post', |
|
65 |
renderer='rhodecode:templates/admin/auth/plugin_settings. |
|
|
65 | renderer='rhodecode:templates/admin/auth/plugin_settings.mako', | |
|
66 | 66 | request_method='POST', |
|
67 | 67 | route_name='auth_home', |
|
68 | 68 | context=RhodecodeAuthnResource) |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2012-201 |
|
|
3 | # Copyright (C) 2012-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2012-201 |
|
|
3 | # Copyright (C) 2012-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2012-201 |
|
|
3 | # Copyright (C) 2012-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,4 +1,4 b'' | |||
|
1 |
# Copyright (C) 201 |
|
|
1 | # Copyright (C) 2017 RhodeCode GmbH | |
|
2 | 2 | # |
|
3 | 3 | # This program is free software: you can redistribute it and/or modify |
|
4 | 4 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2012-201 |
|
|
3 | # Copyright (C) 2012-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -134,7 +134,7 b' class AuthSettingsView(object):' | |||
|
134 | 134 | 'available_plugins': authn_registry.get_plugins(), |
|
135 | 135 | 'enabled_plugins': enabled_plugins, |
|
136 | 136 | } |
|
137 |
html = render('rhodecode:templates/admin/auth/auth_settings. |
|
|
137 | html = render('rhodecode:templates/admin/auth/auth_settings.mako', | |
|
138 | 138 | template_context, |
|
139 | 139 | request=self.request) |
|
140 | 140 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -46,7 +46,7 b' PLUGIN_DEFINITION = {' | |||
|
46 | 46 | 'javascript': [], |
|
47 | 47 | 'css': [], |
|
48 | 48 | 'template_hooks': { |
|
49 |
'plugin_init_template': 'rhodecode:templates/channelstream/plugin_init. |
|
|
49 | 'plugin_init_template': 'rhodecode:templates/channelstream/plugin_init.mako' | |
|
50 | 50 | }, |
|
51 | 51 | 'url_gen': url_gen, |
|
52 | 52 | 'static': None, |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -62,7 +62,7 b' class ChannelstreamView(object):' | |||
|
62 | 62 | registry = request.registry |
|
63 | 63 | self.channelstream_config = registry.rhodecode_plugins['channelstream'] |
|
64 | 64 | if not self.channelstream_config.get('enabled'): |
|
65 |
log.e |
|
|
65 | log.error('Channelstream plugin is disabled') | |
|
66 | 66 | raise HTTPBadRequest() |
|
67 | 67 | |
|
68 | 68 | @NotAnonymous() |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2013-201 |
|
|
3 | # Copyright (C) 2013-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -52,7 +52,8 b' from rhodecode.lib.middleware.https_fixu' | |||
|
52 | 52 | from rhodecode.lib.middleware.vcs import VCSMiddleware |
|
53 | 53 | from rhodecode.lib.plugins.utils import register_rhodecode_plugin |
|
54 | 54 | from rhodecode.lib.utils2 import aslist as rhodecode_aslist |
|
55 |
from rhodecode.subscribers import |
|
|
55 | from rhodecode.subscribers import ( | |
|
56 | scan_repositories_if_enabled, write_metadata_if_needed) | |
|
56 | 57 | |
|
57 | 58 | |
|
58 | 59 | log = logging.getLogger(__name__) |
@@ -232,6 +233,14 b' def error_handler(exception, request):' | |||
|
232 | 233 | if isinstance(exception, HTTPError): |
|
233 | 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 | 244 | c = AttributeDict() |
|
236 | 245 | c.error_message = base_response.status |
|
237 | 246 | c.error_explanation = base_response.explanation or str(base_response) |
@@ -251,7 +260,7 b' def error_handler(exception, request):' | |||
|
251 | 260 | c.causes = base_response.causes |
|
252 | 261 | |
|
253 | 262 | response = render_to_response( |
|
254 |
'/errors/error_document. |
|
|
263 | '/errors/error_document.mako', {'c': c}, request=request, | |
|
255 | 264 | response=base_response) |
|
256 | 265 | |
|
257 | 266 | return response |
@@ -283,8 +292,12 b' def includeme(config):' | |||
|
283 | 292 | config.add_route( |
|
284 | 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 | 298 | # Add subscribers. |
|
287 | 299 | config.add_subscriber(scan_repositories_if_enabled, ApplicationCreated) |
|
300 | config.add_subscriber(write_metadata_if_needed, ApplicationCreated) | |
|
288 | 301 | |
|
289 | 302 | # Set the authorization policy. |
|
290 | 303 | authz_policy = ACLAuthorizationPolicy() |
@@ -320,6 +333,13 b' def includeme_first(config):' | |||
|
320 | 333 | config.add_view(favicon_redirect, route_name='favicon') |
|
321 | 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 | 343 | config.add_static_view( |
|
324 | 344 | '_static/deform', 'deform:static') |
|
325 | 345 | config.add_static_view( |
@@ -351,7 +371,6 b' def wrap_app_in_wsgi_middlewares(pyramid' | |||
|
351 | 371 | pyramid_app = make_gzip_middleware( |
|
352 | 372 | pyramid_app, settings, compress_level=1) |
|
353 | 373 | |
|
354 | ||
|
355 | 374 | # this should be the outer most middleware in the wsgi stack since |
|
356 | 375 | # middleware like Routes make database calls |
|
357 | 376 | def pyramid_app_with_cleanup(environ, start_response): |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2016-201 |
|
|
3 | # Copyright (C) 2016-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -503,12 +503,6 b' def make_map(config):' | |||
|
503 | 503 | m.connect('admin_settings_search', '/settings/search', |
|
504 | 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 | 506 | m.connect('admin_settings_supervisor', '/settings/supervisor', |
|
513 | 507 | action='settings_supervisor', conditions={'method': ['GET']}) |
|
514 | 508 | m.connect('admin_settings_supervisor_log', '/settings/supervisor/{procid}/log', |
@@ -566,6 +560,10 b' def make_map(config):' | |||
|
566 | 560 | '/my_account/toggle_visibility', |
|
567 | 561 | action='my_notifications_toggle_visibility', |
|
568 | 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 | 568 | # NOTIFICATION REST ROUTES |
|
571 | 569 | with rmap.submapper(path_prefix=ADMIN_PREFIX, |
@@ -624,9 +622,11 b' def make_map(config):' | |||
|
624 | 622 | 'pull_requests_global_0', '/pull_requests/{pull_request_id:[0-9]+}', |
|
625 | 623 | action='pull_requests') |
|
626 | 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 | 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 | 631 | # USER JOURNAL |
|
632 | 632 | rmap.connect('journal', '%s/journal' % (ADMIN_PREFIX,), |
@@ -694,8 +694,8 b' def make_map(config):' | |||
|
694 | 694 | requirements=URL_NAME_REQUIREMENTS, jsroute=True) |
|
695 | 695 | |
|
696 | 696 | rmap.connect('repo_refs_data', '/{repo_name}/refs-data', |
|
697 |
controller='summary', action='repo_refs_data', |
|
|
698 | requirements=URL_NAME_REQUIREMENTS) | |
|
697 | controller='summary', action='repo_refs_data', | |
|
698 | requirements=URL_NAME_REQUIREMENTS, jsroute=True) | |
|
699 | 699 | rmap.connect('repo_refs_changelog_data', '/{repo_name}/refs-data-changelog', |
|
700 | 700 | controller='summary', action='repo_refs_changelog_data', |
|
701 | 701 | requirements=URL_NAME_REQUIREMENTS, jsroute=True) |
@@ -704,9 +704,9 b' def make_map(config):' | |||
|
704 | 704 | jsroute=True, requirements=URL_NAME_REQUIREMENTS) |
|
705 | 705 | |
|
706 | 706 | rmap.connect('changeset_home', '/{repo_name}/changeset/{revision}', |
|
707 |
controller='changeset', revision='tip', |
|
|
707 | controller='changeset', revision='tip', | |
|
708 | 708 | conditions={'function': check_repo}, |
|
709 | requirements=URL_NAME_REQUIREMENTS) | |
|
709 | requirements=URL_NAME_REQUIREMENTS, jsroute=True) | |
|
710 | 710 | rmap.connect('changeset_children', '/{repo_name}/changeset_children/{revision}', |
|
711 | 711 | controller='changeset', revision='tip', action='changeset_children', |
|
712 | 712 | conditions={'function': check_repo}, |
@@ -923,7 +923,7 b' def make_map(config):' | |||
|
923 | 923 | controller='pullrequests', |
|
924 | 924 | action='show', conditions={'function': check_repo, |
|
925 | 925 | 'method': ['GET']}, |
|
926 | requirements=URL_NAME_REQUIREMENTS) | |
|
926 | requirements=URL_NAME_REQUIREMENTS, jsroute=True) | |
|
927 | 927 | |
|
928 | 928 | rmap.connect('pullrequest_update', |
|
929 | 929 | '/{repo_name}/pull-request/{pull_request_id}', |
@@ -997,10 +997,10 b' def make_map(config):' | |||
|
997 | 997 | conditions={'function': check_repo}, |
|
998 | 998 | requirements=URL_NAME_REQUIREMENTS, jsroute=True) |
|
999 | 999 | |
|
1000 |
rmap.connect('changelog_ |
|
|
1001 |
controller='changelog', action='changelog_ |
|
|
1000 | rmap.connect('changelog_elements', '/{repo_name}/changelog_details', | |
|
1001 | controller='changelog', action='changelog_elements', | |
|
1002 | 1002 | conditions={'function': check_repo}, |
|
1003 | requirements=URL_NAME_REQUIREMENTS) | |
|
1003 | requirements=URL_NAME_REQUIREMENTS, jsroute=True) | |
|
1004 | 1004 | |
|
1005 | 1005 | rmap.connect('files_home', '/{repo_name}/files/{revision}/{f_path}', |
|
1006 | 1006 | controller='files', revision='tip', f_path='', |
@@ -1064,7 +1064,7 b' def make_map(config):' | |||
|
1064 | 1064 | '/{repo_name}/annotate/{revision}/{f_path}', |
|
1065 | 1065 | controller='files', action='index', revision='tip', |
|
1066 | 1066 | f_path='', annotate=True, conditions={'function': check_repo}, |
|
1067 | requirements=URL_NAME_REQUIREMENTS) | |
|
1067 | requirements=URL_NAME_REQUIREMENTS, jsroute=True) | |
|
1068 | 1068 | |
|
1069 | 1069 | rmap.connect('files_edit', |
|
1070 | 1070 | '/{repo_name}/edit/{revision}/{f_path}', |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -153,11 +153,11 b' class AdminController(BaseController):' | |||
|
153 | 153 | |
|
154 | 154 | c.users_log = Page(users_log, page=p, items_per_page=10, |
|
155 | 155 | url=url_generator) |
|
156 |
c.log_data = render('admin/admin_log. |
|
|
156 | c.log_data = render('admin/admin_log.mako') | |
|
157 | 157 | |
|
158 | 158 | if request.is_xhr: |
|
159 | 159 | return c.log_data |
|
160 |
return render('admin/admin. |
|
|
160 | return render('admin/admin.mako') | |
|
161 | 161 | |
|
162 | 162 | # global redirect doesn't need permissions |
|
163 | 163 | def pull_requests(self, pull_request_id): |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -57,7 +57,7 b' class DefaultsController(BaseController)' | |||
|
57 | 57 | defaults = SettingsModel().get_default_repo_settings() |
|
58 | 58 | |
|
59 | 59 | return htmlfill.render( |
|
60 |
render('admin/defaults/defaults. |
|
|
60 | render('admin/defaults/defaults.mako'), | |
|
61 | 61 | defaults=defaults, |
|
62 | 62 | encoding="UTF-8", |
|
63 | 63 | force_defaults=False |
@@ -88,7 +88,7 b' class DefaultsController(BaseController)' | |||
|
88 | 88 | defaults = errors.value |
|
89 | 89 | |
|
90 | 90 | return htmlfill.render( |
|
91 |
render('admin/defaults/defaults. |
|
|
91 | render('admin/defaults/defaults.mako'), | |
|
92 | 92 | defaults=defaults, |
|
93 | 93 | errors=errors.error_dict or {}, |
|
94 | 94 | prefix_error=False, |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2013-201 |
|
|
3 | # Copyright (C) 2013-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -114,7 +114,7 b' class GistsController(BaseController):' | |||
|
114 | 114 | c.active = 'public' |
|
115 | 115 | |
|
116 | 116 | from rhodecode.lib.utils import PartialRenderer |
|
117 |
_render = PartialRenderer('data_table/_dt_elements. |
|
|
117 | _render = PartialRenderer('data_table/_dt_elements.mako') | |
|
118 | 118 | |
|
119 | 119 | data = [] |
|
120 | 120 | |
@@ -130,7 +130,7 b' class GistsController(BaseController):' | |||
|
130 | 130 | 'description': _render('gist_description', gist.gist_description) |
|
131 | 131 | }) |
|
132 | 132 | c.data = json.dumps(data) |
|
133 |
return render('admin/gists/index. |
|
|
133 | return render('admin/gists/index.mako') | |
|
134 | 134 | |
|
135 | 135 | @LoginRequired() |
|
136 | 136 | @NotAnonymous() |
@@ -186,7 +186,7 b' class GistsController(BaseController):' | |||
|
186 | 186 | del errors['nodes.0.filename'] |
|
187 | 187 | |
|
188 | 188 | return formencode.htmlfill.render( |
|
189 |
render('admin/gists/new. |
|
|
189 | render('admin/gists/new.mako'), | |
|
190 | 190 | defaults=defaults, |
|
191 | 191 | errors=errors, |
|
192 | 192 | prefix_error=False, |
@@ -202,11 +202,11 b' class GistsController(BaseController):' | |||
|
202 | 202 | |
|
203 | 203 | @LoginRequired() |
|
204 | 204 | @NotAnonymous() |
|
205 |
def new(self |
|
|
205 | def new(self): | |
|
206 | 206 | """GET /admin/gists/new: Form to create a new item""" |
|
207 | 207 | # url('new_gist') |
|
208 | 208 | self.__load_defaults() |
|
209 |
return render('admin/gists/new. |
|
|
209 | return render('admin/gists/new.mako') | |
|
210 | 210 | |
|
211 | 211 | @LoginRequired() |
|
212 | 212 | @NotAnonymous() |
@@ -266,7 +266,7 b' class GistsController(BaseController):' | |||
|
266 | 266 | if (f_path is None or f.path == f_path)]) |
|
267 | 267 | response.content_type = 'text/plain' |
|
268 | 268 | return content |
|
269 |
return render('admin/gists/show. |
|
|
269 | return render('admin/gists/show.mako') | |
|
270 | 270 | |
|
271 | 271 | @LoginRequired() |
|
272 | 272 | @NotAnonymous() |
@@ -322,7 +322,9 b' class GistsController(BaseController):' | |||
|
322 | 322 | |
|
323 | 323 | @LoginRequired() |
|
324 | 324 | @NotAnonymous() |
|
325 |
def edit_form(self, gist_id |
|
|
325 | def edit_form(self, gist_id): | |
|
326 | translate = _ = c.pyramid_request.translate | |
|
327 | ||
|
326 | 328 | """GET /admin/gists/gist_id/edit: Form to edit an existing item""" |
|
327 | 329 | # url('edit_gist', gist_id=ID) |
|
328 | 330 | self._add_gist_to_context(gist_id) |
@@ -342,9 +344,11 b' class GistsController(BaseController):' | |||
|
342 | 344 | else: |
|
343 | 345 | # this cannot use timeago, since it's used in select2 as a value |
|
344 | 346 | expiry = h.age(h.time_to_datetime(c.gist.gist_expires)) |
|
347 | ||
|
348 | expiry = translate(expiry) | |
|
345 | 349 | self.__load_defaults( |
|
346 | 350 | extra_values=(0, _('%(expiry)s - current value') % {'expiry': expiry})) |
|
347 |
return render('admin/gists/edit. |
|
|
351 | return render('admin/gists/edit.mako') | |
|
348 | 352 | |
|
349 | 353 | @LoginRequired() |
|
350 | 354 | @NotAnonymous() |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2013-201 |
|
|
3 | # Copyright (C) 2013-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -24,13 +24,16 b' my account controller for RhodeCode admi' | |||
|
24 | 24 | """ |
|
25 | 25 | |
|
26 | 26 | import logging |
|
27 | import datetime | |
|
27 | 28 | |
|
28 | 29 | import formencode |
|
29 | 30 | from formencode import htmlfill |
|
31 | from pyramid.threadlocal import get_current_registry | |
|
30 | 32 | from pylons import request, tmpl_context as c, url, session |
|
31 | 33 | from pylons.controllers.util import redirect |
|
32 | 34 | from pylons.i18n.translation import _ |
|
33 | 35 | from sqlalchemy.orm import joinedload |
|
36 | from webob.exc import HTTPBadGateway | |
|
34 | 37 | |
|
35 | 38 | from rhodecode import forms |
|
36 | 39 | from rhodecode.lib import helpers as h |
@@ -41,6 +44,8 b' from rhodecode.lib.base import BaseContr' | |||
|
41 | 44 | from rhodecode.lib.utils import jsonify |
|
42 | 45 | from rhodecode.lib.utils2 import safe_int, md5, str2bool |
|
43 | 46 | from rhodecode.lib.ext_json import json |
|
47 | from rhodecode.lib.channelstream import channelstream_request, \ | |
|
48 | ChannelstreamException | |
|
44 | 49 | |
|
45 | 50 | from rhodecode.model.validation_schema.schemas import user_schema |
|
46 | 51 | from rhodecode.model.db import ( |
@@ -52,7 +57,7 b' from rhodecode.model.repo import RepoMod' | |||
|
52 | 57 | from rhodecode.model.auth_token import AuthTokenModel |
|
53 | 58 | from rhodecode.model.meta import Session |
|
54 | 59 | from rhodecode.model.pull_request import PullRequestModel |
|
55 |
from rhodecode.model.comment import |
|
|
60 | from rhodecode.model.comment import CommentsModel | |
|
56 | 61 | |
|
57 | 62 | log = logging.getLogger(__name__) |
|
58 | 63 | |
@@ -76,6 +81,9 b' class MyAccountController(BaseController' | |||
|
76 | 81 | " crucial for entire application"), category='warning') |
|
77 | 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 | 87 | def _load_my_repos_data(self, watched=False): |
|
80 | 88 | if watched: |
|
81 | 89 | admin = False |
@@ -104,8 +112,7 b' class MyAccountController(BaseController' | |||
|
104 | 112 | # url('my_account') |
|
105 | 113 | c.active = 'profile_edit' |
|
106 | 114 | self.__load_data() |
|
107 |
c.perm_user = |
|
|
108 | ip_addr=self.ip_addr) | |
|
115 | c.perm_user = c.auth_user | |
|
109 | 116 | c.extern_type = c.user.extern_type |
|
110 | 117 | c.extern_name = c.user.extern_name |
|
111 | 118 | |
@@ -137,7 +144,7 b' class MyAccountController(BaseController' | |||
|
137 | 144 | |
|
138 | 145 | except formencode.Invalid as errors: |
|
139 | 146 | return htmlfill.render( |
|
140 |
render('admin/my_account/my_account. |
|
|
147 | render('admin/my_account/my_account.mako'), | |
|
141 | 148 | defaults=errors.value, |
|
142 | 149 | errors=errors.error_dict or {}, |
|
143 | 150 | prefix_error=False, |
@@ -152,7 +159,7 b' class MyAccountController(BaseController' | |||
|
152 | 159 | return redirect('my_account') |
|
153 | 160 | |
|
154 | 161 | return htmlfill.render( |
|
155 |
render('admin/my_account/my_account. |
|
|
162 | render('admin/my_account/my_account.mako'), | |
|
156 | 163 | defaults=defaults, |
|
157 | 164 | encoding="UTF-8", |
|
158 | 165 | force_defaults=False |
@@ -168,7 +175,7 b' class MyAccountController(BaseController' | |||
|
168 | 175 | |
|
169 | 176 | defaults = c.user.get_dict() |
|
170 | 177 | return htmlfill.render( |
|
171 |
render('admin/my_account/my_account. |
|
|
178 | render('admin/my_account/my_account.mako'), | |
|
172 | 179 | defaults=defaults, encoding="UTF-8", force_defaults=False) |
|
173 | 180 | |
|
174 | 181 | def my_account_edit(self): |
@@ -177,14 +184,13 b' class MyAccountController(BaseController' | |||
|
177 | 184 | """ |
|
178 | 185 | c.active = 'profile_edit' |
|
179 | 186 | self.__load_data() |
|
180 |
c.perm_user = |
|
|
181 | ip_addr=self.ip_addr) | |
|
187 | c.perm_user = c.auth_user | |
|
182 | 188 | c.extern_type = c.user.extern_type |
|
183 | 189 | c.extern_name = c.user.extern_name |
|
184 | 190 | |
|
185 | 191 | defaults = c.user.get_dict() |
|
186 | 192 | return htmlfill.render( |
|
187 |
render('admin/my_account/my_account. |
|
|
193 | render('admin/my_account/my_account.mako'), | |
|
188 | 194 | defaults=defaults, |
|
189 | 195 | encoding="UTF-8", |
|
190 | 196 | force_defaults=False |
@@ -194,6 +200,7 b' class MyAccountController(BaseController' | |||
|
194 | 200 | def my_account_password(self): |
|
195 | 201 | c.active = 'password' |
|
196 | 202 | self.__load_data() |
|
203 | c.extern_type = c.user.extern_type | |
|
197 | 204 | |
|
198 | 205 | schema = user_schema.ChangePasswordSchema().bind( |
|
199 | 206 | username=c.rhodecode_user.username) |
@@ -201,7 +208,7 b' class MyAccountController(BaseController' | |||
|
201 | 208 | form = forms.Form(schema, |
|
202 | 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 | 212 | controls = request.POST.items() |
|
206 | 213 | try: |
|
207 | 214 | valid_data = form.validate(controls) |
@@ -228,7 +235,7 b' class MyAccountController(BaseController' | |||
|
228 | 235 | return redirect(url('my_account_password')) |
|
229 | 236 | |
|
230 | 237 | c.form = form |
|
231 |
return render('admin/my_account/my_account. |
|
|
238 | return render('admin/my_account/my_account.mako') | |
|
232 | 239 | |
|
233 | 240 | def my_account_repos(self): |
|
234 | 241 | c.active = 'repos' |
@@ -236,7 +243,7 b' class MyAccountController(BaseController' | |||
|
236 | 243 | |
|
237 | 244 | # json used to render the grid |
|
238 | 245 | c.data = self._load_my_repos_data() |
|
239 |
return render('admin/my_account/my_account. |
|
|
246 | return render('admin/my_account/my_account.mako') | |
|
240 | 247 | |
|
241 | 248 | def my_account_watched(self): |
|
242 | 249 | c.active = 'watched' |
@@ -244,15 +251,14 b' class MyAccountController(BaseController' | |||
|
244 | 251 | |
|
245 | 252 | # json used to render the grid |
|
246 | 253 | c.data = self._load_my_repos_data(watched=True) |
|
247 |
return render('admin/my_account/my_account. |
|
|
254 | return render('admin/my_account/my_account.mako') | |
|
248 | 255 | |
|
249 | 256 | def my_account_perms(self): |
|
250 | 257 | c.active = 'perms' |
|
251 | 258 | self.__load_data() |
|
252 |
c.perm_user = |
|
|
253 | ip_addr=self.ip_addr) | |
|
259 | c.perm_user = c.auth_user | |
|
254 | 260 | |
|
255 |
return render('admin/my_account/my_account. |
|
|
261 | return render('admin/my_account/my_account.mako') | |
|
256 | 262 | |
|
257 | 263 | def my_account_emails(self): |
|
258 | 264 | c.active = 'emails' |
@@ -260,7 +266,7 b' class MyAccountController(BaseController' | |||
|
260 | 266 | |
|
261 | 267 | c.user_email_map = UserEmailMap.query()\ |
|
262 | 268 | .filter(UserEmailMap.user == c.user).all() |
|
263 |
return render('admin/my_account/my_account. |
|
|
269 | return render('admin/my_account/my_account.mako') | |
|
264 | 270 | |
|
265 | 271 | @auth.CSRFRequired() |
|
266 | 272 | def my_account_emails_add(self): |
@@ -312,11 +318,11 b' class MyAccountController(BaseController' | |||
|
312 | 318 | user_id=c.rhodecode_user.user_id, statuses=statuses) |
|
313 | 319 | |
|
314 | 320 | from rhodecode.lib.utils import PartialRenderer |
|
315 |
_render = PartialRenderer('data_table/_dt_elements. |
|
|
321 | _render = PartialRenderer('data_table/_dt_elements.mako') | |
|
316 | 322 | data = [] |
|
317 | 323 | for pr in pull_requests: |
|
318 | 324 | repo_id = pr.target_repo_id |
|
319 |
comments = |
|
|
325 | comments = CommentsModel().get_all_comments( | |
|
320 | 326 | repo_id, pull_request=pr) |
|
321 | 327 | owned = pr.user_id == c.rhodecode_user.user_id |
|
322 | 328 | status = pr.calculated_review_status() |
@@ -366,7 +372,7 b' class MyAccountController(BaseController' | |||
|
366 | 372 | if not request.is_xhr: |
|
367 | 373 | c.data_participate = json.dumps(data['data']) |
|
368 | 374 | c.records_total_participate = data['recordsTotal'] |
|
369 |
return render('admin/my_account/my_account. |
|
|
375 | return render('admin/my_account/my_account.mako') | |
|
370 | 376 | else: |
|
371 | 377 | return json.dumps(data) |
|
372 | 378 | |
@@ -387,7 +393,7 b' class MyAccountController(BaseController' | |||
|
387 | 393 | c.role_options = [(c.role_values, _("Role"))] |
|
388 | 394 | c.user_auth_tokens = AuthTokenModel().get_auth_tokens( |
|
389 | 395 | c.rhodecode_user.user_id, show_expired=show_expired) |
|
390 |
return render('admin/my_account/my_account. |
|
|
396 | return render('admin/my_account/my_account.mako') | |
|
391 | 397 | |
|
392 | 398 | @auth.CSRFRequired() |
|
393 | 399 | def my_account_auth_tokens_add(self): |
@@ -420,7 +426,7 b' class MyAccountController(BaseController' | |||
|
420 | 426 | |
|
421 | 427 | def my_notifications(self): |
|
422 | 428 | c.active = 'notifications' |
|
423 |
return render('admin/my_account/my_account. |
|
|
429 | return render('admin/my_account/my_account.mako') | |
|
424 | 430 | |
|
425 | 431 | @auth.CSRFRequired() |
|
426 | 432 | @jsonify |
@@ -430,3 +436,33 b' class MyAccountController(BaseController' | |||
|
430 | 436 | user.update_userdata(notification_status=new_status) |
|
431 | 437 | Session().commit() |
|
432 | 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 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -82,9 +82,9 b' class NotificationsController(BaseContro' | |||
|
82 | 82 | c.current_filter = 'comment' |
|
83 | 83 | |
|
84 | 84 | if request.is_xhr: |
|
85 |
return render('admin/notifications/notifications_data. |
|
|
85 | return render('admin/notifications/notifications_data.mako') | |
|
86 | 86 | |
|
87 |
return render('admin/notifications/notifications. |
|
|
87 | return render('admin/notifications/notifications.mako') | |
|
88 | 88 | |
|
89 | 89 | |
|
90 | 90 | @auth.CSRFRequired() |
@@ -102,7 +102,7 b' class NotificationsController(BaseContro' | |||
|
102 | 102 | url('notifications'), request.GET) |
|
103 | 103 | c.notifications = Page(notif, page=1, items_per_page=10, |
|
104 | 104 | url=notifications_url) |
|
105 |
return render('admin/notifications/notifications_data. |
|
|
105 | return render('admin/notifications/notifications_data.mako') | |
|
106 | 106 | |
|
107 | 107 | def _has_permissions(self, notification): |
|
108 | 108 | def is_owner(): |
@@ -173,6 +173,6 b' class NotificationsController(BaseContro' | |||
|
173 | 173 | Session().commit() |
|
174 | 174 | c.notification = no |
|
175 | 175 | |
|
176 |
return render('admin/notifications/show_notification. |
|
|
176 | return render('admin/notifications/show_notification.mako') | |
|
177 | 177 | |
|
178 | 178 | return abort(403) |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -80,7 +80,7 b' class PermissionsController(BaseControll' | |||
|
80 | 80 | defaults.update(c.user.get_default_perms()) |
|
81 | 81 | |
|
82 | 82 | return htmlfill.render( |
|
83 |
render('admin/permissions/permissions. |
|
|
83 | render('admin/permissions/permissions.mako'), | |
|
84 | 84 | defaults=defaults, |
|
85 | 85 | encoding="UTF-8", |
|
86 | 86 | force_defaults=False) |
@@ -116,7 +116,7 b' class PermissionsController(BaseControll' | |||
|
116 | 116 | defaults = errors.value |
|
117 | 117 | |
|
118 | 118 | return htmlfill.render( |
|
119 |
render('admin/permissions/permissions. |
|
|
119 | render('admin/permissions/permissions.mako'), | |
|
120 | 120 | defaults=defaults, |
|
121 | 121 | errors=errors.error_dict or {}, |
|
122 | 122 | prefix_error=False, |
@@ -137,7 +137,7 b' class PermissionsController(BaseControll' | |||
|
137 | 137 | defaults = {} |
|
138 | 138 | defaults.update(c.user.get_default_perms()) |
|
139 | 139 | return htmlfill.render( |
|
140 |
render('admin/permissions/permissions. |
|
|
140 | render('admin/permissions/permissions.mako'), | |
|
141 | 141 | defaults=defaults, |
|
142 | 142 | encoding="UTF-8", |
|
143 | 143 | force_defaults=False) |
@@ -165,7 +165,7 b' class PermissionsController(BaseControll' | |||
|
165 | 165 | defaults = errors.value |
|
166 | 166 | |
|
167 | 167 | return htmlfill.render( |
|
168 |
render('admin/permissions/permissions. |
|
|
168 | render('admin/permissions/permissions.mako'), | |
|
169 | 169 | defaults=defaults, |
|
170 | 170 | errors=errors.error_dict or {}, |
|
171 | 171 | prefix_error=False, |
@@ -188,7 +188,7 b' class PermissionsController(BaseControll' | |||
|
188 | 188 | defaults.update(c.user.get_default_perms()) |
|
189 | 189 | |
|
190 | 190 | return htmlfill.render( |
|
191 |
render('admin/permissions/permissions. |
|
|
191 | render('admin/permissions/permissions.mako'), | |
|
192 | 192 | defaults=defaults, |
|
193 | 193 | encoding="UTF-8", |
|
194 | 194 | force_defaults=False) |
@@ -219,7 +219,7 b' class PermissionsController(BaseControll' | |||
|
219 | 219 | defaults = errors.value |
|
220 | 220 | |
|
221 | 221 | return htmlfill.render( |
|
222 |
render('admin/permissions/permissions. |
|
|
222 | render('admin/permissions/permissions.mako'), | |
|
223 | 223 | defaults=defaults, |
|
224 | 224 | errors=errors.error_dict or {}, |
|
225 | 225 | prefix_error=False, |
@@ -239,11 +239,11 b' class PermissionsController(BaseControll' | |||
|
239 | 239 | c.user_ip_map = ( |
|
240 | 240 | UserIpMap.query().filter(UserIpMap.user == c.user).all()) |
|
241 | 241 | |
|
242 |
return render('admin/permissions/permissions. |
|
|
242 | return render('admin/permissions/permissions.mako') | |
|
243 | 243 | |
|
244 | 244 | @HasPermissionAllDecorator('hg.admin') |
|
245 | 245 | def permission_perms(self): |
|
246 | 246 | c.active = 'perms' |
|
247 | 247 | c.user = User.get_default_user() |
|
248 | 248 | c.perm_user = c.user.AuthUser |
|
249 |
return render('admin/permissions/permissions. |
|
|
249 | return render('admin/permissions/permissions.mako') |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -162,7 +162,7 b' class RepoGroupsController(BaseControlle' | |||
|
162 | 162 | repo_group_data = RepoGroupModel().get_repo_groups_as_dict( |
|
163 | 163 | repo_group_list=repo_group_list_acl, admin=True) |
|
164 | 164 | c.data = json.dumps(repo_group_data) |
|
165 |
return render('admin/repo_groups/repo_groups. |
|
|
165 | return render('admin/repo_groups/repo_groups.mako') | |
|
166 | 166 | |
|
167 | 167 | # perm checks inside |
|
168 | 168 | @NotAnonymous() |
@@ -199,7 +199,7 b' class RepoGroupsController(BaseControlle' | |||
|
199 | 199 | # TODO: in futureaction_logger(, '', '', '', self.sa) |
|
200 | 200 | except formencode.Invalid as errors: |
|
201 | 201 | return htmlfill.render( |
|
202 |
render('admin/repo_groups/repo_group_add. |
|
|
202 | render('admin/repo_groups/repo_group_add.mako'), | |
|
203 | 203 | defaults=errors.value, |
|
204 | 204 | errors=errors.error_dict or {}, |
|
205 | 205 | prefix_error=False, |
@@ -224,7 +224,7 b' class RepoGroupsController(BaseControlle' | |||
|
224 | 224 | return abort(403) |
|
225 | 225 | |
|
226 | 226 | self.__load_defaults() |
|
227 |
return render('admin/repo_groups/repo_group_add. |
|
|
227 | return render('admin/repo_groups/repo_group_add.mako') | |
|
228 | 228 | |
|
229 | 229 | @HasRepoGroupPermissionAnyDecorator('group.admin') |
|
230 | 230 | @auth.CSRFRequired() |
@@ -263,7 +263,7 b' class RepoGroupsController(BaseControlle' | |||
|
263 | 263 | except formencode.Invalid as errors: |
|
264 | 264 | c.active = 'settings' |
|
265 | 265 | return htmlfill.render( |
|
266 |
render('admin/repo_groups/repo_group_edit. |
|
|
266 | render('admin/repo_groups/repo_group_edit.mako'), | |
|
267 | 267 | defaults=errors.value, |
|
268 | 268 | errors=errors.error_dict or {}, |
|
269 | 269 | prefix_error=False, |
@@ -338,7 +338,7 b' class RepoGroupsController(BaseControlle' | |||
|
338 | 338 | defaults = self.__load_data(c.repo_group.group_id) |
|
339 | 339 | |
|
340 | 340 | return htmlfill.render( |
|
341 |
render('admin/repo_groups/repo_group_edit. |
|
|
341 | render('admin/repo_groups/repo_group_edit.mako'), | |
|
342 | 342 | defaults=defaults, |
|
343 | 343 | encoding="UTF-8", |
|
344 | 344 | force_defaults=False |
@@ -351,7 +351,7 b' class RepoGroupsController(BaseControlle' | |||
|
351 | 351 | c.active = 'advanced' |
|
352 | 352 | c.repo_group = RepoGroupModel()._get_repo_group(group_name) |
|
353 | 353 | |
|
354 |
return render('admin/repo_groups/repo_group_edit. |
|
|
354 | return render('admin/repo_groups/repo_group_edit.mako') | |
|
355 | 355 | |
|
356 | 356 | @HasRepoGroupPermissionAnyDecorator('group.admin') |
|
357 | 357 | def edit_repo_group_perms(self, group_name): |
@@ -363,7 +363,7 b' class RepoGroupsController(BaseControlle' | |||
|
363 | 363 | defaults = self.__load_data(c.repo_group.group_id) |
|
364 | 364 | |
|
365 | 365 | return htmlfill.render( |
|
366 |
render('admin/repo_groups/repo_group_edit. |
|
|
366 | render('admin/repo_groups/repo_group_edit.mako'), | |
|
367 | 367 | defaults=defaults, |
|
368 | 368 | encoding="UTF-8", |
|
369 | 369 | force_defaults=False |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2013-201 |
|
|
3 | # Copyright (C) 2013-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -147,7 +147,7 b' class ReposController(BaseRepoController' | |||
|
147 | 147 | # json used to render the grid |
|
148 | 148 | c.data = json.dumps(repos_data) |
|
149 | 149 | |
|
150 |
return render('admin/repos/repos. |
|
|
150 | return render('admin/repos/repos.mako') | |
|
151 | 151 | |
|
152 | 152 | # perms check inside |
|
153 | 153 | @NotAnonymous() |
@@ -175,7 +175,7 b' class ReposController(BaseRepoController' | |||
|
175 | 175 | task_id = task.task_id |
|
176 | 176 | except formencode.Invalid as errors: |
|
177 | 177 | return htmlfill.render( |
|
178 |
render('admin/repos/repo_add. |
|
|
178 | render('admin/repos/repo_add.mako'), | |
|
179 | 179 | defaults=errors.value, |
|
180 | 180 | errors=errors.error_dict or {}, |
|
181 | 181 | prefix_error=False, |
@@ -235,7 +235,7 b' class ReposController(BaseRepoController' | |||
|
235 | 235 | defaults.update({'repo_group': parent_group_choice}) |
|
236 | 236 | |
|
237 | 237 | return htmlfill.render( |
|
238 |
render('admin/repos/repo_add. |
|
|
238 | render('admin/repos/repo_add.mako'), | |
|
239 | 239 | defaults=defaults, |
|
240 | 240 | errors={}, |
|
241 | 241 | prefix_error=False, |
@@ -249,7 +249,7 b' class ReposController(BaseRepoController' | |||
|
249 | 249 | c.task_id = request.GET.get('task_id') |
|
250 | 250 | if not c.repo: |
|
251 | 251 | raise HTTPNotFound() |
|
252 |
return render('admin/repos/repo_creating. |
|
|
252 | return render('admin/repos/repo_creating.mako') | |
|
253 | 253 | |
|
254 | 254 | @NotAnonymous() |
|
255 | 255 | @jsonify |
@@ -334,7 +334,7 b' class ReposController(BaseRepoController' | |||
|
334 | 334 | defaults = self.__load_data(repo_name) |
|
335 | 335 | defaults.update(errors.value) |
|
336 | 336 | return htmlfill.render( |
|
337 |
render('admin/repos/repo_edit. |
|
|
337 | render('admin/repos/repo_edit.mako'), | |
|
338 | 338 | defaults=defaults, |
|
339 | 339 | errors=errors.error_dict or {}, |
|
340 | 340 | prefix_error=False, |
@@ -410,7 +410,7 b' class ReposController(BaseRepoController' | |||
|
410 | 410 | c.personal_repo_group = c.rhodecode_user.personal_repo_group |
|
411 | 411 | c.active = 'settings' |
|
412 | 412 | return htmlfill.render( |
|
413 |
render('admin/repos/repo_edit. |
|
|
413 | render('admin/repos/repo_edit.mako'), | |
|
414 | 414 | defaults=defaults, |
|
415 | 415 | encoding="UTF-8", |
|
416 | 416 | force_defaults=False) |
@@ -424,7 +424,7 b' class ReposController(BaseRepoController' | |||
|
424 | 424 | defaults = RepoModel()._get_defaults(repo_name) |
|
425 | 425 | |
|
426 | 426 | return htmlfill.render( |
|
427 |
render('admin/repos/repo_edit. |
|
|
427 | render('admin/repos/repo_edit.mako'), | |
|
428 | 428 | defaults=defaults, |
|
429 | 429 | encoding="UTF-8", |
|
430 | 430 | force_defaults=False) |
@@ -454,7 +454,7 b' class ReposController(BaseRepoController' | |||
|
454 | 454 | if request.POST: |
|
455 | 455 | |
|
456 | 456 | return redirect(url('repo_edit_fields')) |
|
457 |
return render('admin/repos/repo_edit. |
|
|
457 | return render('admin/repos/repo_edit.mako') | |
|
458 | 458 | |
|
459 | 459 | @HasRepoPermissionAllDecorator('repository.admin') |
|
460 | 460 | @auth.CSRFRequired() |
@@ -509,7 +509,7 b' class ReposController(BaseRepoController' | |||
|
509 | 509 | |
|
510 | 510 | if request.POST: |
|
511 | 511 | return redirect(url('repo_edit_advanced')) |
|
512 |
return render('admin/repos/repo_edit. |
|
|
512 | return render('admin/repos/repo_edit.mako') | |
|
513 | 513 | |
|
514 | 514 | @HasRepoPermissionAllDecorator('repository.admin') |
|
515 | 515 | @auth.CSRFRequired() |
@@ -642,7 +642,7 b' class ReposController(BaseRepoController' | |||
|
642 | 642 | c.repo_info = self._load_repo(repo_name) |
|
643 | 643 | c.active = 'caches' |
|
644 | 644 | |
|
645 |
return render('admin/repos/repo_edit. |
|
|
645 | return render('admin/repos/repo_edit.mako') | |
|
646 | 646 | |
|
647 | 647 | @HasRepoPermissionAllDecorator('repository.admin') |
|
648 | 648 | @auth.CSRFRequired() |
@@ -664,7 +664,7 b' class ReposController(BaseRepoController' | |||
|
664 | 664 | c.repo_info = self._load_repo(repo_name) |
|
665 | 665 | c.active = 'remote' |
|
666 | 666 | |
|
667 |
return render('admin/repos/repo_edit. |
|
|
667 | return render('admin/repos/repo_edit.mako') | |
|
668 | 668 | |
|
669 | 669 | @HasRepoPermissionAllDecorator('repository.admin') |
|
670 | 670 | @auth.CSRFRequired() |
@@ -702,7 +702,7 b' class ReposController(BaseRepoController' | |||
|
702 | 702 | |
|
703 | 703 | c.active = 'statistics' |
|
704 | 704 | |
|
705 |
return render('admin/repos/repo_edit. |
|
|
705 | return render('admin/repos/repo_edit.mako') | |
|
706 | 706 | |
|
707 | 707 | @HasRepoPermissionAllDecorator('repository.admin') |
|
708 | 708 | @auth.CSRFRequired() |
@@ -771,7 +771,7 b' class ReposController(BaseRepoController' | |||
|
771 | 771 | c.global_patterns = c.settings_model.get_global_settings() |
|
772 | 772 | c.repo_patterns = c.settings_model.get_repo_settings() |
|
773 | 773 | |
|
774 |
return render('admin/repos/repo_edit. |
|
|
774 | return render('admin/repos/repo_edit.mako') | |
|
775 | 775 | |
|
776 | 776 | @HasRepoPermissionAllDecorator('repository.admin') |
|
777 | 777 | def repo_settings_vcs(self, repo_name): |
@@ -791,7 +791,7 b' class ReposController(BaseRepoController' | |||
|
791 | 791 | rhodecode.CONFIG.get('labs_settings_active', 'true')) |
|
792 | 792 | |
|
793 | 793 | return htmlfill.render( |
|
794 |
render('admin/repos/repo_edit. |
|
|
794 | render('admin/repos/repo_edit.mako'), | |
|
795 | 795 | defaults=defaults, |
|
796 | 796 | encoding="UTF-8", |
|
797 | 797 | force_defaults=False) |
@@ -819,7 +819,7 b' class ReposController(BaseRepoController' | |||
|
819 | 819 | _("Some form inputs contain invalid data."), |
|
820 | 820 | category='error') |
|
821 | 821 | return htmlfill.render( |
|
822 |
render('admin/repos/repo_edit. |
|
|
822 | render('admin/repos/repo_edit.mako'), | |
|
823 | 823 | defaults=errors.value, |
|
824 | 824 | errors=errors.error_dict or {}, |
|
825 | 825 | prefix_error=False, |
@@ -842,7 +842,7 b' class ReposController(BaseRepoController' | |||
|
842 | 842 | return redirect(url('repo_vcs_settings', repo_name=repo_name)) |
|
843 | 843 | |
|
844 | 844 | return htmlfill.render( |
|
845 |
render('admin/repos/repo_edit. |
|
|
845 | render('admin/repos/repo_edit.mako'), | |
|
846 | 846 | defaults=self._vcs_form_defaults(repo_name), |
|
847 | 847 | encoding="UTF-8", |
|
848 | 848 | force_defaults=False) |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -25,15 +25,13 b' settings controller for rhodecode admin' | |||
|
25 | 25 | |
|
26 | 26 | import collections |
|
27 | 27 | import logging |
|
28 | import urllib2 | |
|
29 | 28 | |
|
30 | 29 | import datetime |
|
31 | 30 | import formencode |
|
32 | 31 | from formencode import htmlfill |
|
33 | import packaging.version | |
|
34 | 32 | from pylons import request, tmpl_context as c, url, config |
|
35 | 33 | from pylons.controllers.util import redirect |
|
36 |
from pylons.i18n.translation import _ |
|
|
34 | from pylons.i18n.translation import _ | |
|
37 | 35 | from pyramid.threadlocal import get_current_registry |
|
38 | 36 | from webob.exc import HTTPBadRequest |
|
39 | 37 | |
@@ -48,7 +46,6 b' from rhodecode.lib.utils import repo2db_' | |||
|
48 | 46 | from rhodecode.lib.utils2 import ( |
|
49 | 47 | str2bool, safe_unicode, AttributeDict, safe_int) |
|
50 | 48 | from rhodecode.lib.compat import OrderedDict |
|
51 | from rhodecode.lib.ext_json import json | |
|
52 | 49 | from rhodecode.lib.utils import jsonify |
|
53 | 50 | |
|
54 | 51 | from rhodecode.model.db import RhodeCodeUi, Repository |
@@ -150,7 +147,7 b' class SettingsController(BaseController)' | |||
|
150 | 147 | _("Some form inputs contain invalid data."), |
|
151 | 148 | category='error') |
|
152 | 149 | return htmlfill.render( |
|
153 |
render('admin/settings/settings. |
|
|
150 | render('admin/settings/settings.mako'), | |
|
154 | 151 | defaults=errors.value, |
|
155 | 152 | errors=errors.error_dict or {}, |
|
156 | 153 | prefix_error=False, |
@@ -179,7 +176,7 b' class SettingsController(BaseController)' | |||
|
179 | 176 | return redirect(url('admin_settings_vcs')) |
|
180 | 177 | |
|
181 | 178 | return htmlfill.render( |
|
182 |
render('admin/settings/settings. |
|
|
179 | render('admin/settings/settings.mako'), | |
|
183 | 180 | defaults=self._form_defaults(), |
|
184 | 181 | encoding="UTF-8", |
|
185 | 182 | force_defaults=False) |
@@ -198,7 +195,7 b' class SettingsController(BaseController)' | |||
|
198 | 195 | c.svn_proxy_generate_config = pyramid_settings[generate_config] |
|
199 | 196 | |
|
200 | 197 | return htmlfill.render( |
|
201 |
render('admin/settings/settings. |
|
|
198 | render('admin/settings/settings.mako'), | |
|
202 | 199 | defaults=self._form_defaults(), |
|
203 | 200 | encoding="UTF-8", |
|
204 | 201 | force_defaults=False) |
@@ -235,7 +232,7 b' class SettingsController(BaseController)' | |||
|
235 | 232 | c.active = 'mapping' |
|
236 | 233 | |
|
237 | 234 | return htmlfill.render( |
|
238 |
render('admin/settings/settings. |
|
|
235 | render('admin/settings/settings.mako'), | |
|
239 | 236 | defaults=self._form_defaults(), |
|
240 | 237 | encoding="UTF-8", |
|
241 | 238 | force_defaults=False) |
@@ -253,7 +250,7 b' class SettingsController(BaseController)' | |||
|
253 | 250 | form_result = application_form.to_python(dict(request.POST)) |
|
254 | 251 | except formencode.Invalid as errors: |
|
255 | 252 | return htmlfill.render( |
|
256 |
render('admin/settings/settings. |
|
|
253 | render('admin/settings/settings.mako'), | |
|
257 | 254 | defaults=errors.value, |
|
258 | 255 | errors=errors.error_dict or {}, |
|
259 | 256 | prefix_error=False, |
@@ -296,7 +293,7 b' class SettingsController(BaseController)' | |||
|
296 | 293 | .get_personal_group_name_pattern() |
|
297 | 294 | |
|
298 | 295 | return htmlfill.render( |
|
299 |
render('admin/settings/settings. |
|
|
296 | render('admin/settings/settings.mako'), | |
|
300 | 297 | defaults=self._form_defaults(), |
|
301 | 298 | encoding="UTF-8", |
|
302 | 299 | force_defaults=False) |
@@ -312,7 +309,7 b' class SettingsController(BaseController)' | |||
|
312 | 309 | form_result = application_form.to_python(dict(request.POST)) |
|
313 | 310 | except formencode.Invalid as errors: |
|
314 | 311 | return htmlfill.render( |
|
315 |
render('admin/settings/settings. |
|
|
312 | render('admin/settings/settings.mako'), | |
|
316 | 313 | defaults=errors.value, |
|
317 | 314 | errors=errors.error_dict or {}, |
|
318 | 315 | prefix_error=False, |
@@ -360,7 +357,7 b' class SettingsController(BaseController)' | |||
|
360 | 357 | c.active = 'visual' |
|
361 | 358 | |
|
362 | 359 | return htmlfill.render( |
|
363 |
render('admin/settings/settings. |
|
|
360 | render('admin/settings/settings.mako'), | |
|
364 | 361 | defaults=self._form_defaults(), |
|
365 | 362 | encoding="UTF-8", |
|
366 | 363 | force_defaults=False) |
@@ -406,7 +403,7 b' class SettingsController(BaseController)' | |||
|
406 | 403 | 'desc': defaults.get('rhodecode_issuetracker_desc_' + uid), |
|
407 | 404 | }) |
|
408 | 405 | |
|
409 |
return render('admin/settings/settings. |
|
|
406 | return render('admin/settings/settings.mako') | |
|
410 | 407 | |
|
411 | 408 | @HasPermissionAllDecorator('hg.admin') |
|
412 | 409 | @auth.CSRFRequired() |
@@ -469,7 +466,7 b' class SettingsController(BaseController)' | |||
|
469 | 466 | c.rhodecode_ini = rhodecode.CONFIG |
|
470 | 467 | |
|
471 | 468 | return htmlfill.render( |
|
472 |
render('admin/settings/settings. |
|
|
469 | render('admin/settings/settings.mako'), | |
|
473 | 470 | defaults=self._form_defaults(), |
|
474 | 471 | encoding="UTF-8", |
|
475 | 472 | force_defaults=False) |
@@ -526,7 +523,7 b' class SettingsController(BaseController)' | |||
|
526 | 523 | c.custom_hooks = model.get_custom_hooks() |
|
527 | 524 | |
|
528 | 525 | return htmlfill.render( |
|
529 |
render('admin/settings/settings. |
|
|
526 | render('admin/settings/settings.mako'), | |
|
530 | 527 | defaults=self._form_defaults(), |
|
531 | 528 | encoding="UTF-8", |
|
532 | 529 | force_defaults=False) |
@@ -541,154 +538,7 b' class SettingsController(BaseController)' | |||
|
541 | 538 | searcher = searcher_from_config(config) |
|
542 | 539 | c.statistics = searcher.statistics() |
|
543 | 540 | |
|
544 |
return render('admin/settings/settings. |
|
|
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') | |
|
541 | return render('admin/settings/settings.mako') | |
|
692 | 542 | |
|
693 | 543 | @HasPermissionAllDecorator('hg.admin') |
|
694 | 544 | def settings_supervisor(self): |
@@ -710,7 +560,7 b' class SettingsController(BaseController)' | |||
|
710 | 560 | except Exception as e: |
|
711 | 561 | c.connection_error = str(e) |
|
712 | 562 | log.exception("Exception reading supervisor data") |
|
713 |
return render('admin/settings/settings. |
|
|
563 | return render('admin/settings/settings.mako') | |
|
714 | 564 | |
|
715 | 565 | groupid = c.rhodecode_ini.get('supervisor.group_id') |
|
716 | 566 | |
@@ -734,7 +584,7 b' class SettingsController(BaseController)' | |||
|
734 | 584 | log.exception("Exception reading supervisor data") |
|
735 | 585 | c.supervisor_procs[k] = {'_rhodecode_error': str(e)} |
|
736 | 586 | |
|
737 |
return render('admin/settings/settings. |
|
|
587 | return render('admin/settings/settings.mako') | |
|
738 | 588 | |
|
739 | 589 | @HasPermissionAllDecorator('hg.admin') |
|
740 | 590 | def settings_supervisor_log(self, procid): |
@@ -751,7 +601,7 b' class SettingsController(BaseController)' | |||
|
751 | 601 | offset = abs(safe_int(request.GET.get('offset', c.log_size))) * -1 |
|
752 | 602 | c.log = supervisor.read_process_log(_connection, procid, offset, 0) |
|
753 | 603 | |
|
754 |
return render('admin/settings/settings. |
|
|
604 | return render('admin/settings/settings.mako') | |
|
755 | 605 | |
|
756 | 606 | @HasPermissionAllDecorator('hg.admin') |
|
757 | 607 | @auth.CSRFRequired() |
@@ -768,7 +618,7 b' class SettingsController(BaseController)' | |||
|
768 | 618 | _('Some form inputs contain invalid data.'), |
|
769 | 619 | category='error') |
|
770 | 620 | return htmlfill.render( |
|
771 |
render('admin/settings/settings. |
|
|
621 | render('admin/settings/settings.mako'), | |
|
772 | 622 | defaults=errors.value, |
|
773 | 623 | errors=errors.error_dict or {}, |
|
774 | 624 | prefix_error=False, |
@@ -795,7 +645,7 b' class SettingsController(BaseController)' | |||
|
795 | 645 | return redirect(url('admin_settings_labs')) |
|
796 | 646 | |
|
797 | 647 | return htmlfill.render( |
|
798 |
render('admin/settings/settings. |
|
|
648 | render('admin/settings/settings.mako'), | |
|
799 | 649 | defaults=self._form_defaults(), |
|
800 | 650 | encoding='UTF-8', |
|
801 | 651 | force_defaults=False) |
@@ -811,7 +661,7 b' class SettingsController(BaseController)' | |||
|
811 | 661 | c.lab_settings = _LAB_SETTINGS |
|
812 | 662 | |
|
813 | 663 | return htmlfill.render( |
|
814 |
render('admin/settings/settings. |
|
|
664 | render('admin/settings/settings.mako'), | |
|
815 | 665 | defaults=self._form_defaults(), |
|
816 | 666 | encoding='UTF-8', |
|
817 | 667 | force_defaults=False) |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -109,7 +109,7 b' class UserGroupsController(BaseControlle' | |||
|
109 | 109 | # url('users_groups') |
|
110 | 110 | |
|
111 | 111 | from rhodecode.lib.utils import PartialRenderer |
|
112 |
_render = PartialRenderer('data_table/_dt_elements. |
|
|
112 | _render = PartialRenderer('data_table/_dt_elements.mako') | |
|
113 | 113 | |
|
114 | 114 | def user_group_name(user_group_id, user_group_name): |
|
115 | 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 | 138 | c.data = json.dumps(user_groups_data) |
|
139 |
return render('admin/user_groups/user_groups. |
|
|
139 | return render('admin/user_groups/user_groups.mako') | |
|
140 | 140 | |
|
141 | 141 | @HasPermissionAnyDecorator('hg.admin', 'hg.usergroup.create.true') |
|
142 | 142 | @auth.CSRFRequired() |
@@ -167,7 +167,7 b' class UserGroupsController(BaseControlle' | |||
|
167 | 167 | Session().commit() |
|
168 | 168 | except formencode.Invalid as errors: |
|
169 | 169 | return htmlfill.render( |
|
170 |
render('admin/user_groups/user_group_add. |
|
|
170 | render('admin/user_groups/user_group_add.mako'), | |
|
171 | 171 | defaults=errors.value, |
|
172 | 172 | errors=errors.error_dict or {}, |
|
173 | 173 | prefix_error=False, |
@@ -185,7 +185,7 b' class UserGroupsController(BaseControlle' | |||
|
185 | 185 | def new(self): |
|
186 | 186 | """GET /user_groups/new: Form to create a new item""" |
|
187 | 187 | # url('new_users_group') |
|
188 |
return render('admin/user_groups/user_group_add. |
|
|
188 | return render('admin/user_groups/user_group_add.mako') | |
|
189 | 189 | |
|
190 | 190 | @HasUserGroupPermissionAnyDecorator('usergroup.admin') |
|
191 | 191 | @auth.CSRFRequired() |
@@ -224,7 +224,7 b' class UserGroupsController(BaseControlle' | |||
|
224 | 224 | e = errors.error_dict or {} |
|
225 | 225 | |
|
226 | 226 | return htmlfill.render( |
|
227 |
render('admin/user_groups/user_group_edit. |
|
|
227 | render('admin/user_groups/user_group_edit.mako'), | |
|
228 | 228 | defaults=defaults, |
|
229 | 229 | errors=e, |
|
230 | 230 | prefix_error=False, |
@@ -276,7 +276,7 b' class UserGroupsController(BaseControlle' | |||
|
276 | 276 | defaults = self.__load_defaults(user_group_id) |
|
277 | 277 | |
|
278 | 278 | return htmlfill.render( |
|
279 |
render('admin/user_groups/user_group_edit. |
|
|
279 | render('admin/user_groups/user_group_edit.mako'), | |
|
280 | 280 | defaults=defaults, |
|
281 | 281 | encoding="UTF-8", |
|
282 | 282 | force_defaults=False |
@@ -299,7 +299,7 b' class UserGroupsController(BaseControlle' | |||
|
299 | 299 | p.permission.permission_name}) |
|
300 | 300 | |
|
301 | 301 | return htmlfill.render( |
|
302 |
render('admin/user_groups/user_group_edit. |
|
|
302 | render('admin/user_groups/user_group_edit.mako'), | |
|
303 | 303 | defaults=defaults, |
|
304 | 304 | encoding="UTF-8", |
|
305 | 305 | force_defaults=False |
@@ -365,7 +365,7 b' class UserGroupsController(BaseControlle' | |||
|
365 | 365 | permissions['repositories_groups'][gr.group.group_name] \ |
|
366 | 366 | = gr.permission.permission_name |
|
367 | 367 | c.permissions = permissions |
|
368 |
return render('admin/user_groups/user_group_edit. |
|
|
368 | return render('admin/user_groups/user_group_edit.mako') | |
|
369 | 369 | |
|
370 | 370 | @HasUserGroupPermissionAnyDecorator('usergroup.admin') |
|
371 | 371 | def edit_global_perms(self, user_group_id): |
@@ -379,7 +379,7 b' class UserGroupsController(BaseControlle' | |||
|
379 | 379 | defaults.update(c.user_group.get_default_perms()) |
|
380 | 380 | |
|
381 | 381 | return htmlfill.render( |
|
382 |
render('admin/user_groups/user_group_edit. |
|
|
382 | render('admin/user_groups/user_group_edit.mako'), | |
|
383 | 383 | defaults=defaults, |
|
384 | 384 | encoding="UTF-8", |
|
385 | 385 | force_defaults=False |
@@ -425,7 +425,7 b' class UserGroupsController(BaseControlle' | |||
|
425 | 425 | defaults = errors.value |
|
426 | 426 | c.user_group = user_group |
|
427 | 427 | return htmlfill.render( |
|
428 |
render('admin/user_groups/user_group_edit. |
|
|
428 | render('admin/user_groups/user_group_edit.mako'), | |
|
429 | 429 | defaults=defaults, |
|
430 | 430 | errors=errors.error_dict or {}, |
|
431 | 431 | prefix_error=False, |
@@ -456,7 +456,7 b' class UserGroupsController(BaseControlle' | |||
|
456 | 456 | (x.group for x in c.user_group.users_group_repo_group_to_perm), |
|
457 | 457 | key=lambda u: u.group_name.lower()) |
|
458 | 458 | |
|
459 |
return render('admin/user_groups/user_group_edit. |
|
|
459 | return render('admin/user_groups/user_group_edit.mako') | |
|
460 | 460 | |
|
461 | 461 | @HasUserGroupPermissionAnyDecorator('usergroup.admin') |
|
462 | 462 | @XHRRequired() |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -82,7 +82,7 b' class UsersController(BaseController):' | |||
|
82 | 82 | # url('users') |
|
83 | 83 | |
|
84 | 84 | from rhodecode.lib.utils import PartialRenderer |
|
85 |
_render = PartialRenderer('data_table/_dt_elements. |
|
|
85 | _render = PartialRenderer('data_table/_dt_elements.mako') | |
|
86 | 86 | |
|
87 | 87 | def username(user_id, username): |
|
88 | 88 | return _render("user_name", user_id, username) |
@@ -119,7 +119,7 b' class UsersController(BaseController):' | |||
|
119 | 119 | |
|
120 | 120 | |
|
121 | 121 | c.data = json.dumps(users_data) |
|
122 |
return render('admin/users/users. |
|
|
122 | return render('admin/users/users.mako') | |
|
123 | 123 | |
|
124 | 124 | def _get_personal_repo_group_template_vars(self): |
|
125 | 125 | DummyUser = AttributeDict({ |
@@ -156,7 +156,7 b' class UsersController(BaseController):' | |||
|
156 | 156 | except formencode.Invalid as errors: |
|
157 | 157 | self._get_personal_repo_group_template_vars() |
|
158 | 158 | return htmlfill.render( |
|
159 |
render('admin/users/user_add. |
|
|
159 | render('admin/users/user_add.mako'), | |
|
160 | 160 | defaults=errors.value, |
|
161 | 161 | errors=errors.error_dict or {}, |
|
162 | 162 | prefix_error=False, |
@@ -176,7 +176,7 b' class UsersController(BaseController):' | |||
|
176 | 176 | # url('new_user') |
|
177 | 177 | c.default_extern_type = auth_rhodecode.RhodeCodeAuthPlugin.name |
|
178 | 178 | self._get_personal_repo_group_template_vars() |
|
179 |
return render('admin/users/user_add. |
|
|
179 | return render('admin/users/user_add.mako') | |
|
180 | 180 | |
|
181 | 181 | @HasPermissionAllDecorator('hg.admin') |
|
182 | 182 | @auth.CSRFRequired() |
@@ -218,7 +218,7 b' class UsersController(BaseController):' | |||
|
218 | 218 | e = errors.error_dict or {} |
|
219 | 219 | |
|
220 | 220 | return htmlfill.render( |
|
221 |
render('admin/users/user_edit. |
|
|
221 | render('admin/users/user_edit.mako'), | |
|
222 | 222 | defaults=defaults, |
|
223 | 223 | errors=e, |
|
224 | 224 | prefix_error=False, |
@@ -414,7 +414,7 b' class UsersController(BaseController):' | |||
|
414 | 414 | defaults = c.user.get_dict() |
|
415 | 415 | defaults.update({'language': c.user.user_data.get('language')}) |
|
416 | 416 | return htmlfill.render( |
|
417 |
render('admin/users/user_edit. |
|
|
417 | render('admin/users/user_edit.mako'), | |
|
418 | 418 | defaults=defaults, |
|
419 | 419 | encoding="UTF-8", |
|
420 | 420 | force_defaults=False) |
@@ -446,7 +446,7 b' class UsersController(BaseController):' | |||
|
446 | 446 | '"inactive" instead of deleting it.') if has_review else '' |
|
447 | 447 | |
|
448 | 448 | return htmlfill.render( |
|
449 |
render('admin/users/user_edit. |
|
|
449 | render('admin/users/user_edit.mako'), | |
|
450 | 450 | defaults=defaults, |
|
451 | 451 | encoding="UTF-8", |
|
452 | 452 | force_defaults=False) |
@@ -476,7 +476,7 b' class UsersController(BaseController):' | |||
|
476 | 476 | c.user.user_id, show_expired=show_expired) |
|
477 | 477 | defaults = c.user.get_dict() |
|
478 | 478 | return htmlfill.render( |
|
479 |
render('admin/users/user_edit. |
|
|
479 | render('admin/users/user_edit.mako'), | |
|
480 | 480 | defaults=defaults, |
|
481 | 481 | encoding="UTF-8", |
|
482 | 482 | force_defaults=False) |
@@ -539,7 +539,7 b' class UsersController(BaseController):' | |||
|
539 | 539 | defaults.update(c.user.get_default_perms()) |
|
540 | 540 | |
|
541 | 541 | return htmlfill.render( |
|
542 |
render('admin/users/user_edit. |
|
|
542 | render('admin/users/user_edit.mako'), | |
|
543 | 543 | defaults=defaults, |
|
544 | 544 | encoding="UTF-8", |
|
545 | 545 | force_defaults=False) |
@@ -584,7 +584,7 b' class UsersController(BaseController):' | |||
|
584 | 584 | defaults = errors.value |
|
585 | 585 | c.user = user |
|
586 | 586 | return htmlfill.render( |
|
587 |
render('admin/users/user_edit. |
|
|
587 | render('admin/users/user_edit.mako'), | |
|
588 | 588 | defaults=defaults, |
|
589 | 589 | errors=errors.error_dict or {}, |
|
590 | 590 | prefix_error=False, |
@@ -607,7 +607,7 b' class UsersController(BaseController):' | |||
|
607 | 607 | c.active = 'perms_summary' |
|
608 | 608 | c.perm_user = AuthUser(user_id=user_id, ip_addr=self.ip_addr) |
|
609 | 609 | |
|
610 |
return render('admin/users/user_edit. |
|
|
610 | return render('admin/users/user_edit.mako') | |
|
611 | 611 | |
|
612 | 612 | @HasPermissionAllDecorator('hg.admin') |
|
613 | 613 | def edit_emails(self, user_id): |
@@ -623,7 +623,7 b' class UsersController(BaseController):' | |||
|
623 | 623 | |
|
624 | 624 | defaults = c.user.get_dict() |
|
625 | 625 | return htmlfill.render( |
|
626 |
render('admin/users/user_edit. |
|
|
626 | render('admin/users/user_edit.mako'), | |
|
627 | 627 | defaults=defaults, |
|
628 | 628 | encoding="UTF-8", |
|
629 | 629 | force_defaults=False) |
@@ -685,7 +685,7 b' class UsersController(BaseController):' | |||
|
685 | 685 | |
|
686 | 686 | defaults = c.user.get_dict() |
|
687 | 687 | return htmlfill.render( |
|
688 |
render('admin/users/user_edit. |
|
|
688 | render('admin/users/user_edit.mako'), | |
|
689 | 689 | defaults=defaults, |
|
690 | 690 | encoding="UTF-8", |
|
691 | 691 | force_defaults=False) |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -34,8 +34,8 b' log = logging.getLogger(__name__)' | |||
|
34 | 34 | |
|
35 | 35 | class BookmarksController(BaseReferencesController): |
|
36 | 36 | |
|
37 |
partials_template = 'bookmarks/bookmarks_data. |
|
|
38 |
template = 'bookmarks/bookmarks. |
|
|
37 | partials_template = 'bookmarks/bookmarks_data.mako' | |
|
38 | template = 'bookmarks/bookmarks.mako' | |
|
39 | 39 | |
|
40 | 40 | def __before__(self): |
|
41 | 41 | super(BookmarksController, self).__before__() |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -34,8 +34,8 b' log = logging.getLogger(__name__)' | |||
|
34 | 34 | |
|
35 | 35 | class BranchesController(BaseReferencesController): |
|
36 | 36 | |
|
37 |
partials_template = 'branches/branches_data. |
|
|
38 |
template = 'branches/branches. |
|
|
37 | partials_template = 'branches/branches_data.mako' | |
|
38 | template = 'branches/branches.mako' | |
|
39 | 39 | |
|
40 | 40 | def __before__(self): |
|
41 | 41 | super(BranchesController, self).__before__() |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -30,7 +30,8 b' from pylons.i18n.translation import _' | |||
|
30 | 30 | from webob.exc import HTTPNotFound, HTTPBadRequest |
|
31 | 31 | |
|
32 | 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 | 35 | from rhodecode.lib.base import BaseRepoController, render |
|
35 | 36 | from rhodecode.lib.ext_json import json |
|
36 | 37 | from rhodecode.lib.graphmod import _colored, _dagwalker |
@@ -98,7 +99,7 b' class ChangelogController(BaseRepoContro' | |||
|
98 | 99 | redirect(h.url('changelog_home', repo_name=repo.repo_name)) |
|
99 | 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 | 104 | Generates a DAG graph for repo |
|
104 | 105 | |
@@ -106,12 +107,30 b' class ChangelogController(BaseRepoContro' | |||
|
106 | 107 | :param commits: list of commits |
|
107 | 108 | """ |
|
108 | 109 | if not commits: |
|
109 |
|
|
|
110 | return | |
|
110 | return json.dumps([]) | |
|
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 | 129 | dag = _dagwalker(repo, commits) |
|
113 | data = [['', vtx, edges] for vtx, edges in _colored(dag)] | |
|
114 | c.jsdata = json.dumps(data) | |
|
130 | ||
|
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 | 135 | def _check_if_valid_branch(self, branch_name, repo_name, f_path): |
|
117 | 136 | if branch_name not in c.rhodecode_repo.branches_all: |
@@ -120,26 +139,37 b' class ChangelogController(BaseRepoContro' | |||
|
120 | 139 | redirect(url('changelog_file_home', repo_name=repo_name, |
|
121 | 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 | 161 | @LoginRequired() |
|
124 | 162 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', |
|
125 | 163 | 'repository.admin') |
|
126 | 164 | def index(self, repo_name, revision=None, f_path=None): |
|
127 | 165 | commit_id = revision |
|
128 |
|
|
|
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 | 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 | 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 | 174 | c.selected_name = branch_name or book_name |
|
145 | 175 | if not commit_id and branch_name: |
@@ -147,6 +177,8 b' class ChangelogController(BaseRepoContro' | |||
|
147 | 177 | |
|
148 | 178 | c.changelog_for_path = f_path |
|
149 | 179 | pre_load = ['author', 'branch', 'date', 'message', 'parents'] |
|
180 | commit_ids = [] | |
|
181 | ||
|
150 | 182 | try: |
|
151 | 183 | if f_path: |
|
152 | 184 | log.debug('generating changelog for path %s', f_path) |
@@ -174,13 +206,9 b' class ChangelogController(BaseRepoContro' | |||
|
174 | 206 | collection = c.rhodecode_repo.get_commits( |
|
175 | 207 | branch_name=branch_name, pre_load=pre_load) |
|
176 | 208 | |
|
177 | c.total_cs = len(collection) | |
|
178 | c.showing_commits = min(c.size, c.total_cs) | |
|
179 | c.pagination = RepoPage(collection, page=p, item_count=c.total_cs, | |
|
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) | |
|
209 | self._load_changelog_data( | |
|
210 | collection, p, chunk_size, c.branch_name, dynamic=f_path) | |
|
211 | ||
|
184 | 212 | except EmptyRepositoryError as e: |
|
185 | 213 | h.flash(safe_str(e), category='warning') |
|
186 | 214 | return redirect(url('summary_home', repo_name=repo_name)) |
@@ -193,24 +221,64 b' class ChangelogController(BaseRepoContro' | |||
|
193 | 221 | if (request.environ.get('HTTP_X_PARTIAL_XHR') |
|
194 | 222 | or request.environ.get('HTTP_X_PJAX')): |
|
195 | 223 | # loading from ajax, we don't want the first result, it's popped |
|
196 |
return render('changelog/changelog_file_history. |
|
|
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: | |
|
199 | revs = [] | |
|
200 | else: | |
|
201 | revs = c.pagination | |
|
202 | self._graph(c.rhodecode_repo, revs) | |
|
229 | c.graph_data, c.graph_commits = self._graph( | |
|
230 | c.rhodecode_repo, commit_ids) | |
|
203 | 231 | |
|
204 |
return render('changelog/changelog. |
|
|
232 | return render('changelog/changelog.mako') | |
|
205 | 233 | |
|
206 | 234 | @LoginRequired() |
|
207 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', | |
|
208 | 'repository.admin') | |
|
209 | def changelog_details(self, commit_id): | |
|
210 | if request.environ.get('HTTP_X_PARTIAL_XHR'): | |
|
211 | c.commit = c.rhodecode_repo.get_commit(commit_id=commit_id) | |
|
212 | return render('changelog/changelog_details.html') | |
|
213 | raise HTTPNotFound() | |
|
235 | @XHRRequired() | |
|
236 | @HasRepoPermissionAnyDecorator( | |
|
237 | 'repository.read', 'repository.write', 'repository.admin') | |
|
238 | def changelog_elements(self, repo_name): | |
|
239 | commit_id = None | |
|
240 | chunk_size = 20 | |
|
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 | 283 | @LoginRequired() |
|
216 | 284 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', |
@@ -218,5 +286,5 b' class ChangelogController(BaseRepoContro' | |||
|
218 | 286 | def changelog_summary(self, repo_name): |
|
219 | 287 | if request.environ.get('HTTP_X_PJAX'): |
|
220 | 288 | _load_changelog_summary() |
|
221 |
return render('changelog/changelog_summary_data. |
|
|
289 | return render('changelog/changelog_summary_data.mako') | |
|
222 | 290 | raise HTTPNotFound() |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -46,7 +46,7 b' from rhodecode.lib.vcs.exceptions import' | |||
|
46 | 46 | RepositoryError, CommitDoesNotExistError, NodeDoesNotExistError) |
|
47 | 47 | from rhodecode.model.db import ChangesetComment, ChangesetStatus |
|
48 | 48 | from rhodecode.model.changeset_status import ChangesetStatusModel |
|
49 |
from rhodecode.model.comment import |
|
|
49 | from rhodecode.model.comment import CommentsModel | |
|
50 | 50 | from rhodecode.model.meta import Session |
|
51 | 51 | from rhodecode.model.repo import RepoModel |
|
52 | 52 | |
@@ -198,15 +198,20 b' class ChangesetController(BaseRepoContro' | |||
|
198 | 198 | c.lines_added = 0 |
|
199 | 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 | 205 | c.commit_statuses = ChangesetStatus.STATUSES |
|
202 | 206 | c.inline_comments = [] |
|
203 | 207 | c.files = [] |
|
204 | 208 | |
|
205 | 209 | c.statuses = [] |
|
206 | 210 | c.comments = [] |
|
211 | c.unresolved_comments = [] | |
|
207 | 212 | if len(c.commit_ranges) == 1: |
|
208 | 213 | commit = c.commit_ranges[0] |
|
209 |
c.comments = |
|
|
214 | c.comments = CommentsModel().get_comments( | |
|
210 | 215 | c.rhodecode_db_repo.repo_id, |
|
211 | 216 | revision=commit.raw_id) |
|
212 | 217 | c.statuses.append(ChangesetStatusModel().get_status( |
@@ -222,6 +227,9 b' class ChangesetController(BaseRepoContro' | |||
|
222 | 227 | for pr in prs: |
|
223 | 228 | c.comments.extend(pr.comments) |
|
224 | 229 | |
|
230 | c.unresolved_comments = CommentsModel()\ | |
|
231 | .get_commit_unresolved_todos(commit.raw_id) | |
|
232 | ||
|
225 | 233 | # Iterate over ranges (default commit view is always one commit) |
|
226 | 234 | for commit in c.commit_ranges: |
|
227 | 235 | c.changes[commit.raw_id] = [] |
@@ -251,9 +259,9 b' class ChangesetController(BaseRepoContro' | |||
|
251 | 259 | return None |
|
252 | 260 | return get_node |
|
253 | 261 | |
|
254 |
inline_comments = |
|
|
262 | inline_comments = CommentsModel().get_inline_comments( | |
|
255 | 263 | c.rhodecode_db_repo.repo_id, revision=commit.raw_id) |
|
256 |
c.inline_cnt = |
|
|
264 | c.inline_cnt = CommentsModel().get_inline_comments_count( | |
|
257 | 265 | inline_comments) |
|
258 | 266 | |
|
259 | 267 | diffset = codeblocks.DiffSet( |
@@ -271,7 +279,6 b' class ChangesetController(BaseRepoContro' | |||
|
271 | 279 | # sort comments by how they were generated |
|
272 | 280 | c.comments = sorted(c.comments, key=lambda x: x.comment_id) |
|
273 | 281 | |
|
274 | ||
|
275 | 282 | if len(c.commit_ranges) == 1: |
|
276 | 283 | c.commit = c.commit_ranges[0] |
|
277 | 284 | c.parent_tmpl = ''.join( |
@@ -284,17 +291,17 b' class ChangesetController(BaseRepoContro' | |||
|
284 | 291 | elif method == 'patch': |
|
285 | 292 | response.content_type = 'text/plain' |
|
286 | 293 | c.diff = safe_unicode(diff) |
|
287 |
return render('changeset/patch_changeset. |
|
|
294 | return render('changeset/patch_changeset.mako') | |
|
288 | 295 | elif method == 'raw': |
|
289 | 296 | response.content_type = 'text/plain' |
|
290 | 297 | return diff |
|
291 | 298 | elif method == 'show': |
|
292 | 299 | if len(c.commit_ranges) == 1: |
|
293 |
return render('changeset/changeset. |
|
|
300 | return render('changeset/changeset.mako') | |
|
294 | 301 | else: |
|
295 | 302 | c.ancestor = None |
|
296 | 303 | c.target_repo = c.rhodecode_db_repo |
|
297 |
return render('changeset/changeset_range. |
|
|
304 | return render('changeset/changeset_range.mako') | |
|
298 | 305 | |
|
299 | 306 | @LoginRequired() |
|
300 | 307 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', |
@@ -330,29 +337,39 b' class ChangesetController(BaseRepoContro' | |||
|
330 | 337 | commit_id = revision |
|
331 | 338 | status = request.POST.get('changeset_status', None) |
|
332 | 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 | 343 | if status: |
|
334 | 344 | text = text or (_('Status change %(transition_icon)s %(status)s') |
|
335 | 345 | % {'transition_icon': '>', |
|
336 | 346 | 'status': ChangesetStatus.get_status_lbl(status)}) |
|
337 | 347 | |
|
338 |
multi_commit_ids = |
|
|
339 | lambda s: s not in ['', None], | |
|
340 | request.POST.get('commit_ids', '').split(','),) | |
|
348 | multi_commit_ids = [] | |
|
349 | for _commit_id in 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 | 354 | commit_ids = multi_commit_ids or [commit_id] |
|
355 | ||
|
343 | 356 | comment = None |
|
344 | 357 | for current_id in filter(None, commit_ids): |
|
345 |
c.co = comment = |
|
|
358 | c.co = comment = CommentsModel().create( | |
|
346 | 359 | text=text, |
|
347 | 360 | repo=c.rhodecode_db_repo.repo_id, |
|
348 | 361 | user=c.rhodecode_user.user_id, |
|
349 |
|
|
|
362 | commit_id=current_id, | |
|
350 | 363 | f_path=request.POST.get('f_path'), |
|
351 | 364 | line_no=request.POST.get('line'), |
|
352 | 365 | status_change=(ChangesetStatus.get_status_lbl(status) |
|
353 | 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 | 373 | # get status if set ! |
|
357 | 374 | if status: |
|
358 | 375 | # if latest status was from pull request and it's closed |
@@ -386,7 +403,7 b' class ChangesetController(BaseRepoContro' | |||
|
386 | 403 | if comment: |
|
387 | 404 | data.update(comment.get_dict()) |
|
388 | 405 | data.update({'rendered_text': |
|
389 |
render('changeset/changeset_comment_block. |
|
|
406 | render('changeset/changeset_comment_block.mako')}) | |
|
390 | 407 | |
|
391 | 408 | return data |
|
392 | 409 | |
@@ -417,10 +434,15 b' class ChangesetController(BaseRepoContro' | |||
|
417 | 434 | @jsonify |
|
418 | 435 | def delete_comment(self, repo_name, comment_id): |
|
419 | 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 | 442 | owner = (comment.author.user_id == c.rhodecode_user.user_id) |
|
421 | 443 | is_repo_admin = h.HasRepoPermissionAny('repository.admin')(c.repo_name) |
|
422 | 444 | if h.HasPermissionAny('hg.admin')() or is_repo_admin or owner: |
|
423 |
|
|
|
445 | CommentsModel().delete(comment=comment) | |
|
424 | 446 | Session().commit() |
|
425 | 447 | return True |
|
426 | 448 | else: |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2012-201 |
|
|
3 | # Copyright (C) 2012-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -79,6 +79,7 b' class CompareController(BaseRepoControll' | |||
|
79 | 79 | def index(self, repo_name): |
|
80 | 80 | c.compare_home = True |
|
81 | 81 | c.commit_ranges = [] |
|
82 | c.collapse_all_commits = False | |
|
82 | 83 | c.diffset = None |
|
83 | 84 | c.limited_diff = False |
|
84 | 85 | source_repo = c.rhodecode_db_repo.repo_name |
@@ -90,7 +91,8 b' class CompareController(BaseRepoControll' | |||
|
90 | 91 | c.target_ref_type = "" |
|
91 | 92 | c.commit_statuses = ChangesetStatus.STATUSES |
|
92 | 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 | 97 | @LoginRequired() |
|
96 | 98 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', |
@@ -103,8 +105,10 b' class CompareController(BaseRepoControll' | |||
|
103 | 105 | |
|
104 | 106 | # target_ref will be evaluated in target_repo |
|
105 | 107 | target_repo_name = request.GET.get('target_repo', source_repo_name) |
|
106 |
target_path, target_id = parse_path_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 | 112 | c.commit_statuses = ChangesetStatus.STATUSES |
|
109 | 113 | |
|
110 | 114 | # if merge is True |
@@ -115,7 +119,6 b' class CompareController(BaseRepoControll' | |||
|
115 | 119 | # if merge is False |
|
116 | 120 | # Show a raw diff of source/target refs even if no ancestor exists |
|
117 | 121 | |
|
118 | ||
|
119 | 122 | # c.fulldiff disables cut_off_limit |
|
120 | 123 | c.fulldiff = str2bool(request.GET.get('fulldiff')) |
|
121 | 124 | |
@@ -131,7 +134,8 b' class CompareController(BaseRepoControll' | |||
|
131 | 134 | target_repo=source_repo_name, |
|
132 | 135 | target_ref_type=source_ref_type, |
|
133 | 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 | 140 | source_repo = Repository.get_by_repo_name(source_repo_name) |
|
137 | 141 | target_repo = Repository.get_by_repo_name(target_repo_name) |
@@ -151,8 +155,11 b' class CompareController(BaseRepoControll' | |||
|
151 | 155 | h.flash(msg, category='error') |
|
152 | 156 | return redirect(url('compare_home', repo_name=c.repo_name)) |
|
153 | 157 | |
|
154 |
source_ |
|
|
155 |
target_ |
|
|
158 | source_scm = source_repo.scm_instance() | |
|
159 | target_scm = target_repo.scm_instance() | |
|
160 | ||
|
161 | source_alias = source_scm.alias | |
|
162 | target_alias = target_scm.alias | |
|
156 | 163 | if source_alias != target_alias: |
|
157 | 164 | msg = _('The comparison of two different kinds of remote repos ' |
|
158 | 165 | 'is not available') |
@@ -175,34 +182,42 b' class CompareController(BaseRepoControll' | |||
|
175 | 182 | c.source_ref_type = source_ref_type |
|
176 | 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 | 185 | pre_load = ["author", "branch", "date", "message"] |
|
182 | 186 | c.ancestor = None |
|
183 | try: | |
|
184 | c.commit_ranges = source_scm.compare( | |
|
185 |
|
|
|
186 | target_scm, merge, pre_load=pre_load) | |
|
187 |
|
|
|
188 |
c. |
|
|
189 | source_commit.raw_id, target_commit.raw_id, target_scm) | |
|
190 | except RepositoryRequirementError: | |
|
191 | msg = _('Could not compare repos with different ' | |
|
192 | 'large file settings') | |
|
193 | log.error(msg) | |
|
194 |
if |
|
|
195 | return msg | |
|
196 | h.flash(msg, category='error') | |
|
197 | return redirect(url('compare_home', repo_name=c.repo_name)) | |
|
187 | ||
|
188 | if c.file_path: | |
|
189 | if source_commit == target_commit: | |
|
190 | c.commit_ranges = [] | |
|
191 | else: | |
|
192 | c.commit_ranges = [target_commit] | |
|
193 | else: | |
|
194 | try: | |
|
195 | c.commit_ranges = source_scm.compare( | |
|
196 | source_commit.raw_id, target_commit.raw_id, | |
|
197 | target_scm, merge, pre_load=pre_load) | |
|
198 | if merge: | |
|
199 | c.ancestor = source_scm.get_common_ancestor( | |
|
200 | source_commit.raw_id, target_commit.raw_id, target_scm) | |
|
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 | 210 | c.statuses = c.rhodecode_db_repo.statuses( |
|
200 | 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 | 218 | if not c.ancestor: |
|
204 | return '' # cannot merge if there is no ancestor | |
|
205 |
return render('compare/compare_commits. |
|
|
219 | return '' # cannot merge if there is no ancestor | |
|
220 | return render('compare/compare_commits.mako') | |
|
206 | 221 | |
|
207 | 222 | if c.ancestor: |
|
208 | 223 | # case we want a simple diff without incoming commits, |
@@ -238,7 +253,8 b' class CompareController(BaseRepoControll' | |||
|
238 | 253 | |
|
239 | 254 | txtdiff = source_repo.scm_instance().get_diff( |
|
240 | 255 | commit1=source_commit, commit2=target_commit, |
|
241 |
path1=source_path |
|
|
256 | path=target_path, path1=source_path) | |
|
257 | ||
|
242 | 258 | diff_processor = diffs.DiffProcessor( |
|
243 | 259 | txtdiff, format='newdiff', diff_limit=diff_limit, |
|
244 | 260 | file_limit=file_limit, show_full_diff=c.fulldiff) |
@@ -260,5 +276,7 b' class CompareController(BaseRepoControll' | |||
|
260 | 276 | ).render_patchset(_parsed, source_ref, target_ref) |
|
261 | 277 | |
|
262 | 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. |
|
|
282 | return render('compare/compare_diff.mako') |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2014-201 |
|
|
3 | # Copyright (C) 2014-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -144,7 +144,7 b' class FilesController(BaseRepoController' | |||
|
144 | 144 | log.debug('Generating cached file tree for %s, %s, %s', |
|
145 | 145 | repo_name, commit_id, f_path) |
|
146 | 146 | c.full_load = full_load |
|
147 |
return render('files/files_browser_tree. |
|
|
147 | return render('files/files_browser_tree.mako') | |
|
148 | 148 | |
|
149 | 149 | cache_manager = self.__get_tree_cache_manager( |
|
150 | 150 | repo_name, caches.FILE_TREE) |
@@ -255,9 +255,9 b' class FilesController(BaseRepoController' | |||
|
255 | 255 | raise HTTPNotFound() |
|
256 | 256 | |
|
257 | 257 | if request.environ.get('HTTP_X_PJAX'): |
|
258 |
return render('files/files_pjax. |
|
|
258 | return render('files/files_pjax.mako') | |
|
259 | 259 | |
|
260 |
return render('files/files. |
|
|
260 | return render('files/files.mako') | |
|
261 | 261 | |
|
262 | 262 | @LoginRequired() |
|
263 | 263 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', |
@@ -305,7 +305,7 b' class FilesController(BaseRepoController' | |||
|
305 | 305 | c.authors.append(( |
|
306 | 306 | h.email(author), |
|
307 | 307 | h.person(author, 'username_or_name_or_email'))) |
|
308 |
return render('files/file_authors_box. |
|
|
308 | return render('files/file_authors_box.mako') | |
|
309 | 309 | |
|
310 | 310 | @LoginRequired() |
|
311 | 311 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', |
@@ -465,7 +465,7 b' class FilesController(BaseRepoController' | |||
|
465 | 465 | 'Deleted file %s via RhodeCode Enterprise') % (f_path) |
|
466 | 466 | c.f_path = f_path |
|
467 | 467 | |
|
468 |
return render('files/files_delete. |
|
|
468 | return render('files/files_delete.mako') | |
|
469 | 469 | |
|
470 | 470 | @CSRFRequired() |
|
471 | 471 | @LoginRequired() |
@@ -574,7 +574,7 b' class FilesController(BaseRepoController' | |||
|
574 | 574 | 'Edited file %s via RhodeCode Enterprise') % (f_path) |
|
575 | 575 | c.f_path = f_path |
|
576 | 576 | |
|
577 |
return render('files/files_edit. |
|
|
577 | return render('files/files_edit.mako') | |
|
578 | 578 | |
|
579 | 579 | def _is_valid_head(self, commit_id, repo): |
|
580 | 580 | # check if commit is a branch identifier- basically we cannot |
@@ -700,7 +700,7 b' class FilesController(BaseRepoController' | |||
|
700 | 700 | c.default_message = (_('Added file via RhodeCode Enterprise')) |
|
701 | 701 | c.f_path = f_path |
|
702 | 702 | |
|
703 |
return render('files/files_add. |
|
|
703 | return render('files/files_add.mako') | |
|
704 | 704 | |
|
705 | 705 | @LoginRequired() |
|
706 | 706 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', |
@@ -799,21 +799,15 b' class FilesController(BaseRepoController' | |||
|
799 | 799 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', |
|
800 | 800 | 'repository.admin') |
|
801 | 801 | def diff(self, repo_name, f_path): |
|
802 | ignore_whitespace = request.GET.get('ignorews') == '1' | |
|
803 |
|
|
|
802 | ||
|
803 | c.action = request.GET.get('diff') | |
|
804 | 804 | diff1 = request.GET.get('diff1', '') |
|
805 | diff2 = request.GET.get('diff2', '') | |
|
805 | 806 | |
|
806 | 807 | path1, diff1 = parse_path_ref(diff1, default_path=f_path) |
|
807 | 808 | |
|
808 | diff2 = request.GET.get('diff2', '') | |
|
809 |
|
|
|
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] = [] | |
|
809 | ignore_whitespace = str2bool(request.GET.get('ignorews')) | |
|
810 | line_context = request.GET.get('context', 3) | |
|
817 | 811 | |
|
818 | 812 | if not any((diff1, diff2)): |
|
819 | 813 | h.flash( |
@@ -821,18 +815,16 b' class FilesController(BaseRepoController' | |||
|
821 | 815 | category='error') |
|
822 | 816 | raise HTTPBadRequest() |
|
823 | 817 | |
|
824 | # special case if we want a show commit_id only, it's impl here | |
|
825 | # to reduce JS and callbacks | |
|
826 | ||
|
827 | if request.GET.get('show_rev') and diff1: | |
|
828 | if str2bool(request.GET.get('annotate', 'False')): | |
|
829 | _url = url('files_annotate_home', repo_name=c.repo_name, | |
|
830 | revision=diff1, f_path=path1) | |
|
831 | else: | |
|
832 | _url = url('files_home', repo_name=c.repo_name, | |
|
833 |
|
|
|
834 | ||
|
835 | return redirect(_url) | |
|
818 | if c.action not in ['download', 'raw']: | |
|
819 | # redirect to new view if we render diff | |
|
820 | return redirect( | |
|
821 | url('compare_url', repo_name=repo_name, | |
|
822 | source_ref_type='rev', | |
|
823 | source_ref=diff1, | |
|
824 | target_repo=c.repo_name, | |
|
825 | target_ref_type='rev', | |
|
826 | target_ref=diff2, | |
|
827 | f_path=f_path)) | |
|
836 | 828 | |
|
837 | 829 | try: |
|
838 | 830 | node1 = self._get_file_node(diff1, path1) |
@@ -877,98 +869,40 b' class FilesController(BaseRepoController' | |||
|
877 | 869 | return diff.as_raw() |
|
878 | 870 | |
|
879 | 871 | else: |
|
880 | fid = h.FID(diff2, node2.path) | |
|
881 | line_context_lcl = get_line_ctx(fid, request.GET) | |
|
882 | ign_whitespace_lcl = get_ignore_ws(fid, request.GET) | |
|
883 | ||
|
884 | __, commit1, commit2, diff, st, data = diffs.wrapped_diff( | |
|
885 | filenode_old=node1, | |
|
886 | filenode_new=node2, | |
|
887 | diff_limit=self.cut_off_limit_diff, | |
|
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') | |
|
872 | return redirect( | |
|
873 | url('compare_url', repo_name=repo_name, | |
|
874 | source_ref_type='rev', | |
|
875 | source_ref=diff1, | |
|
876 | target_repo=c.repo_name, | |
|
877 | target_ref_type='rev', | |
|
878 | target_ref=diff2, | |
|
879 | f_path=f_path)) | |
|
917 | 880 | |
|
918 | 881 | @LoginRequired() |
|
919 | 882 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', |
|
920 | 883 | 'repository.admin') |
|
921 | 884 | def diff_2way(self, repo_name, f_path): |
|
885 | """ | |
|
886 | Kept only to make OLD links work | |
|
887 | """ | |
|
922 | 888 | diff1 = request.GET.get('diff1', '') |
|
923 | 889 | diff2 = request.GET.get('diff2', '') |
|
924 | 890 | |
|
925 | nodes = [] | |
|
926 | unknown_commits = [] | |
|
927 | for commit in [diff1, diff2]: | |
|
928 |
|
|
|
929 | nodes.append(self._get_file_node(commit, f_path)) | |
|
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 | |
|
891 | if not any((diff1, diff2)): | |
|
892 | h.flash( | |
|
893 | 'Need query parameter "diff1" or "diff2" to generate a diff.', | |
|
894 | category='error') | |
|
895 | raise HTTPBadRequest() | |
|
945 | 896 | |
|
946 | f_gitdiff = diffs.get_gitdiff(node1, node2, ignore_whitespace=False) | |
|
947 | diff_processor = diffs.DiffProcessor(f_gitdiff, format='gitdiff') | |
|
948 | diff_data = diff_processor.prepare() | |
|
949 | ||
|
950 | if not diff_data or diff_data[0]['raw_diff'] == '': | |
|
951 | h.flash(h.literal(_('%(file_path)s has not changed ' | |
|
952 | 'between %(commit_1)s and %(commit_2)s.') % { | |
|
953 |
|
|
|
954 | 'commit_1': node1.commit.id, | |
|
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') | |
|
897 | return redirect( | |
|
898 | url('compare_url', repo_name=repo_name, | |
|
899 | source_ref_type='rev', | |
|
900 | source_ref=diff1, | |
|
901 | target_repo=c.repo_name, | |
|
902 | target_ref_type='rev', | |
|
903 | target_ref=diff2, | |
|
904 | f_path=f_path, | |
|
905 | diffmode='sideside')) | |
|
972 | 906 | |
|
973 | 907 | def _get_file_node(self, commit_id, f_path): |
|
974 | 908 | if commit_id not in ['', None, 'None', '0' * 12, '0' * 40]: |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -50,9 +50,9 b' class FollowersController(BaseRepoContro' | |||
|
50 | 50 | .order_by(UserFollowing.follows_from) |
|
51 | 51 | c.followers_pager = Page(d, page=p, items_per_page=20) |
|
52 | 52 | |
|
53 |
c.followers_data = render('/followers/followers_data. |
|
|
53 | c.followers_data = render('/followers/followers_data.mako') | |
|
54 | 54 | |
|
55 | 55 | if request.environ.get('HTTP_X_PJAX'): |
|
56 | 56 | return c.followers_data |
|
57 | 57 | |
|
58 |
return render('/followers/followers. |
|
|
58 | return render('/followers/followers.mako') |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2011-201 |
|
|
3 | # Copyright (C) 2011-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -122,12 +122,12 b' class ForksController(BaseRepoController' | |||
|
122 | 122 | d.append(r) |
|
123 | 123 | c.forks_pager = Page(d, page=p, items_per_page=20) |
|
124 | 124 | |
|
125 |
c.forks_data = render('/forks/forks_data. |
|
|
125 | c.forks_data = render('/forks/forks_data.mako') | |
|
126 | 126 | |
|
127 | 127 | if request.environ.get('HTTP_X_PJAX'): |
|
128 | 128 | return c.forks_data |
|
129 | 129 | |
|
130 |
return render('/forks/forks. |
|
|
130 | return render('/forks/forks.mako') | |
|
131 | 131 | |
|
132 | 132 | @LoginRequired() |
|
133 | 133 | @NotAnonymous() |
@@ -144,7 +144,7 b' class ForksController(BaseRepoController' | |||
|
144 | 144 | defaults = self.__load_data(repo_name) |
|
145 | 145 | |
|
146 | 146 | return htmlfill.render( |
|
147 |
render('forks/fork. |
|
|
147 | render('forks/fork.mako'), | |
|
148 | 148 | defaults=defaults, |
|
149 | 149 | encoding="UTF-8", |
|
150 | 150 | force_defaults=False |
@@ -177,7 +177,7 b' class ForksController(BaseRepoController' | |||
|
177 | 177 | except formencode.Invalid as errors: |
|
178 | 178 | c.new_repo = errors.value['repo_name'] |
|
179 | 179 | return htmlfill.render( |
|
180 |
render('forks/fork. |
|
|
180 | render('forks/fork.mako'), | |
|
181 | 181 | defaults=errors.value, |
|
182 | 182 | errors=errors.error_dict or {}, |
|
183 | 183 | prefix_error=False, |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -97,7 +97,7 b' class HomeController(BaseController):' | |||
|
97 | 97 | c.repos_data = json.dumps(repo_data) |
|
98 | 98 | c.repo_groups_data = json.dumps(repo_group_data) |
|
99 | 99 | |
|
100 |
return render('/index. |
|
|
100 | return render('/index.mako') | |
|
101 | 101 | |
|
102 | 102 | @LoginRequired() |
|
103 | 103 | @HasRepoGroupPermissionAnyDecorator('group.read', 'group.write', |
@@ -112,7 +112,7 b' class HomeController(BaseController):' | |||
|
112 | 112 | c.repos_data = json.dumps(repo_data) |
|
113 | 113 | c.repo_groups_data = json.dumps(repo_group_data) |
|
114 | 114 | |
|
115 |
return render('index_repo_group. |
|
|
115 | return render('index_repo_group.mako') | |
|
116 | 116 | |
|
117 | 117 | def _get_repo_list(self, name_contains=None, repo_type=None, limit=20): |
|
118 | 118 | query = Repository.query()\ |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -205,11 +205,11 b' class JournalController(BaseController):' | |||
|
205 | 205 | c.journal_pager = Page(journal, page=p, items_per_page=20, url=url_generator) |
|
206 | 206 | c.journal_day_aggreagate = self._get_daily_aggregate(c.journal_pager) |
|
207 | 207 | |
|
208 |
c.journal_data = render('journal/journal_data. |
|
|
208 | c.journal_data = render('journal/journal_data.mako') | |
|
209 | 209 | if request.is_xhr: |
|
210 | 210 | return c.journal_data |
|
211 | 211 | |
|
212 |
return render('journal/journal. |
|
|
212 | return render('journal/journal.mako') | |
|
213 | 213 | |
|
214 | 214 | @LoginRequired(auth_token_access=True) |
|
215 | 215 | @NotAnonymous() |
@@ -276,10 +276,10 b' class JournalController(BaseController):' | |||
|
276 | 276 | |
|
277 | 277 | c.journal_day_aggreagate = self._get_daily_aggregate(c.journal_pager) |
|
278 | 278 | |
|
279 |
c.journal_data = render('journal/journal_data. |
|
|
279 | c.journal_data = render('journal/journal_data.mako') | |
|
280 | 280 | if request.is_xhr: |
|
281 | 281 | return c.journal_data |
|
282 |
return render('journal/public_journal. |
|
|
282 | return render('journal/public_journal.mako') | |
|
283 | 283 | |
|
284 | 284 | @LoginRequired(auth_token_access=True) |
|
285 | 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 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2012-201 |
|
|
3 | # Copyright (C) 2012-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -21,10 +21,12 b'' | |||
|
21 | 21 | """ |
|
22 | 22 | pull requests controller for rhodecode for initializing pull requests |
|
23 | 23 | """ |
|
24 | import types | |
|
24 | 25 | |
|
25 | 26 | import peppercorn |
|
26 | 27 | import formencode |
|
27 | 28 | import logging |
|
29 | import collections | |
|
28 | 30 | |
|
29 | 31 | from webob.exc import HTTPNotFound, HTTPForbidden, HTTPBadRequest |
|
30 | 32 | from pylons import request, tmpl_context as c, url |
@@ -43,125 +45,31 b' from rhodecode.lib.auth import (' | |||
|
43 | 45 | LoginRequired, HasRepoPermissionAnyDecorator, NotAnonymous, |
|
44 | 46 | HasAcceptedRepoType, XHRRequired) |
|
45 | 47 | from rhodecode.lib.channelstream import channelstream_request |
|
46 | from rhodecode.lib.compat import OrderedDict | |
|
47 | 48 | from rhodecode.lib.utils import jsonify |
|
48 |
from rhodecode.lib.utils2 import |
|
|
49 | from rhodecode.lib.vcs.backends.base import EmptyCommit, UpdateFailureReason | |
|
49 | from rhodecode.lib.utils2 import ( | |
|
50 | safe_int, safe_str, str2bool, safe_unicode) | |
|
51 | from rhodecode.lib.vcs.backends.base import ( | |
|
52 | EmptyCommit, UpdateFailureReason, EmptyRepository) | |
|
50 | 53 | from rhodecode.lib.vcs.exceptions import ( |
|
51 | 54 | EmptyRepositoryError, CommitDoesNotExistError, RepositoryRequirementError, |
|
52 | 55 | NodeDoesNotExistError) |
|
53 | from rhodecode.lib.diffs import LimitedDiffContainer | |
|
56 | ||
|
54 | 57 | from rhodecode.model.changeset_status import ChangesetStatusModel |
|
55 |
from rhodecode.model.comment import |
|
|
56 |
from rhodecode.model.db import PullRequest, ChangesetStatus, ChangesetComment, |
|
|
57 | Repository | |
|
58 | from rhodecode.model.comment import CommentsModel | |
|
59 | from rhodecode.model.db import (PullRequest, ChangesetStatus, ChangesetComment, | |
|
60 | Repository, PullRequestVersion) | |
|
58 | 61 | from rhodecode.model.forms import PullRequestForm |
|
59 | 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 | 65 | log = logging.getLogger(__name__) |
|
63 | 66 | |
|
64 | 67 | |
|
65 | 68 | class PullrequestsController(BaseRepoController): |
|
69 | ||
|
66 | 70 | def __before__(self): |
|
67 | 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 | 73 | def _extract_ordering(self, request): |
|
166 | 74 | column_index = safe_int(request.GET.get('order[0][column]')) |
|
167 | 75 | order_dir = request.GET.get('order[0][dir]', 'desc') |
@@ -205,7 +113,7 b' class PullrequestsController(BaseRepoCon' | |||
|
205 | 113 | if not request.is_xhr: |
|
206 | 114 | c.data = json.dumps(data['data']) |
|
207 | 115 | c.records_total = data['recordsTotal'] |
|
208 |
return render('/pullrequests/pullrequests. |
|
|
116 | return render('/pullrequests/pullrequests.mako') | |
|
209 | 117 | else: |
|
210 | 118 | return json.dumps(data) |
|
211 | 119 | |
@@ -244,10 +152,10 b' class PullrequestsController(BaseRepoCon' | |||
|
244 | 152 | opened_by=opened_by) |
|
245 | 153 | |
|
246 | 154 | from rhodecode.lib.utils import PartialRenderer |
|
247 |
_render = PartialRenderer('data_table/_dt_elements. |
|
|
155 | _render = PartialRenderer('data_table/_dt_elements.mako') | |
|
248 | 156 | data = [] |
|
249 | 157 | for pr in pull_requests: |
|
250 |
comments = |
|
|
158 | comments = CommentsModel().get_all_comments( | |
|
251 | 159 | c.rhodecode_db_repo.repo_id, pull_request=pr) |
|
252 | 160 | |
|
253 | 161 | data.append({ |
@@ -336,7 +244,7 b' class PullrequestsController(BaseRepoCon' | |||
|
336 | 244 | } |
|
337 | 245 | c.default_source_ref = selected_source_ref |
|
338 | 246 | |
|
339 |
return render('/pullrequests/pullrequest. |
|
|
247 | return render('/pullrequests/pullrequest.mako') | |
|
340 | 248 | |
|
341 | 249 | @LoginRequired() |
|
342 | 250 | @NotAnonymous() |
@@ -586,14 +494,20 b' class PullrequestsController(BaseRepoCon' | |||
|
586 | 494 | |
|
587 | 495 | Merge will perform a server-side merge of the specified |
|
588 | 496 | pull request, if the pull request is approved and mergeable. |
|
589 |
After succesfu |
|
|
497 | After successful merging, the pull request is automatically | |
|
590 | 498 | closed, with a relevant comment. |
|
591 | 499 | """ |
|
592 | 500 | pull_request_id = safe_int(pull_request_id) |
|
593 | 501 | pull_request = PullRequest.get_or_404(pull_request_id) |
|
594 | 502 | user = c.rhodecode_user |
|
595 | 503 | |
|
596 |
|
|
|
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 | 511 | log.debug("Pre-conditions checked, trying to merge.") |
|
598 | 512 | extras = vcs_operation_context( |
|
599 | 513 | request.environ, repo_name=pull_request.target_repo.repo_name, |
@@ -606,24 +520,6 b' class PullrequestsController(BaseRepoCon' | |||
|
606 | 520 | repo_name=pull_request.target_repo.repo_name, |
|
607 | 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 | 523 | def _merge_pull_request(self, pull_request, user, extras): |
|
628 | 524 | merge_resp = PullRequestModel().merge( |
|
629 | 525 | pull_request, user, extras=extras) |
@@ -675,82 +571,295 b' class PullrequestsController(BaseRepoCon' | |||
|
675 | 571 | return redirect(url('my_account_pullrequests')) |
|
676 | 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 | 630 | @LoginRequired() |
|
679 | 631 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', |
|
680 | 632 | 'repository.admin') |
|
681 | 633 | def show(self, repo_name, pull_request_id): |
|
682 | 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'] = \ | |
|
686 | pull_request_id | |
|
647 | c.at_version = at_version | |
|
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 | 670 | # pull_requests repo_name we opened it against |
|
689 | 671 | # ie. target_repo must match |
|
690 |
if repo_name != |
|
|
672 | if repo_name != pull_request_at_ver.target_repo.repo_name: | |
|
691 | 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 | 675 | c.shadow_clone_url = PullRequestModel().get_shadow_clone_url( |
|
700 |
|
|
|
701 | c.allowed_to_delete = PullRequestModel().check_user_delete( | |
|
702 | c.pull_request, c.rhodecode_user) and not c.pull_request.is_closed() | |
|
676 | pull_request_at_ver) | |
|
677 | ||
|
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() | |
|
709 | c.pr_merge_status, c.pr_merge_msg = PullRequestModel().merge_status( | |
|
710 | c.pull_request) | |
|
711 | c.approval_msg = None | |
|
712 | if c.pull_request_review_status != ChangesetStatus.STATUS_APPROVED: | |
|
713 | c.approval_msg = _('Reviewer approval is pending.') | |
|
714 | c.pr_merge_status = False | |
|
715 | # load compare data into template context | |
|
716 | enable_comments = not c.pull_request.is_closed() | |
|
740 | # if we use version, then do not show later comments | |
|
741 | # than current version | |
|
742 | display_inline_comments = collections.defaultdict( | |
|
743 | lambda: collections.defaultdict(list)) | |
|
744 | for co in inline_comments: | |
|
745 | if c.at_version_num: | |
|
746 | # pick comments that are at least UPTO given version, so we | |
|
747 | # don't render comments for higher version | |
|
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 | |
|
720 | c.inline_comments = cc_model.get_inline_comments( | |
|
721 | c.rhodecode_db_repo.repo_id, | |
|
722 | pull_request=pull_request_id) | |
|
770 | # despite opening commits for bookmarks/branches/tags, we always | |
|
771 | # convert this to rev to prevent changes after bookmark or branch change | |
|
772 | c.source_ref_type = 'rev' | |
|
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( | |
|
727 | c.pull_request, c.inline_comments, enable_comments=enable_comments) | |
|
792 | # try first shadow repo, fallback to regular repo | |
|
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 | |
|
730 | c.outdated_comments = {} | |
|
731 | c.outdated_cnt = 0 | |
|
732 | if ChangesetCommentsModel.use_outdated_comments(c.pull_request): | |
|
733 | c.outdated_comments = cc_model.get_outdated_comments( | |
|
734 | c.rhodecode_db_repo.repo_id, | |
|
735 | pull_request=c.pull_request) | |
|
736 | # Count outdated comments and check for deleted files | |
|
737 | for file_name, lines in c.outdated_comments.iteritems(): | |
|
738 | for comments in lines.values(): | |
|
739 | c.outdated_cnt += len(comments) | |
|
740 | if file_name not in c.included_files: | |
|
741 | c.deleted_files.append(file_name) | |
|
810 | target_commit = commits_source_repo.get_commit( | |
|
811 | commit_id=safe_str(target_ref_id)) | |
|
812 | source_commit = commits_source_repo.get_commit( | |
|
813 | commit_id=safe_str(source_ref_id)) | |
|
814 | except CommitDoesNotExistError: | |
|
815 | pass | |
|
816 | except RepositoryRequirementError: | |
|
817 | log.warning( | |
|
818 | 'Failed to get all required data from repo', exc_info=True) | |
|
819 | c.missing_requirements = True | |
|
820 | ||
|
821 | c.statuses = source_repo.statuses( | |
|
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 | 857 | # this is a hack to properly display links, when creating PR, the |
|
745 | 858 | # compare view and others uses different notation, and |
|
746 |
# compare_commits. |
|
|
859 | # compare_commits.mako renders links based on the target_repo. | |
|
747 | 860 | # We need to swap that here to generate it properly on the html side |
|
748 | 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 | 863 | if c.allowed_to_update: |
|
755 | 864 | force_close = ('forced_closed', _('Close Pull Request')) |
|
756 | 865 | statuses = ChangesetStatus.STATUSES + [force_close] |
@@ -758,14 +867,55 b' class PullrequestsController(BaseRepoCon' | |||
|
758 | 867 | statuses = ChangesetStatus.STATUSES |
|
759 | 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 | 915 | @LoginRequired() |
|
766 | 916 | @NotAnonymous() |
|
767 |
@HasRepoPermissionAnyDecorator( |
|
|
768 | 'repository.admin') | |
|
917 | @HasRepoPermissionAnyDecorator( | |
|
918 | 'repository.read', 'repository.write', 'repository.admin') | |
|
769 | 919 | @auth.CSRFRequired() |
|
770 | 920 | @jsonify |
|
771 | 921 | def comment(self, repo_name, pull_request_id): |
@@ -778,6 +928,9 b' class PullrequestsController(BaseRepoCon' | |||
|
778 | 928 | # as a changeset status, still we want to send it in one value. |
|
779 | 929 | status = request.POST.get('changeset_status', None) |
|
780 | 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 | 934 | if status and '_closed' in status: |
|
782 | 935 | close_pr = True |
|
783 | 936 | status = status.replace('_closed', '') |
@@ -798,7 +951,7 b' class PullrequestsController(BaseRepoCon' | |||
|
798 | 951 | if close_pr: |
|
799 | 952 | message = _('Closing with') + ' ' + message |
|
800 | 953 | text = text or message |
|
801 |
comm = |
|
|
954 | comm = CommentsModel().create( | |
|
802 | 955 | text=text, |
|
803 | 956 | repo=c.rhodecode_db_repo.repo_id, |
|
804 | 957 | user=c.rhodecode_user.user_id, |
@@ -809,11 +962,11 b' class PullrequestsController(BaseRepoCon' | |||
|
809 | 962 | if status and allowed_to_change_status else None), |
|
810 | 963 | status_change_type=(status |
|
811 | 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 | 970 | if allowed_to_change_status: |
|
818 | 971 | old_calculated_status = pull_request.calculated_review_status() |
|
819 | 972 | # get status if set ! |
@@ -863,9 +1016,10 b' class PullrequestsController(BaseRepoCon' | |||
|
863 | 1016 | } |
|
864 | 1017 | if comm: |
|
865 | 1018 | c.co = comm |
|
1019 | c.inline_comment = True if comm.line_no else False | |
|
866 | 1020 | data.update(comm.get_dict()) |
|
867 | 1021 | data.update({'rendered_text': |
|
868 |
render('changeset/changeset_comment_block. |
|
|
1022 | render('changeset/changeset_comment_block.mako')}) | |
|
869 | 1023 | |
|
870 | 1024 | return data |
|
871 | 1025 | |
@@ -889,7 +1043,7 b' class PullrequestsController(BaseRepoCon' | |||
|
889 | 1043 | is_repo_admin = h.HasRepoPermissionAny('repository.admin')(c.repo_name) |
|
890 | 1044 | if h.HasPermissionAny('hg.admin')() or is_repo_admin or is_owner: |
|
891 | 1045 | old_calculated_status = co.pull_request.calculated_review_status() |
|
892 |
|
|
|
1046 | CommentsModel().delete(comment=co) | |
|
893 | 1047 | Session().commit() |
|
894 | 1048 | calculated_status = co.pull_request.calculated_review_status() |
|
895 | 1049 | if old_calculated_status != calculated_status: |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -108,4 +108,4 b' class SearchController(BaseRepoControlle' | |||
|
108 | 108 | c.cur_query = search_query |
|
109 | 109 | c.search_type = search_type |
|
110 | 110 | # Return a rendered template |
|
111 |
return render('/search/search. |
|
|
111 | return render('/search/search.mako') |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -165,7 +165,7 b' class SummaryController(BaseRepoControll' | |||
|
165 | 165 | c.repo_name, c.rhodecode_user.user_id) |
|
166 | 166 | |
|
167 | 167 | if c.repository_requirements_missing: |
|
168 |
return render('summary/missing_requirements. |
|
|
168 | return render('summary/missing_requirements.mako') | |
|
169 | 169 | |
|
170 | 170 | c.readme_data, c.readme_file = \ |
|
171 | 171 | self.__get_readme_data(c.rhodecode_db_repo) |
@@ -173,9 +173,9 b' class SummaryController(BaseRepoControll' | |||
|
173 | 173 | _load_changelog_summary() |
|
174 | 174 | |
|
175 | 175 | if request.is_xhr: |
|
176 |
return render('changelog/changelog_summary_data. |
|
|
176 | return render('changelog/changelog_summary_data.mako') | |
|
177 | 177 | |
|
178 |
return render('summary/summary. |
|
|
178 | return render('summary/summary.mako') | |
|
179 | 179 | |
|
180 | 180 | @LoginRequired() |
|
181 | 181 | @XHRRequired() |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -31,8 +31,8 b' log = logging.getLogger(__name__)' | |||
|
31 | 31 | |
|
32 | 32 | class TagsController(BaseReferencesController): |
|
33 | 33 | |
|
34 |
partials_template = 'tags/tags_data. |
|
|
35 |
template = 'tags/tags. |
|
|
34 | partials_template = 'tags/tags_data.mako' | |
|
35 | template = 'tags/tags.mako' | |
|
36 | 36 | |
|
37 | 37 | def _get_reference_items(self, repo): |
|
38 | 38 | return repo.tags.items() |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -40,4 +40,4 b' class UsersController(BaseController):' | |||
|
40 | 40 | raise HTTPNotFound() |
|
41 | 41 | |
|
42 | 42 | c.active = 'user_profile' |
|
43 |
return render('users/user. |
|
|
43 | return render('users/user.mako') |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -27,6 +27,7 b' Should only contain utilities to be shar' | |||
|
27 | 27 | from rhodecode.lib import helpers as h |
|
28 | 28 | from rhodecode.lib.vcs.exceptions import RepositoryError |
|
29 | 29 | |
|
30 | ||
|
30 | 31 | def parse_path_ref(ref, default_path=None): |
|
31 | 32 | """ |
|
32 | 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 | 79 | commit_id = ref_name |
|
79 | if repo_scm.alias != 'svn': # pass svn refs straight to backend until | |
|
80 | # the branch issue with svn is fixed | |
|
80 | if repo_scm.alias != 'svn': # pass svn refs straight to backend until | |
|
81 | # the branch issue with svn is fixed | |
|
81 | 82 | if ref_type and ref_type in ref_type_mapping: |
|
82 | 83 | try: |
|
83 | 84 | commit_id = ref_type_mapping[ref_type][ref_name] |
@@ -1,4 +1,4 b'' | |||
|
1 |
# Copyright (C) 2016-201 |
|
|
1 | # Copyright (C) 2016-2017 RhodeCode GmbH | |
|
2 | 2 | # |
|
3 | 3 | # This program is free software: you can redistribute it and/or modify |
|
4 | 4 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,4 +1,4 b'' | |||
|
1 |
# Copyright (C) 2016-201 |
|
|
1 | # Copyright (C) 2016-2017 RhodeCode GmbH | |
|
2 | 2 | # |
|
3 | 3 | # This program is free software: you can redistribute it and/or modify |
|
4 | 4 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,4 +1,4 b'' | |||
|
1 |
# Copyright (C) 2016-201 |
|
|
1 | # Copyright (C) 2016-2017 RhodeCode GmbH | |
|
2 | 2 | # |
|
3 | 3 | # This program is free software: you can redistribute it and/or modify |
|
4 | 4 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,4 +1,4 b'' | |||
|
1 |
# Copyright (C) 2016-201 |
|
|
1 | # Copyright (C) 2016-2017 RhodeCode GmbH | |
|
2 | 2 | # |
|
3 | 3 | # This program is free software: you can redistribute it and/or modify |
|
4 | 4 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -114,7 +114,7 b' class PullRequestCommentEvent(PullReques' | |||
|
114 | 114 | self.comment = comment |
|
115 | 115 | |
|
116 | 116 | def as_dict(self): |
|
117 |
from rhodecode.model.comment import |
|
|
117 | from rhodecode.model.comment import CommentsModel | |
|
118 | 118 | data = super(PullRequestCommentEvent, self).as_dict() |
|
119 | 119 | |
|
120 | 120 | status = None |
@@ -125,7 +125,7 b' class PullRequestCommentEvent(PullReques' | |||
|
125 | 125 | 'comment': { |
|
126 | 126 | 'status': status, |
|
127 | 127 | 'text': self.comment.text, |
|
128 |
'url': |
|
|
128 | 'url': CommentsModel().get_url(self.comment) | |
|
129 | 129 | } |
|
130 | 130 | }) |
|
131 | 131 | return data |
@@ -1,4 +1,4 b'' | |||
|
1 |
# Copyright (C) 2016-201 |
|
|
1 | # Copyright (C) 2016-2017 RhodeCode GmbH | |
|
2 | 2 | # |
|
3 | 3 | # This program is free software: you can redistribute it and/or modify |
|
4 | 4 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,4 +1,4 b'' | |||
|
1 |
# Copyright (C) 2016-201 |
|
|
1 | # Copyright (C) 2016-2017 RhodeCode GmbH | |
|
2 | 2 | # |
|
3 | 3 | # This program is free software: you can redistribute it and/or modify |
|
4 | 4 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,4 +1,4 b'' | |||
|
1 |
# Copyright (C) 2016-201 |
|
|
1 | # Copyright (C) 2016-2017 RhodeCode GmbH | |
|
2 | 2 | # |
|
3 | 3 | # This program is free software: you can redistribute it and/or modify |
|
4 | 4 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 |
# Copyright (C) 2010-201 |
|
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,5 +1,5 b'' | |||
|
1 | 1 | # Translations template for rhodecode-enterprise-ce. |
|
2 |
# Copyright (C) 201 |
|
|
2 | # Copyright (C) 2017 RhodeCode GmbH | |
|
3 | 3 | # This file is distributed under the same license as the rhodecode-enterprise-ce project. |
|
4 | 4 | # |
|
5 | 5 | # Translators: |
@@ -1,5 +1,5 b'' | |||
|
1 | 1 | # Translations template for rhodecode-enterprise-ce. |
|
2 |
# Copyright (C) 201 |
|
|
2 | # Copyright (C) 2017 RhodeCode GmbH | |
|
3 | 3 | # This file is distributed under the same license as the rhodecode-enterprise-ce project. |
|
4 | 4 | # |
|
5 | 5 | # Translators: |
@@ -1,5 +1,5 b'' | |||
|
1 | 1 | # Translations template for rhodecode-enterprise-ce. |
|
2 |
# Copyright (C) 201 |
|
|
2 | # Copyright (C) 2017 RhodeCode GmbH | |
|
3 | 3 | # This file is distributed under the same license as the rhodecode-enterprise-ce project. |
|
4 | 4 | # |
|
5 | 5 | # Translators: |
@@ -1,5 +1,5 b'' | |||
|
1 | 1 | # Translations template for rhodecode-enterprise-ce. |
|
2 |
# Copyright (C) 201 |
|
|
2 | # Copyright (C) 2017 RhodeCode GmbH | |
|
3 | 3 | # This file is distributed under the same license as the rhodecode-enterprise-ce project. |
|
4 | 4 | # |
|
5 | 5 | # Translators: |
@@ -1,5 +1,5 b'' | |||
|
1 | 1 | # Translations template for rhodecode-enterprise-ce. |
|
2 |
# Copyright (C) 201 |
|
|
2 | # Copyright (C) 2017 RhodeCode GmbH | |
|
3 | 3 | # This file is distributed under the same license as the rhodecode-enterprise-ce project. |
|
4 | 4 | # |
|
5 | 5 | # Translators: |
@@ -1,9 +1,9 b'' | |||
|
1 | 1 | # Translations template for rhodecode-enterprise-ce. |
|
2 |
# Copyright (C) 201 |
|
|
2 | # Copyright (C) 2017 RhodeCode GmbH | |
|
3 | 3 | # This file is distributed under the same license as the rhodecode-enterprise-ce project. |
|
4 | 4 | # |
|
5 | 5 | # Translators: |
|
6 |
# Alessandro sauzher Ceglie, 2014-201 |
|
|
6 | # Alessandro sauzher Ceglie, 2014-2017 | |
|
7 | 7 | # FIRST AUTHOR <EMAIL@ADDRESS>, 2014 |
|
8 | 8 | msgid "" |
|
9 | 9 | msgstr "" |
@@ -1,5 +1,5 b'' | |||
|
1 | 1 | # Translations template for rhodecode-enterprise-ce. |
|
2 |
# Copyright (C) 201 |
|
|
2 | # Copyright (C) 2017 RhodeCode GmbH | |
|
3 | 3 | # This file is distributed under the same license as the rhodecode-enterprise-ce project. |
|
4 | 4 | # |
|
5 | 5 | # Translators: |
@@ -1,5 +1,5 b'' | |||
|
1 | 1 | # Translations template for rhodecode-enterprise-ce. |
|
2 |
# Copyright (C) 201 |
|
|
2 | # Copyright (C) 2017 RhodeCode GmbH | |
|
3 | 3 | # This file is distributed under the same license as the rhodecode-enterprise-ce project. |
|
4 | 4 | # |
|
5 | 5 | # Translators: |
@@ -1,5 +1,5 b'' | |||
|
1 | 1 | # Translations template for rhodecode-enterprise-ce. |
|
2 |
# Copyright (C) 201 |
|
|
2 | # Copyright (C) 2017 RhodeCode GmbH | |
|
3 | 3 | # This file is distributed under the same license as the rhodecode-enterprise-ce project. |
|
4 | 4 | # |
|
5 | 5 | # Translators: |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | 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 | |
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 | |
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 | |
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 | |
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 | |
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 |
|
1 | 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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 |
|
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 |
|
1 | 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 | |
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 | |
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 | |
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 |
|
1 | 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 |
|
1 | 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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 |
|
1 | 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 | |
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 | |
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 |
|
1 | 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 |
|
1 | 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 | |
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 |
|
1 | 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 |
|
1 | 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 | |
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 | |
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 | |
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 | |
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 |
|
1 | 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 |
|
1 | 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 |
|
1 | 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 |
|
1 | 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 | |
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 |
|
1 | 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 | |
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 |
|
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 |
|
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 |
|
1 | 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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 |
|
1 | 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 | |
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 | |
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 | |
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 | |
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 | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | 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 | |
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 |
|
1 | 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 | |
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 | |
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 | |
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 | |
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 |
|
1 | 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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | 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 | |
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 | |
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 | |
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 |
|
1 | 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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | NO CONTENT: modified file | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | 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 |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed |
|
1 | 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 | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | 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 | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | 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 | |
The requested commit or file is too big and content was truncated. Show full diff |
|
1 | 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