Show More
The requested changes are too big and content was truncated. Show full diff
@@ -0,0 +1,60 b'' | |||||
|
1 | .. _user-session-ref: | |||
|
2 | ||||
|
3 | Increase User Session Performance | |||
|
4 | --------------------------------- | |||
|
5 | ||||
|
6 | The default file-based sessions are only suitable for smaller setups, or | |||
|
7 | instances that doesn't have a lot of users or traffic. | |||
|
8 | They are set as default option because it's setup-free solution. | |||
|
9 | ||||
|
10 | The most common issue of file based sessions are file limit errors which occur | |||
|
11 | if there are lots of session files. | |||
|
12 | ||||
|
13 | Therefore, in a large scale deployment, to give better performance, | |||
|
14 | scalability, and maintainability we recommend switching from file-based | |||
|
15 | sessions to database-based user sessions or memcached sessions. | |||
|
16 | ||||
|
17 | To switch to database-based user sessions uncomment the following section in | |||
|
18 | your :file:`/home/{user}/.rccontrol/{instance-id}/rhodecode.ini` file. | |||
|
19 | ||||
|
20 | ||||
|
21 | .. code-block:: ini | |||
|
22 | ||||
|
23 | ## db based session, fast, and allows easy management over logged in users | |||
|
24 | beaker.session.type = ext:database | |||
|
25 | beaker.session.table_name = db_session | |||
|
26 | ||||
|
27 | # use just one of the following accoring to the type of database | |||
|
28 | beaker.session.sa.url = postgresql://postgres:secret@localhost/rhodecode | |||
|
29 | beaker.session.sa.url = mysql://root:secret@127.0.0.1/rhodecode | |||
|
30 | ||||
|
31 | beaker.session.sa.pool_recycle = 3600 | |||
|
32 | beaker.session.sa.echo = false | |||
|
33 | ||||
|
34 | ||||
|
35 | and make sure you comment out the file based sessions. | |||
|
36 | ||||
|
37 | .. code-block:: ini | |||
|
38 | ||||
|
39 | ## types are file, ext:memcached, ext:database, and memory (default). | |||
|
40 | #beaker.session.type = file | |||
|
41 | #beaker.session.data_dir = %(here)s/data/sessions/data | |||
|
42 | ||||
|
43 | ||||
|
44 | To switch to memcached-based user sessions uncomment the following section in | |||
|
45 | your :file:`/home/{user}/.rccontrol/{instance-id}/rhodecode.ini` file. | |||
|
46 | ||||
|
47 | .. code-block:: ini | |||
|
48 | ||||
|
49 | ## memcached sessions | |||
|
50 | beaker.session.type = ext:memcached | |||
|
51 | beaker.session.url = localhost:11211 | |||
|
52 | ||||
|
53 | ||||
|
54 | and make sure you comment out the file based sessions. | |||
|
55 | ||||
|
56 | .. code-block:: ini | |||
|
57 | ||||
|
58 | ## types are file, ext:memcached, ext:database, and memory (default). | |||
|
59 | #beaker.session.type = file | |||
|
60 | #beaker.session.data_dir = %(here)s/data/sessions/data No newline at end of file |
@@ -0,0 +1,158 b'' | |||||
|
1 | |RCE| 4.6.0 |RNS| | |||
|
2 | ----------------- | |||
|
3 | ||||
|
4 | Release Date | |||
|
5 | ^^^^^^^^^^^^ | |||
|
6 | ||||
|
7 | - 2017-02-03 | |||
|
8 | ||||
|
9 | ||||
|
10 | New Features | |||
|
11 | ^^^^^^^^^^^^ | |||
|
12 | ||||
|
13 | - Pull requests: introduced versioning for pull requests. | |||
|
14 | Each update of pull requests creates and exposes a new version of it. | |||
|
15 | Users can navigate each version to show the previous state of pull request, or | |||
|
16 | generate diffs between versions to show what changed since the last update. | |||
|
17 | Also on each update attached comments are pinned to versions, so users can | |||
|
18 | tell at which state particular comment was made. | |||
|
19 | Various UI/UX fixes on PR page. | |||
|
20 | ||||
|
21 | - Pull requests: introduced new merge-checks. | |||
|
22 | Merge checks show nicer UI for the status of merge approval. | |||
|
23 | Merge checks now also forbid a merge if TODO notes are present. | |||
|
24 | Submitting a status will auto-refresh merge checks, it means that it's no | |||
|
25 | longer required to re-load diff to merge a PR. | |||
|
26 | Same logic is now used for API, pre-conditions on show, and checks on | |||
|
27 | actual merge API call. | |||
|
28 | ||||
|
29 | - Code review: approval state is now bound to pull request versioning. Users | |||
|
30 | can track their last approval and only show changes of pull requests between | |||
|
31 | their last approval and latest state. | |||
|
32 | - Code review: inline and main comments have now two types. a `note` and `todo`. | |||
|
33 | unresolved TODO comments show up in pull requests or commit view. | |||
|
34 | Unresolved TODO also prevents a PR from being merged. | |||
|
35 | - Code review: added navigation on outdated comments. | |||
|
36 | ||||
|
37 | - Diffs: compare mode overhaul. | |||
|
38 | Made compare and commit range pages more consistent with other commit | |||
|
39 | diff pages. Old diff2way is replaced by new diffs with side-by-side | |||
|
40 | mode, and it also removes mergerly. Cleanup button behaviour on the compare | |||
|
41 | page. Switched file-diffs to use the compare page with file filter. | |||
|
42 | Added collapse/expand commits buttons in compare views. Generally improved UX. | |||
|
43 | - Diffs: added a wide-mode button to expand large diffs. | |||
|
44 | ||||
|
45 | - Comments: an overhaul of comments forms. Adjust them for new comment types and | |||
|
46 | resolution comments. | |||
|
47 | - Comments: replaced a ctrl+space commands with slash commands. This becomes | |||
|
48 | more standardized and easier to use. | |||
|
49 | ||||
|
50 | - Changelog: added load more anchors into changelog view. | |||
|
51 | Users in changelog can now load comments via ajax and extend the data | |||
|
52 | set to show more than 100 commits. This also re-renders the graph. So it's | |||
|
53 | possible to show 1000s of commits in an efficient way with the DAG graph. | |||
|
54 | ||||
|
55 | - User sessions: added interface to show, and cleanup user auth sessions. | |||
|
56 | It's possible to show, and clean obsolete sessions. Also a cleanup of all | |||
|
57 | sessions option were added to completely log-out all users from the system. | |||
|
58 | ||||
|
59 | - Integrations: webhook integration have now additional setting to choose if | |||
|
60 | the call should be made with POST or GET. | |||
|
61 | ||||
|
62 | - API: get_repos call now allows to filter returned data by specifying a start | |||
|
63 | root location. Additionally, a traverse flag was added to define if returned | |||
|
64 | data should be only from top-level or recursive. | |||
|
65 | - API: comment_type (`note` or `todo`) for comment API. | |||
|
66 | - API: added comment_resolved_id into comments API to resolve TODO notes. | |||
|
67 | ||||
|
68 | ||||
|
69 | General | |||
|
70 | ^^^^^^^ | |||
|
71 | ||||
|
72 | - Api: comment_pull_request, added commit_id parameter to validate status | |||
|
73 | changed on particular commit. In case users set status on the commit | |||
|
74 | which is not current valid head this API call won't change the status anymore. | |||
|
75 | - Channelstream: added testing panel for live notifications. | |||
|
76 | - Authentication: disable password change form for accounts that are not | |||
|
77 | managed by RhodeCode, in the case of external accounts such as LDAP/oAuth, | |||
|
78 | password reset doesn't make sense. | |||
|
79 | - Core: let pyramid handle tracebacks for all exceptions. | |||
|
80 | Otherwise, we'll miss exception caused in pure pyramid views. | |||
|
81 | - Vcs server: expose remote tracebacks from HTTP backend using | |||
|
82 | the Pyro4AwareFormatter. This will now in most cases propagate VCSServer | |||
|
83 | exception into Enterprise logs for easier tracking of errors | |||
|
84 | - Ishell: updated code with latest iShell changes. | |||
|
85 | - Svn: generate HTTP downgrade via the auto-generated config. This allows | |||
|
86 | a HTTPs/HTTP configuration with SVN. | |||
|
87 | - Dependencies: bumped various pytest related libraries to latest versions. | |||
|
88 | - Dependencies: bumped gevent to 1.1.2 and greenlet to 0.4.10 versions. | |||
|
89 | - Dependencies: bumped msgpack to version 0.4.8. | |||
|
90 | - Dependencies: bumped supervisor to 3.3.1 version. | |||
|
91 | - Dependencies: bumped Whoosh to version 2.7.4. | |||
|
92 | - Dependencies: bumped Markdown library to 2.6.7 | |||
|
93 | - Dependencies: bumped mako templates to 1.0.6 | |||
|
94 | - Dependencies: bumped waitress version to 1.0.1 | |||
|
95 | - Dependencies: bumped pygments to 2.2.0 | |||
|
96 | - dependencies: bumped Mercurial version to 4.0.2 | |||
|
97 | - dependencies: bumped git version to 2.9.3 | |||
|
98 | ||||
|
99 | ||||
|
100 | Security | |||
|
101 | ^^^^^^^^ | |||
|
102 | ||||
|
103 | - Login: Don't display partial password helper hash inside the logs. | |||
|
104 | The information is not-required and will prevent people worrying about this | |||
|
105 | shown in logs. | |||
|
106 | - Auth: use pyramid HTTP exception when detecting CSRF errors. It helps | |||
|
107 | catching this error by our error handler and displaying it nicely to users. | |||
|
108 | - SVN: hide password entries in logs using specially generated configuration | |||
|
109 | for Apache Mod-Dav | |||
|
110 | - Permissions: fixed call to correctly check permissions for admin, before admin | |||
|
111 | users were ban deleting of pull requests in certain conditions. | |||
|
112 | ||||
|
113 | ||||
|
114 | Performance | |||
|
115 | ^^^^^^^^^^^ | |||
|
116 | ||||
|
117 | - Markup renderer: use global Markdown object to speed up markdown rendering. | |||
|
118 | We'll skip heavy initialization on each render thanks to this. | |||
|
119 | - Diffs: optimize how lexer is fetched for rich highlight mode. | |||
|
120 | Speeds up initial diff creation significantly since lexer cache is re used | |||
|
121 | and we don't need to fetch lexer many times. | |||
|
122 | - VCS: do an early detection of vcs-type request. | |||
|
123 | In case we're handling a VCS request, we can skip some of the pylons | |||
|
124 | stack initialization, speeding the request processing. | |||
|
125 | ||||
|
126 | ||||
|
127 | Fixes | |||
|
128 | ^^^^^ | |||
|
129 | ||||
|
130 | - Code review: render outdated comments that don't fit current context. | |||
|
131 | Comments attached to files that were removed from pull-request now will also | |||
|
132 | properly show up. | |||
|
133 | - Markup renderer: don't render plaintext files as RST. This prevents plain | |||
|
134 | Readme files have been wrongly rendered. | |||
|
135 | - VCS: raise a better exception if file node history cannot be extracted. | |||
|
136 | Helps to trace corrupted repositories. | |||
|
137 | - Exception handling: nicer error catching on repository creation. | |||
|
138 | - Fixed excessive number of session object creation. There should be now a | |||
|
139 | significant reduction in new file or DB entries created for sessions. | |||
|
140 | - Core: remove global timezone hook from tests. This was leaking into main | |||
|
141 | application causing TZ problems (such as UTC log dates). | |||
|
142 | - Pull requests: wait for all dynamic checks before enabling opening a PR. | |||
|
143 | This ensures that all code analysis were run before users are allowed to open | |||
|
144 | a pull request. | |||
|
145 | - i18n: use a consistent way of setting user language. | |||
|
146 | - API: added merge checks into API because it was not validated before and could | |||
|
147 | return an error if the merge wasn't possible for some reason. | |||
|
148 | - VCSServer: fetch proper locale before defaulting to default. Prevents | |||
|
149 | errors on some machines that don't have locales set. | |||
|
150 | - VCSServer: fixed 500 error if the wrong URL on HTTP mode vcsserver was accessed. | |||
|
151 | ||||
|
152 | ||||
|
153 | Upgrade notes | |||
|
154 | ^^^^^^^^^^^^^ | |||
|
155 | ||||
|
156 | - Integrations: since new POST/GET option was added to integrations, users | |||
|
157 | are advised to optionally check Webhooks integrations and pick one. | |||
|
158 | (default is still POST) No newline at end of file |
@@ -0,0 +1,17 b'' | |||||
|
1 | # test related requirements | |||
|
2 | pytest==3.0.5 | |||
|
3 | py==1.4.31 | |||
|
4 | pytest-cov==2.4.0 | |||
|
5 | pytest-sugar==0.7.1 | |||
|
6 | pytest-runner==2.9.0 | |||
|
7 | pytest-catchlog==1.2.2 | |||
|
8 | pytest-profiling==1.2.2 | |||
|
9 | gprof2dot==2016.10.13 | |||
|
10 | pytest-timeout==1.2.0 | |||
|
11 | ||||
|
12 | mock==1.0.1 | |||
|
13 | WebTest==1.4.3 | |||
|
14 | cov-core==1.15.0 | |||
|
15 | coverage==3.7.1 | |||
|
16 | cssselect==0.9.1 | |||
|
17 | lxml==3.4.4 |
@@ -0,0 +1,19 b'' | |||||
|
1 | # -*- coding: utf-8 -*- | |||
|
2 | ||||
|
3 | # Copyright (C) 2016-2017 RhodeCode GmbH | |||
|
4 | # | |||
|
5 | # This program is free software: you can redistribute it and/or modify | |||
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |||
|
7 | # (only), as published by the Free Software Foundation. | |||
|
8 | # | |||
|
9 | # This program is distributed in the hope that it will be useful, | |||
|
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
|
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
|
12 | # GNU General Public License for more details. | |||
|
13 | # | |||
|
14 | # You should have received a copy of the GNU Affero General Public License | |||
|
15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
|
16 | # | |||
|
17 | # This program is dual-licensed. If you wish to learn more about the | |||
|
18 | # RhodeCode Enterprise Edition, including its added features, Support services, | |||
|
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ |
@@ -0,0 +1,28 b'' | |||||
|
1 | # -*- coding: utf-8 -*- | |||
|
2 | ||||
|
3 | # Copyright (C) 2016-2017 RhodeCode GmbH | |||
|
4 | # | |||
|
5 | # This program is free software: you can redistribute it and/or modify | |||
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |||
|
7 | # (only), as published by the Free Software Foundation. | |||
|
8 | # | |||
|
9 | # This program is distributed in the hope that it will be useful, | |||
|
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
|
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
|
12 | # GNU General Public License for more details. | |||
|
13 | # | |||
|
14 | # You should have received a copy of the GNU Affero General Public License | |||
|
15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
|
16 | # | |||
|
17 | # This program is dual-licensed. If you wish to learn more about the | |||
|
18 | # RhodeCode Enterprise Edition, including its added features, Support services, | |||
|
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |||
|
20 | ||||
|
21 | ||||
|
22 | class AdminSettingsView(object): | |||
|
23 | ||||
|
24 | def __init__(self, context, request): | |||
|
25 | self.request = request | |||
|
26 | self.context = context | |||
|
27 | self.session = request.session | |||
|
28 | self._rhodecode_user = request.user |
@@ -0,0 +1,48 b'' | |||||
|
1 | # -*- coding: utf-8 -*- | |||
|
2 | ||||
|
3 | # Copyright (C) 2016-2017 RhodeCode GmbH | |||
|
4 | # | |||
|
5 | # This program is free software: you can redistribute it and/or modify | |||
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |||
|
7 | # (only), as published by the Free Software Foundation. | |||
|
8 | # | |||
|
9 | # This program is distributed in the hope that it will be useful, | |||
|
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
|
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
|
12 | # GNU General Public License for more details. | |||
|
13 | # | |||
|
14 | # You should have received a copy of the GNU Affero General Public License | |||
|
15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
|
16 | # | |||
|
17 | # This program is dual-licensed. If you wish to learn more about the | |||
|
18 | # RhodeCode Enterprise Edition, including its added features, Support services, | |||
|
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |||
|
20 | ||||
|
21 | import collections | |||
|
22 | import logging | |||
|
23 | ||||
|
24 | from pylons import tmpl_context as c | |||
|
25 | from pyramid.view import view_config | |||
|
26 | ||||
|
27 | from rhodecode.admin.views.base import AdminSettingsView | |||
|
28 | from rhodecode.admin.navigation import navigation_list | |||
|
29 | from rhodecode.lib.auth import (LoginRequired, HasPermissionAllDecorator) | |||
|
30 | from rhodecode.lib.utils import read_opensource_licenses | |||
|
31 | ||||
|
32 | log = logging.getLogger(__name__) | |||
|
33 | ||||
|
34 | ||||
|
35 | class OpenSourceLicensesAdminSettingsView(AdminSettingsView): | |||
|
36 | ||||
|
37 | @LoginRequired() | |||
|
38 | @HasPermissionAllDecorator('hg.admin') | |||
|
39 | @view_config( | |||
|
40 | route_name='admin_settings_open_source', request_method='GET', | |||
|
41 | renderer='rhodecode:templates/admin/settings/settings.mako') | |||
|
42 | def open_source_licenses(self): | |||
|
43 | c.active = 'open_source' | |||
|
44 | c.navlist = navigation_list(self.request) | |||
|
45 | c.opensource_licenses = collections.OrderedDict( | |||
|
46 | sorted(read_opensource_licenses().items(), key=lambda t: t[0])) | |||
|
47 | ||||
|
48 | return {} |
@@ -0,0 +1,100 b'' | |||||
|
1 | # -*- coding: utf-8 -*- | |||
|
2 | ||||
|
3 | # Copyright (C) 2016-2017 RhodeCode GmbH | |||
|
4 | # | |||
|
5 | # This program is free software: you can redistribute it and/or modify | |||
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |||
|
7 | # (only), as published by the Free Software Foundation. | |||
|
8 | # | |||
|
9 | # This program is distributed in the hope that it will be useful, | |||
|
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
|
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
|
12 | # GNU General Public License for more details. | |||
|
13 | # | |||
|
14 | # You should have received a copy of the GNU Affero General Public License | |||
|
15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
|
16 | # | |||
|
17 | # This program is dual-licensed. If you wish to learn more about the | |||
|
18 | # RhodeCode Enterprise Edition, including its added features, Support services, | |||
|
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |||
|
20 | ||||
|
21 | import logging | |||
|
22 | ||||
|
23 | from pylons import tmpl_context as c | |||
|
24 | from pyramid.view import view_config | |||
|
25 | from pyramid.httpexceptions import HTTPFound | |||
|
26 | ||||
|
27 | from rhodecode.translation import _ | |||
|
28 | ||||
|
29 | from rhodecode.admin.views.base import AdminSettingsView | |||
|
30 | from rhodecode.lib.auth import ( | |||
|
31 | LoginRequired, HasPermissionAllDecorator, CSRFRequired) | |||
|
32 | from rhodecode.lib.utils2 import safe_int | |||
|
33 | from rhodecode.lib import system_info | |||
|
34 | from rhodecode.lib import user_sessions | |||
|
35 | ||||
|
36 | ||||
|
37 | from rhodecode.admin.navigation import navigation_list | |||
|
38 | ||||
|
39 | ||||
|
40 | log = logging.getLogger(__name__) | |||
|
41 | ||||
|
42 | ||||
|
43 | class AdminSessionSettingsView(AdminSettingsView): | |||
|
44 | ||||
|
45 | @LoginRequired() | |||
|
46 | @HasPermissionAllDecorator('hg.admin') | |||
|
47 | @view_config( | |||
|
48 | route_name='admin_settings_sessions', request_method='GET', | |||
|
49 | renderer='rhodecode:templates/admin/settings/settings.mako') | |||
|
50 | def settings_sessions(self): | |||
|
51 | c.active = 'sessions' | |||
|
52 | c.navlist = navigation_list(self.request) | |||
|
53 | ||||
|
54 | c.cleanup_older_days = 60 | |||
|
55 | older_than_seconds = 60 * 60 * 24 * c.cleanup_older_days | |||
|
56 | ||||
|
57 | config = system_info.rhodecode_config().get_value()['value']['config'] | |||
|
58 | c.session_model = user_sessions.get_session_handler( | |||
|
59 | config.get('beaker.session.type', 'memory'))(config) | |||
|
60 | ||||
|
61 | c.session_conf = c.session_model.config | |||
|
62 | c.session_count = c.session_model.get_count() | |||
|
63 | c.session_expired_count = c.session_model.get_expired_count( | |||
|
64 | older_than_seconds) | |||
|
65 | ||||
|
66 | return {} | |||
|
67 | ||||
|
68 | @LoginRequired() | |||
|
69 | @CSRFRequired() | |||
|
70 | @HasPermissionAllDecorator('hg.admin') | |||
|
71 | @view_config( | |||
|
72 | route_name='admin_settings_sessions_cleanup', request_method='POST') | |||
|
73 | def settings_sessions_cleanup(self): | |||
|
74 | _ = self.request.translate | |||
|
75 | expire_days = safe_int(self.request.params.get('expire_days')) | |||
|
76 | ||||
|
77 | if expire_days is None: | |||
|
78 | expire_days = 60 | |||
|
79 | ||||
|
80 | older_than_seconds = 60 * 60 * 24 * expire_days | |||
|
81 | ||||
|
82 | config = system_info.rhodecode_config().get_value()['value']['config'] | |||
|
83 | session_model = user_sessions.get_session_handler( | |||
|
84 | config.get('beaker.session.type', 'memory'))(config) | |||
|
85 | ||||
|
86 | try: | |||
|
87 | session_model.clean_sessions( | |||
|
88 | older_than_seconds=older_than_seconds) | |||
|
89 | self.request.session.flash( | |||
|
90 | _('Cleaned up old sessions'), queue='success') | |||
|
91 | except user_sessions.CleanupCommand as msg: | |||
|
92 | self.request.session.flash(msg.message, queue='warning') | |||
|
93 | except Exception as e: | |||
|
94 | log.exception('Failed session cleanup') | |||
|
95 | self.request.session.flash( | |||
|
96 | _('Failed to cleanup up old sessions'), queue='error') | |||
|
97 | ||||
|
98 | redirect_to = self.request.resource_path( | |||
|
99 | self.context, route_name='admin_settings_sessions') | |||
|
100 | return HTTPFound(redirect_to) |
@@ -0,0 +1,60 b'' | |||||
|
1 | # -*- coding: utf-8 -*- | |||
|
2 | ||||
|
3 | # Copyright (C) 2016-2017 RhodeCode GmbH | |||
|
4 | # | |||
|
5 | # This program is free software: you can redistribute it and/or modify | |||
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |||
|
7 | # (only), as published by the Free Software Foundation. | |||
|
8 | # | |||
|
9 | # This program is distributed in the hope that it will be useful, | |||
|
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
|
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
|
12 | # GNU General Public License for more details. | |||
|
13 | # | |||
|
14 | # You should have received a copy of the GNU Affero General Public License | |||
|
15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
|
16 | # | |||
|
17 | # This program is dual-licensed. If you wish to learn more about the | |||
|
18 | # RhodeCode Enterprise Edition, including its added features, Support services, | |||
|
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |||
|
20 | ||||
|
21 | import logging | |||
|
22 | ||||
|
23 | from pyramid.view import view_config | |||
|
24 | ||||
|
25 | from rhodecode.svn_support.utils import generate_mod_dav_svn_config | |||
|
26 | ||||
|
27 | from rhodecode.admin.views.base import AdminSettingsView | |||
|
28 | from rhodecode.lib.auth import ( | |||
|
29 | LoginRequired, HasPermissionAllDecorator, CSRFRequired) | |||
|
30 | ||||
|
31 | log = logging.getLogger(__name__) | |||
|
32 | ||||
|
33 | ||||
|
34 | class SvnConfigAdminSettingsView(AdminSettingsView): | |||
|
35 | ||||
|
36 | @LoginRequired() | |||
|
37 | @CSRFRequired() | |||
|
38 | @HasPermissionAllDecorator('hg.admin') | |||
|
39 | @view_config( | |||
|
40 | route_name='admin_settings_vcs_svn_generate_cfg', | |||
|
41 | request_method='POST', renderer='json') | |||
|
42 | def vcs_svn_generate_config(self): | |||
|
43 | _ = self.request.translate | |||
|
44 | try: | |||
|
45 | generate_mod_dav_svn_config(self.request.registry) | |||
|
46 | msg = { | |||
|
47 | 'message': _('Apache configuration for Subversion generated.'), | |||
|
48 | 'level': 'success', | |||
|
49 | } | |||
|
50 | except Exception: | |||
|
51 | log.exception( | |||
|
52 | 'Exception while generating the Apache ' | |||
|
53 | 'configuration for Subversion.') | |||
|
54 | msg = { | |||
|
55 | 'message': _('Failed to generate the Apache configuration for Subversion.'), | |||
|
56 | 'level': 'error', | |||
|
57 | } | |||
|
58 | ||||
|
59 | data = {'message': msg} | |||
|
60 | return data |
@@ -0,0 +1,202 b'' | |||||
|
1 | # -*- coding: utf-8 -*- | |||
|
2 | ||||
|
3 | # Copyright (C) 2016-2017 RhodeCode GmbH | |||
|
4 | # | |||
|
5 | # This program is free software: you can redistribute it and/or modify | |||
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |||
|
7 | # (only), as published by the Free Software Foundation. | |||
|
8 | # | |||
|
9 | # This program is distributed in the hope that it will be useful, | |||
|
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
|
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
|
12 | # GNU General Public License for more details. | |||
|
13 | # | |||
|
14 | # You should have received a copy of the GNU Affero General Public License | |||
|
15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
|
16 | # | |||
|
17 | # This program is dual-licensed. If you wish to learn more about the | |||
|
18 | # RhodeCode Enterprise Edition, including its added features, Support services, | |||
|
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |||
|
20 | ||||
|
21 | import logging | |||
|
22 | import urllib2 | |||
|
23 | import packaging.version | |||
|
24 | ||||
|
25 | from pylons import tmpl_context as c | |||
|
26 | from pyramid.view import view_config | |||
|
27 | ||||
|
28 | import rhodecode | |||
|
29 | from rhodecode.lib import helpers as h | |||
|
30 | from rhodecode.lib.auth import (LoginRequired, HasPermissionAllDecorator) | |||
|
31 | from rhodecode.lib.utils2 import str2bool | |||
|
32 | from rhodecode.lib import system_info | |||
|
33 | from rhodecode.lib.ext_json import json | |||
|
34 | ||||
|
35 | from rhodecode.admin.views.base import AdminSettingsView | |||
|
36 | from rhodecode.admin.navigation import navigation_list | |||
|
37 | from rhodecode.model.settings import SettingsModel | |||
|
38 | ||||
|
39 | log = logging.getLogger(__name__) | |||
|
40 | ||||
|
41 | ||||
|
42 | class AdminSystemInfoSettingsView(AdminSettingsView): | |||
|
43 | ||||
|
44 | @staticmethod | |||
|
45 | def get_update_data(update_url): | |||
|
46 | """Return the JSON update data.""" | |||
|
47 | ver = rhodecode.__version__ | |||
|
48 | log.debug('Checking for upgrade on `%s` server', update_url) | |||
|
49 | opener = urllib2.build_opener() | |||
|
50 | opener.addheaders = [('User-agent', 'RhodeCode-SCM/%s' % ver)] | |||
|
51 | response = opener.open(update_url) | |||
|
52 | response_data = response.read() | |||
|
53 | data = json.loads(response_data) | |||
|
54 | ||||
|
55 | return data | |||
|
56 | ||||
|
57 | def get_update_url(self): | |||
|
58 | settings = SettingsModel().get_all_settings() | |||
|
59 | return settings.get('rhodecode_update_url') | |||
|
60 | ||||
|
61 | @LoginRequired() | |||
|
62 | @HasPermissionAllDecorator('hg.admin') | |||
|
63 | @view_config( | |||
|
64 | route_name='admin_settings_system', request_method='GET', | |||
|
65 | renderer='rhodecode:templates/admin/settings/settings.mako') | |||
|
66 | def settings_system_info(self): | |||
|
67 | _ = self.request.translate | |||
|
68 | ||||
|
69 | c.active = 'system' | |||
|
70 | c.navlist = navigation_list(self.request) | |||
|
71 | ||||
|
72 | # TODO(marcink), figure out how to allow only selected users to do this | |||
|
73 | c.allowed_to_snapshot = self._rhodecode_user.admin | |||
|
74 | ||||
|
75 | snapshot = str2bool(self.request.params.get('snapshot')) | |||
|
76 | ||||
|
77 | c.rhodecode_update_url = self.get_update_url() | |||
|
78 | server_info = system_info.get_system_info(self.request.environ) | |||
|
79 | ||||
|
80 | for key, val in server_info.items(): | |||
|
81 | setattr(c, key, val) | |||
|
82 | ||||
|
83 | def val(name, subkey='human_value'): | |||
|
84 | return server_info[name][subkey] | |||
|
85 | ||||
|
86 | def state(name): | |||
|
87 | return server_info[name]['state'] | |||
|
88 | ||||
|
89 | def val2(name): | |||
|
90 | val = server_info[name]['human_value'] | |||
|
91 | state = server_info[name]['state'] | |||
|
92 | return val, state | |||
|
93 | ||||
|
94 | update_info_msg = _('Note: please make sure this server can ' | |||
|
95 | 'access `${url}` for the update link to work', | |||
|
96 | mapping=dict(url=c.rhodecode_update_url)) | |||
|
97 | c.data_items = [ | |||
|
98 | # update info | |||
|
99 | (_('Update info'), h.literal( | |||
|
100 | '<span class="link" id="check_for_update" >%s.</span>' % ( | |||
|
101 | _('Check for updates')) + | |||
|
102 | '<br/> <span >%s.</span>' % (update_info_msg) | |||
|
103 | ), ''), | |||
|
104 | ||||
|
105 | # RhodeCode specific | |||
|
106 | (_('RhodeCode Version'), val('rhodecode_app')['text'], state('rhodecode_app')), | |||
|
107 | (_('RhodeCode Server IP'), val('server')['server_ip'], state('server')), | |||
|
108 | (_('RhodeCode Server ID'), val('server')['server_id'], state('server')), | |||
|
109 | (_('RhodeCode Configuration'), val('rhodecode_config')['path'], state('rhodecode_config')), | |||
|
110 | ('', '', ''), # spacer | |||
|
111 | ||||
|
112 | # Database | |||
|
113 | (_('Database'), val('database')['url'], state('database')), | |||
|
114 | (_('Database version'), val('database')['version'], state('database')), | |||
|
115 | ('', '', ''), # spacer | |||
|
116 | ||||
|
117 | # Platform/Python | |||
|
118 | (_('Platform'), val('platform')['name'], state('platform')), | |||
|
119 | (_('Platform UUID'), val('platform')['uuid'], state('platform')), | |||
|
120 | (_('Python version'), val('python')['version'], state('python')), | |||
|
121 | (_('Python path'), val('python')['executable'], state('python')), | |||
|
122 | ('', '', ''), # spacer | |||
|
123 | ||||
|
124 | # Systems stats | |||
|
125 | (_('CPU'), val('cpu'), state('cpu')), | |||
|
126 | (_('Load'), val('load')['text'], state('load')), | |||
|
127 | (_('Memory'), val('memory')['text'], state('memory')), | |||
|
128 | (_('Uptime'), val('uptime')['text'], state('uptime')), | |||
|
129 | ('', '', ''), # spacer | |||
|
130 | ||||
|
131 | # Repo storage | |||
|
132 | (_('Storage location'), val('storage')['path'], state('storage')), | |||
|
133 | (_('Storage info'), val('storage')['text'], state('storage')), | |||
|
134 | (_('Storage inodes'), val('storage_inodes')['text'], state('storage_inodes')), | |||
|
135 | ||||
|
136 | (_('Gist storage location'), val('storage_gist')['path'], state('storage_gist')), | |||
|
137 | (_('Gist storage info'), val('storage_gist')['text'], state('storage_gist')), | |||
|
138 | ||||
|
139 | (_('Archive cache storage location'), val('storage_archive')['path'], state('storage_archive')), | |||
|
140 | (_('Archive cache info'), val('storage_archive')['text'], state('storage_archive')), | |||
|
141 | ||||
|
142 | (_('Temp storage location'), val('storage_temp')['path'], state('storage_temp')), | |||
|
143 | (_('Temp storage info'), val('storage_temp')['text'], state('storage_temp')), | |||
|
144 | ||||
|
145 | (_('Search info'), val('search')['text'], state('search')), | |||
|
146 | (_('Search location'), val('search')['location'], state('search')), | |||
|
147 | ('', '', ''), # spacer | |||
|
148 | ||||
|
149 | # VCS specific | |||
|
150 | (_('VCS Backends'), val('vcs_backends'), state('vcs_backends')), | |||
|
151 | (_('VCS Server'), val('vcs_server')['text'], state('vcs_server')), | |||
|
152 | (_('GIT'), val('git'), state('git')), | |||
|
153 | (_('HG'), val('hg'), state('hg')), | |||
|
154 | (_('SVN'), val('svn'), state('svn')), | |||
|
155 | ||||
|
156 | ] | |||
|
157 | ||||
|
158 | if snapshot: | |||
|
159 | if c.allowed_to_snapshot: | |||
|
160 | c.data_items.pop(0) # remove server info | |||
|
161 | self.request.override_renderer = 'admin/settings/settings_system_snapshot.mako' | |||
|
162 | else: | |||
|
163 | self.request.session.flash( | |||
|
164 | 'You are not allowed to do this', queue='warning') | |||
|
165 | return {} | |||
|
166 | ||||
|
167 | @LoginRequired() | |||
|
168 | @HasPermissionAllDecorator('hg.admin') | |||
|
169 | @view_config( | |||
|
170 | route_name='admin_settings_system_update', request_method='GET', | |||
|
171 | renderer='rhodecode:templates/admin/settings/settings_system_update.mako') | |||
|
172 | def settings_system_info_check_update(self): | |||
|
173 | _ = self.request.translate | |||
|
174 | ||||
|
175 | update_url = self.get_update_url() | |||
|
176 | ||||
|
177 | _err = lambda s: '<div style="color:#ff8888; padding:4px 0px">{}</div>'.format(s) | |||
|
178 | try: | |||
|
179 | data = self.get_update_data(update_url) | |||
|
180 | except urllib2.URLError as e: | |||
|
181 | log.exception("Exception contacting upgrade server") | |||
|
182 | self.request.override_renderer = 'string' | |||
|
183 | return _err('Failed to contact upgrade server: %r' % e) | |||
|
184 | except ValueError as e: | |||
|
185 | log.exception("Bad data sent from update server") | |||
|
186 | self.request.override_renderer = 'string' | |||
|
187 | return _err('Bad data sent from update server') | |||
|
188 | ||||
|
189 | latest = data['versions'][0] | |||
|
190 | ||||
|
191 | c.update_url = update_url | |||
|
192 | c.latest_data = latest | |||
|
193 | c.latest_ver = latest['version'] | |||
|
194 | c.cur_ver = rhodecode.__version__ | |||
|
195 | c.should_upgrade = False | |||
|
196 | ||||
|
197 | if (packaging.version.Version(c.latest_ver) > | |||
|
198 | packaging.version.Version(c.cur_ver)): | |||
|
199 | c.should_upgrade = True | |||
|
200 | c.important_notices = latest['general'] | |||
|
201 | ||||
|
202 | return {} |
@@ -0,0 +1,44 b'' | |||||
|
1 | # -*- coding: utf-8 -*- | |||
|
2 | ||||
|
3 | # Copyright (C) 2017-2017 RhodeCode GmbH | |||
|
4 | # | |||
|
5 | # This program is free software: you can redistribute it and/or modify | |||
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |||
|
7 | # (only), as published by the Free Software Foundation. | |||
|
8 | # | |||
|
9 | # This program is distributed in the hope that it will be useful, | |||
|
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
|
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
|
12 | # GNU General Public License for more details. | |||
|
13 | # | |||
|
14 | # You should have received a copy of the GNU Affero General Public License | |||
|
15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
|
16 | # | |||
|
17 | # This program is dual-licensed. If you wish to learn more about the | |||
|
18 | # RhodeCode Enterprise Edition, including its added features, Support services, | |||
|
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |||
|
20 | ||||
|
21 | import mock | |||
|
22 | import pytest | |||
|
23 | ||||
|
24 | from rhodecode.lib.user_sessions import FileAuthSessions | |||
|
25 | from rhodecode.api.tests.utils import ( | |||
|
26 | build_data, api_call, assert_ok, assert_error, crash) | |||
|
27 | ||||
|
28 | ||||
|
29 | @pytest.mark.usefixtures("testuser_api", "app") | |||
|
30 | class TestCleanupSessions(object): | |||
|
31 | def test_api_cleanup_sessions(self): | |||
|
32 | id_, params = build_data(self.apikey, 'cleanup_sessions') | |||
|
33 | response = api_call(self.app, params) | |||
|
34 | ||||
|
35 | expected = {'backend': 'file sessions', 'sessions_removed': 0} | |||
|
36 | assert_ok(id_, expected, given=response.body) | |||
|
37 | ||||
|
38 | @mock.patch.object(FileAuthSessions, 'clean_sessions', crash) | |||
|
39 | def test_api_cleanup_error(self): | |||
|
40 | id_, params = build_data(self.apikey, 'cleanup_sessions', ) | |||
|
41 | response = api_call(self.app, params) | |||
|
42 | ||||
|
43 | expected = 'Error occurred during session cleanup' | |||
|
44 | assert_error(id_, expected, given=response.body) |
1 | NO CONTENT: new file 100644 |
|
NO CONTENT: new file 100644 | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: new file 100644 |
|
NO CONTENT: new file 100644 | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: new file 100644 |
|
NO CONTENT: new file 100644 | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: new file 100644 |
|
NO CONTENT: new file 100644 | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: new file 100644 |
|
NO CONTENT: new file 100644 | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: new file 100644 |
|
NO CONTENT: new file 100644 | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: new file 100644 |
|
NO CONTENT: new file 100644 | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: new file 100644 |
|
NO CONTENT: new file 100644 | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: new file 100644 |
|
NO CONTENT: new file 100644 | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: new file 100644 |
|
NO CONTENT: new file 100644 | ||
The requested commit or file is too big and content was truncated. Show full diff |
@@ -1,5 +1,5 b'' | |||||
1 | [bumpversion] |
|
1 | [bumpversion] | |
2 |
current_version = 4. |
|
2 | current_version = 4.6.0 | |
3 | message = release: Bump version {current_version} to {new_version} |
|
3 | message = release: Bump version {current_version} to {new_version} | |
4 |
|
4 | |||
5 | [bumpversion:file:rhodecode/VERSION] |
|
5 | [bumpversion:file:rhodecode/VERSION] |
@@ -4,26 +4,21 b' done = false' | |||||
4 | [task:bump_version] |
|
4 | [task:bump_version] | |
5 | done = true |
|
5 | done = true | |
6 |
|
6 | |||
7 | [task:rc_tools_pinned] |
|
|||
8 | done = true |
|
|||
9 |
|
||||
10 | [task:fixes_on_stable] |
|
7 | [task:fixes_on_stable] | |
11 | done = true |
|
|||
12 |
|
8 | |||
13 | [task:pip2nix_generated] |
|
9 | [task:pip2nix_generated] | |
14 | done = true |
|
|||
15 |
|
10 | |||
16 | [task:changelog_updated] |
|
11 | [task:changelog_updated] | |
17 | done = true |
|
|||
18 |
|
12 | |||
19 | [task:generate_api_docs] |
|
13 | [task:generate_api_docs] | |
20 | done = true |
|
14 | ||
|
15 | [task:updated_translation] | |||
21 |
|
16 | |||
22 | [release] |
|
17 | [release] | |
23 |
state = |
|
18 | state = in_progress | |
24 |
version = 4. |
|
19 | version = 4.6.0 | |
25 |
|
20 | |||
26 | [task:updated_translation] |
|
21 | [task:rc_tools_pinned] | |
27 |
|
22 | |||
28 | [task:generate_js_routes] |
|
23 | [task:generate_js_routes] | |
29 |
|
24 |
@@ -29,8 +29,6 b' recursive-include rhodecode *.mako' | |||||
29 | # 502 page |
|
29 | # 502 page | |
30 | include rhodecode/public/502.html |
|
30 | include rhodecode/public/502.html | |
31 |
|
31 | |||
32 | # 502 page |
|
|||
33 | include rhodecode/public/502.html |
|
|||
34 |
|
32 | |||
35 | # images, css |
|
33 | # images, css | |
36 | include rhodecode/public/css/*.css |
|
34 | include rhodecode/public/css/*.css |
@@ -1,11 +1,25 b'' | |||||
|
1 | ||||
|
2 | .PHONY: clean docs docs-clean docs-cleanup test test-clean test-only web-build | |||
1 |
|
3 | |||
2 | WEBPACK=./node_modules/webpack/bin/webpack.js |
|
4 | WEBPACK=./node_modules/webpack/bin/webpack.js | |
3 | GRUNT=grunt |
|
5 | GRUNT=grunt | |
4 | NODE_PATH=./node_modules |
|
6 | NODE_PATH=./node_modules | |
5 | CI_PREFIX=enterprise |
|
7 | ||
|
8 | ||||
|
9 | clean: | |||
|
10 | make test-clean | |||
|
11 | find . -type f \( -iname '*.c' -o -iname '*.pyc' -o -iname '*.so' \) -exec rm '{}' ';' | |||
6 |
|
|
12 | ||
7 | .PHONY: docs docs-clean ci-docs clean test test-clean test-lint test-only |
|
13 | test: | |
|
14 | make test-clean | |||
|
15 | make test-only | |||
8 |
|
|
16 | ||
|
17 | test-clean: | |||
|
18 | rm -rf coverage.xml htmlcov junit.xml pylint.log result | |||
|
19 | find . -type d -name "__pycache__" -prune -exec rm -rf '{}' ';' | |||
|
20 | ||||
|
21 | test-only: | |||
|
22 | PYTHONHASHSEED=random py.test -vv -r xw --cov=rhodecode --cov-report=term-missing --cov-report=html rhodecode | |||
9 |
|
23 | |||
10 | docs: |
|
24 | docs: | |
11 | (cd docs; nix-build default.nix -o result; make clean html) |
|
25 | (cd docs; nix-build default.nix -o result; make clean html) | |
@@ -13,27 +27,9 b' docs:' | |||||
13 | docs-clean: |
|
27 | docs-clean: | |
14 | (cd docs; make clean) |
|
28 | (cd docs; make clean) | |
15 |
|
29 | |||
16 | ci-docs: docs; |
|
30 | docs-cleanup: | |
17 |
|
31 | (cd docs; make cleanup) | ||
18 |
|
||||
19 | clean: test-clean |
|
|||
20 | find . -type f \( -iname '*.c' -o -iname '*.pyc' -o -iname '*.so' \) -exec rm '{}' ';' |
|
|||
21 |
|
||||
22 | test: test-clean test-only |
|
|||
23 |
|
||||
24 | test-clean: |
|
|||
25 | rm -rf coverage.xml htmlcov junit.xml pylint.log result |
|
|||
26 |
|
||||
27 | test-only: |
|
|||
28 | PYTHONHASHSEED=random py.test -vv -r xw --cov=rhodecode --cov-report=term-missing --cov-report=html rhodecode/tests/ |
|
|||
29 |
|
32 | |||
30 | web-build: |
|
33 | web-build: | |
31 | NODE_PATH=$(NODE_PATH) $(GRUNT) |
|
34 | NODE_PATH=$(NODE_PATH) $(GRUNT) | |
32 |
|
35 | |||
33 | web-test: |
|
|||
34 | @echo "no test for our javascript, yet!" |
|
|||
35 |
|
||||
36 | docs-bootstrap: |
|
|||
37 | (cd docs; nix-build default.nix -o result) |
|
|||
38 | @echo "Please go to docs folder and run make html" |
|
|||
39 |
|
@@ -415,19 +415,23 b' search.location = %(here)s/data/index' | |||||
415 | ######################################## |
|
415 | ######################################## | |
416 | ## channelstream enables persistent connections and live notification |
|
416 | ## channelstream enables persistent connections and live notification | |
417 | ## in the system. It's also used by the chat system |
|
417 | ## in the system. It's also used by the chat system | |
|
418 | channelstream.enabled = false | |||
418 |
|
419 | |||
419 | channelstream.enabled = false |
|
420 | ## server address for channelstream server on the backend | |
420 | ## location of channelstream server on the backend |
|
|||
421 | channelstream.server = 127.0.0.1:9800 |
|
421 | channelstream.server = 127.0.0.1:9800 | |
|
422 | ||||
422 | ## location of the channelstream server from outside world |
|
423 | ## location of the channelstream server from outside world | |
423 | ## most likely this would be an http server special backend URL, that handles |
|
424 | ## use ws:// for http or wss:// for https. This address needs to be handled | |
424 | ## websocket connections see nginx example for config |
|
425 | ## by external HTTP server such as Nginx or Apache | |
425 | # channelstream.ws_url = ws://rhodecode.yourserver.com/_channelstream |
|
426 | ## see nginx/apache configuration examples in our docs | |
426 | ## proxy path that can be used by http daemons for exposing channelstream |
|
427 | channelstream.ws_url = ws://rhodecode.yourserver.com/_channelstream | |
427 | # channelstream.proxy_path = /_channelstream |
|
|||
428 | channelstream.secret = secret |
|
428 | channelstream.secret = secret | |
429 | channelstream.history.location = %(here)s/channelstream_history |
|
429 | channelstream.history.location = %(here)s/channelstream_history | |
430 |
|
430 | |||
|
431 | ## Internal application path that Javascript uses to connect into. | |||
|
432 | ## If you use proxy-prefix the prefix should be added before /_channelstream | |||
|
433 | channelstream.proxy_path = /_channelstream | |||
|
434 | ||||
431 |
|
435 | |||
432 | ################################### |
|
436 | ################################### | |
433 | ## APPENLIGHT CONFIG ## |
|
437 | ## APPENLIGHT CONFIG ## | |
@@ -501,9 +505,9 b' appenlight.log_namespace_blacklist =' | |||||
501 | ############## |
|
505 | ############## | |
502 | debug_style = true |
|
506 | debug_style = true | |
503 |
|
507 | |||
504 |
########################################### |
|
508 | ########################################### | |
505 | ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ### |
|
509 | ### MAIN RHODECODE DATABASE CONFIG ### | |
506 |
########################################### |
|
510 | ########################################### | |
507 | #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db?timeout=30 |
|
511 | #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db?timeout=30 | |
508 | #sqlalchemy.db1.url = postgresql://postgres:qweqwe@localhost/rhodecode |
|
512 | #sqlalchemy.db1.url = postgresql://postgres:qweqwe@localhost/rhodecode | |
509 | #sqlalchemy.db1.url = mysql://root:qweqwe@localhost/rhodecode |
|
513 | #sqlalchemy.db1.url = mysql://root:qweqwe@localhost/rhodecode | |
@@ -586,12 +590,16 b' svn.proxy.location_root = /' | |||||
586 | ## be killed. Setting it to zero means no timeout. Defaults to 10 seconds. |
|
590 | ## be killed. Setting it to zero means no timeout. Defaults to 10 seconds. | |
587 | #svn.proxy.reload_timeout = 10 |
|
591 | #svn.proxy.reload_timeout = 10 | |
588 |
|
592 | |||
|
593 | ## Dummy marker to add new entries after. | |||
|
594 | ## Add any custom entries below. Please don't remove. | |||
|
595 | custom.conf = 1 | |||
|
596 | ||||
589 |
|
597 | |||
590 | ################################ |
|
598 | ################################ | |
591 | ### LOGGING CONFIGURATION #### |
|
599 | ### LOGGING CONFIGURATION #### | |
592 | ################################ |
|
600 | ################################ | |
593 | [loggers] |
|
601 | [loggers] | |
594 |
keys = root, routes, rhodecode, sqlalchemy, beaker, |
|
602 | keys = root, routes, rhodecode, sqlalchemy, beaker, templates | |
595 |
|
603 | |||
596 | [handlers] |
|
604 | [handlers] | |
597 | keys = console, console_sql |
|
605 | keys = console, console_sql | |
@@ -619,12 +627,6 b' handlers =' | |||||
619 | qualname = beaker.container |
|
627 | qualname = beaker.container | |
620 | propagate = 1 |
|
628 | propagate = 1 | |
621 |
|
629 | |||
622 | [logger_pyro4] |
|
|||
623 | level = DEBUG |
|
|||
624 | handlers = |
|
|||
625 | qualname = Pyro4 |
|
|||
626 | propagate = 1 |
|
|||
627 |
|
||||
628 | [logger_templates] |
|
630 | [logger_templates] | |
629 | level = INFO |
|
631 | level = INFO | |
630 | handlers = |
|
632 | handlers = |
@@ -1,4 +1,17 b'' | |||||
1 | """gunicorn config hooks""" |
|
1 | """ | |
|
2 | gunicorn config extension and hooks. Sets additional configuration that is | |||
|
3 | available post the .ini config. | |||
|
4 | ||||
|
5 | - workers = ${cpu_number} | |||
|
6 | - threads = 1 | |||
|
7 | - proc_name = ${gunicorn_proc_name} | |||
|
8 | - worker_class = sync | |||
|
9 | - worker_connections = 10 | |||
|
10 | - max_requests = 1000 | |||
|
11 | - max_requests_jitter = 30 | |||
|
12 | - timeout = 21600 | |||
|
13 | ||||
|
14 | """ | |||
2 |
|
15 | |||
3 | import multiprocessing |
|
16 | import multiprocessing | |
4 | import sys |
|
17 | import sys | |
@@ -6,50 +19,31 b' import threading' | |||||
6 | import traceback |
|
19 | import traceback | |
7 |
|
20 | |||
8 |
|
21 | |||
9 |
# GLOBAL |
|
22 | # GLOBAL | |
10 | errorlog = '-' |
|
23 | errorlog = '-' | |
11 | accesslog = '-' |
|
24 | accesslog = '-' | |
12 | loglevel = 'debug' |
|
25 | loglevel = 'debug' | |
13 |
|
26 | |||
14 |
# SECURITY |
|
27 | # SECURITY | |
15 | limit_request_line = 4094 |
|
28 | limit_request_line = 4094 | |
16 | limit_request_fields = 100 |
|
29 | limit_request_fields = 100 | |
17 | limit_request_field_size = 8190 |
|
30 | limit_request_field_size = 8190 | |
18 |
|
31 | |||
19 |
# SERVER MECHANICS |
|
32 | # SERVER MECHANICS | |
20 |
# None == system temp dir |
|
33 | # None == system temp dir | |
21 | worker_tmp_dir = None |
|
34 | worker_tmp_dir = None | |
22 | tmp_upload_dir = None |
|
35 | tmp_upload_dir = None | |
23 | #proc_name = |
|
|||
24 |
|
||||
25 | # self adjust workers based on CPU # |
|
|||
26 | #workers = multiprocessing.cpu_count() * 2 + 1 |
|
|||
27 |
|
||||
28 | access_log_format = '[%(p)s] %(h)15s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s" request_time:%(L)s' |
|
|||
29 |
|
||||
30 | # For the gevent worker classes # |
|
|||
31 | # this limits the maximum number of simultaneous clients that # |
|
|||
32 | # a single process can handle. # |
|
|||
33 | #worker_connections = 10 |
|
|||
34 |
|
36 | |||
35 | # Max requests to handle by each worker before restarting it, # |
|
37 | # Custom log format | |
36 | # could prevent memory leaks # |
|
38 | access_log_format = ( | |
37 | #max_requests = 1000 |
|
39 | '%(t)s GNCRN %(p)-8s %(h)-15s rqt:%(L)s %(s)s %(b)s "%(m)s:%(U)s %(q)s" usr:%(u)s "%(f)s" "%(a)s"') | |
38 | #max_requests_jitter = 30 |
|
|||
39 |
|
||||
40 |
|
40 | |||
41 | # If a worker does not notify the master process in this # |
|
41 | # self adjust workers based on CPU count | |
42 | # number of seconds it is killed and a new worker is spawned # |
|
42 | # workers = multiprocessing.cpu_count() * 2 + 1 | |
43 | # to replace it. # |
|
|||
44 | #timeout = 3600 |
|
|||
45 |
|
||||
46 | access_log_format = ( |
|
|||
47 | '[%(p)-10s] %(h)s time:%(L)s %(l)s %(u)s ' |
|
|||
48 | '%(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"') |
|
|||
49 |
|
43 | |||
50 |
|
44 | |||
51 | def post_fork(server, worker): |
|
45 | def post_fork(server, worker): | |
52 |
server.log.info("[<% |
|
46 | server.log.info("[<%-10s>] WORKER spawned", worker.pid) | |
53 |
|
47 | |||
54 |
|
48 | |||
55 | def pre_fork(server, worker): |
|
49 | def pre_fork(server, worker): | |
@@ -67,7 +61,7 b' def when_ready(server):' | |||||
67 | def worker_int(worker): |
|
61 | def worker_int(worker): | |
68 | worker.log.info("[<%-10s>] worker received INT or QUIT signal", worker.pid) |
|
62 | worker.log.info("[<%-10s>] worker received INT or QUIT signal", worker.pid) | |
69 |
|
63 | |||
70 | # get traceback info |
|
64 | # get traceback info, on worker crash | |
71 | id2name = dict([(th.ident, th.name) for th in threading.enumerate()]) |
|
65 | id2name = dict([(th.ident, th.name) for th in threading.enumerate()]) | |
72 | code = [] |
|
66 | code = [] | |
73 | for thread_id, stack in sys._current_frames().items(): |
|
67 | for thread_id, stack in sys._current_frames().items(): |
@@ -389,19 +389,23 b' search.location = %(here)s/data/index' | |||||
389 | ######################################## |
|
389 | ######################################## | |
390 | ## channelstream enables persistent connections and live notification |
|
390 | ## channelstream enables persistent connections and live notification | |
391 | ## in the system. It's also used by the chat system |
|
391 | ## in the system. It's also used by the chat system | |
|
392 | channelstream.enabled = false | |||
392 |
|
393 | |||
393 | channelstream.enabled = false |
|
394 | ## server address for channelstream server on the backend | |
394 | ## location of channelstream server on the backend |
|
|||
395 | channelstream.server = 127.0.0.1:9800 |
|
395 | channelstream.server = 127.0.0.1:9800 | |
|
396 | ||||
396 | ## location of the channelstream server from outside world |
|
397 | ## location of the channelstream server from outside world | |
397 | ## most likely this would be an http server special backend URL, that handles |
|
398 | ## use ws:// for http or wss:// for https. This address needs to be handled | |
398 | ## websocket connections see nginx example for config |
|
399 | ## by external HTTP server such as Nginx or Apache | |
399 | # channelstream.ws_url = ws://rhodecode.yourserver.com/_channelstream |
|
400 | ## see nginx/apache configuration examples in our docs | |
400 | ## proxy path that can be used by http daemons for exposing channelstream |
|
401 | channelstream.ws_url = ws://rhodecode.yourserver.com/_channelstream | |
401 | # channelstream.proxy_path = /_channelstream |
|
|||
402 | channelstream.secret = secret |
|
402 | channelstream.secret = secret | |
403 | channelstream.history.location = %(here)s/channelstream_history |
|
403 | channelstream.history.location = %(here)s/channelstream_history | |
404 |
|
404 | |||
|
405 | ## Internal application path that Javascript uses to connect into. | |||
|
406 | ## If you use proxy-prefix the prefix should be added before /_channelstream | |||
|
407 | channelstream.proxy_path = /_channelstream | |||
|
408 | ||||
405 |
|
409 | |||
406 | ################################### |
|
410 | ################################### | |
407 | ## APPENLIGHT CONFIG ## |
|
411 | ## APPENLIGHT CONFIG ## | |
@@ -470,9 +474,9 b' appenlight.log_namespace_blacklist =' | |||||
470 | set debug = false |
|
474 | set debug = false | |
471 |
|
475 | |||
472 |
|
476 | |||
473 |
########################################### |
|
477 | ########################################### | |
474 | ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ### |
|
478 | ### MAIN RHODECODE DATABASE CONFIG ### | |
475 |
########################################### |
|
479 | ########################################### | |
476 | #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db?timeout=30 |
|
480 | #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db?timeout=30 | |
477 | #sqlalchemy.db1.url = postgresql://postgres:qweqwe@localhost/rhodecode |
|
481 | #sqlalchemy.db1.url = postgresql://postgres:qweqwe@localhost/rhodecode | |
478 | #sqlalchemy.db1.url = mysql://root:qweqwe@localhost/rhodecode |
|
482 | #sqlalchemy.db1.url = mysql://root:qweqwe@localhost/rhodecode | |
@@ -555,12 +559,16 b' svn.proxy.location_root = /' | |||||
555 | ## be killed. Setting it to zero means no timeout. Defaults to 10 seconds. |
|
559 | ## be killed. Setting it to zero means no timeout. Defaults to 10 seconds. | |
556 | #svn.proxy.reload_timeout = 10 |
|
560 | #svn.proxy.reload_timeout = 10 | |
557 |
|
561 | |||
|
562 | ## Dummy marker to add new entries after. | |||
|
563 | ## Add any custom entries below. Please don't remove. | |||
|
564 | custom.conf = 1 | |||
|
565 | ||||
558 |
|
566 | |||
559 | ################################ |
|
567 | ################################ | |
560 | ### LOGGING CONFIGURATION #### |
|
568 | ### LOGGING CONFIGURATION #### | |
561 | ################################ |
|
569 | ################################ | |
562 | [loggers] |
|
570 | [loggers] | |
563 |
keys = root, routes, rhodecode, sqlalchemy, beaker, |
|
571 | keys = root, routes, rhodecode, sqlalchemy, beaker, templates | |
564 |
|
572 | |||
565 | [handlers] |
|
573 | [handlers] | |
566 | keys = console, console_sql |
|
574 | keys = console, console_sql | |
@@ -588,12 +596,6 b' handlers =' | |||||
588 | qualname = beaker.container |
|
596 | qualname = beaker.container | |
589 | propagate = 1 |
|
597 | propagate = 1 | |
590 |
|
598 | |||
591 | [logger_pyro4] |
|
|||
592 | level = DEBUG |
|
|||
593 | handlers = |
|
|||
594 | qualname = Pyro4 |
|
|||
595 | propagate = 1 |
|
|||
596 |
|
||||
597 | [logger_templates] |
|
599 | [logger_templates] | |
598 | level = INFO |
|
600 | level = INFO | |
599 | handlers = |
|
601 | handlers = |
@@ -135,6 +135,8 b' let' | |||||
135 | rhodecode-testdata |
|
135 | rhodecode-testdata | |
136 | ]); |
|
136 | ]); | |
137 |
|
137 | |||
|
138 | #TODO: either move this into overrides, OR use the new machanics from | |||
|
139 | # pip2nix and requiremtn.txt file | |||
138 | propagatedBuildInputs = attrs.propagatedBuildInputs ++ (with self; [ |
|
140 | propagatedBuildInputs = attrs.propagatedBuildInputs ++ (with self; [ | |
139 | rhodecode-tools |
|
141 | rhodecode-tools | |
140 | ]); |
|
142 | ]); |
@@ -49,6 +49,12 b' help:' | |||||
49 | clean: |
|
49 | clean: | |
50 | rm -rf $(BUILDDIR)/* |
|
50 | rm -rf $(BUILDDIR)/* | |
51 |
|
51 | |||
|
52 | cleanup: | |||
|
53 | @echo "cleaning build dir" | |||
|
54 | rm -rf $(BUILDDIR)/* | |||
|
55 | @echo "cleaning result symlink" | |||
|
56 | rm -v result | |||
|
57 | ||||
52 | html: |
|
58 | html: | |
53 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html |
|
59 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html | |
54 | @echo |
|
60 | @echo |
@@ -1,32 +1,68 b'' | |||||
1 | .. _apache-conf-eg: |
|
1 | .. _apache-conf-eg: | |
2 |
|
2 | |||
3 |
Apache Configuration Example |
|
3 | Apache Configuration Example | |
4 |
---------------------------- |
|
4 | ---------------------------- | |
|
5 | ||||
|
6 | Use the following example to configure Apache as a your web server. | |||
|
7 | Below config if for an Apache Reverse Proxy configuration. | |||
|
8 | ||||
|
9 | .. note:: | |||
|
10 | ||||
|
11 | Apache requires the following modules to be enabled. Below is an example | |||
|
12 | how to enable them on Ubuntu Server | |||
|
13 | ||||
5 |
|
14 | |||
6 | Use the following example to securely configure your Apache HTTP virtual hosts |
|
15 | .. code-block:: bash | |
7 | file. |
|
16 | ||
|
17 | $ sudo a2enmod proxy | |||
|
18 | $ sudo a2enmod proxy_http | |||
|
19 | $ sudo a2enmod proxy_balancer | |||
|
20 | $ sudo a2enmod headers | |||
|
21 | $ sudo a2enmod ssl | |||
|
22 | $ sudo a2enmod rewrite | |||
|
23 | ||||
|
24 | # requires Apache 2.4+, required to handle websockets/channelstream | |||
|
25 | $ sudo a2enmod proxy_wstunnel | |||
|
26 | ||||
8 |
|
|
27 | ||
9 | .. code-block:: apache |
|
28 | .. code-block:: apache | |
10 |
|
29 | |||
|
30 | ## HTTP to HTTPS rewrite | |||
11 | <VirtualHost *:80> |
|
31 | <VirtualHost *:80> | |
12 |
|
|
32 | ServerName rhodecode.myserver.com | |
13 | ServerAlias hg.myserver.com |
|
33 | DocumentRoot /var/www/html | |
|
34 | Redirect permanent / https://rhodecode.myserver.com/ | |||
|
35 | </VirtualHost> | |||
|
36 | ||||
|
37 | ## MAIN SSL enabled server | |||
|
38 | <VirtualHost *:443> | |||
|
39 | ||||
|
40 | ServerName rhodecode.myserver.com | |||
|
41 | ServerAlias rhodecode.myserver.com | |||
|
42 | ||||
|
43 | ## serve static files by Apache, recommended for performance | |||
|
44 | #Alias /_static /home/ubuntu/.rccontrol/community-1/static | |||
|
45 | ||||
|
46 | RequestHeader set X-Forwarded-Proto "https" | |||
|
47 | ||||
|
48 | ## channelstream websocket handling | |||
|
49 | ProxyPass /_channelstream ws://localhost:9800 | |||
|
50 | ProxyPassReverse /_channelstream ws://localhost:9800 | |||
14 |
|
51 | |||
15 | <Proxy *> |
|
52 | <Proxy *> | |
16 | Order allow,deny |
|
53 | Order allow,deny | |
17 | Allow from all |
|
54 | Allow from all | |
18 | </Proxy> |
|
55 | </Proxy> | |
19 |
|
56 | |||
20 | # important ! |
|
57 | # Directive to properly generate url (clone url) for RhodeCode | |
21 | # Directive to properly generate url (clone url) for pylons |
|
|||
22 |
|
||||
23 | ProxyPreserveHost On |
|
58 | ProxyPreserveHost On | |
24 |
|
59 | |||
25 | #rhodecode instance |
|
60 | # Url to running RhodeCode instance. This is shown as `- URL:` when | |
26 | ProxyPass / http://127.0.0.1:5000/ |
|
61 | # running rccontrol status. | |
27 |
ProxyPass |
|
62 | ProxyPass / http://127.0.0.1:10002/ | |
|
63 | ProxyPassReverse / http://127.0.0.1:10002/ | |||
28 |
|
64 | |||
29 | # Set strict HTTPS |
|
65 | # strict http prevents from https -> http downgrade | |
30 | Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload" |
|
66 | Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload" | |
31 |
|
67 | |||
32 | # Set x-frame options |
|
68 | # Set x-frame options | |
@@ -35,80 +71,17 b' file.' | |||||
35 | # To enable https use line below |
|
71 | # To enable https use line below | |
36 | # SetEnvIf X-Url-Scheme https HTTPS=1 |
|
72 | # SetEnvIf X-Url-Scheme https HTTPS=1 | |
37 |
|
73 | |||
38 | # Secure your Diffie-hellmann deployment |
|
74 | # SSL setup | |
|
75 | SSLEngine On | |||
|
76 | SSLCertificateFile /etc/apache2/ssl/rhodecode.myserver.pem | |||
|
77 | SSLCertificateKeyFile /etc/apache2/ssl/rhodecode.myserver.key | |||
|
78 | ||||
39 | SSLProtocol all -SSLv2 -SSLv3 |
|
79 | SSLProtocol all -SSLv2 -SSLv3 | |
40 | SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA |
|
80 | SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA | |
41 | SSLHonorCipherOrder on |
|
81 | SSLHonorCipherOrder on | |
42 | SSLOpenSSLConfCmd DHParameters "{path to dhparams.pem}" |
|
82 | ||
|
83 | # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits | |||
|
84 | #SSLOpenSSLConfCmd DHParameters "/etc/apache2/dhparam.pem" | |||
43 |
|
85 | |||
44 | </VirtualHost> |
|
86 | </VirtualHost> | |
45 |
|
87 | |||
46 | Use the following example to configure Apache for a multi-node setup. The |
|
|||
47 | timeout setting should be increased if you experience timeouts when working |
|
|||
48 | with large |repos|. |
|
|||
49 |
|
||||
50 | .. code-block:: apache |
|
|||
51 |
|
||||
52 | # |
|
|||
53 | # Timeout: The number of seconds before receives and sends time out. |
|
|||
54 | # |
|
|||
55 | Timeout 600 |
|
|||
56 |
|
||||
57 | <VirtualHost *:80> |
|
|||
58 |
|
||||
59 | ProxyRequests off |
|
|||
60 |
|
||||
61 | #important ! |
|
|||
62 | #Directive to properly generate url (clone url) for pylons |
|
|||
63 | ProxyPreserveHost On |
|
|||
64 |
|
||||
65 | ServerName your.rce.com |
|
|||
66 | ServerAlias your.rce.com |
|
|||
67 |
|
||||
68 | <Proxy balancer://mycluster> |
|
|||
69 | # WebHead1 |
|
|||
70 | BalancerMember http://10.58.1.171:10002 route=1 |
|
|||
71 | # WebHead2 |
|
|||
72 | BalancerMember http://10.58.1.172:10001 route=2 |
|
|||
73 |
|
||||
74 | # Security "technically we aren't blocking |
|
|||
75 | # anyone but this the place to make those |
|
|||
76 | # chages |
|
|||
77 | Order Deny,Allow |
|
|||
78 | Deny from none |
|
|||
79 | Allow from all |
|
|||
80 |
|
||||
81 | # Load Balancer Settings |
|
|||
82 | # We will be configuring a simple Round |
|
|||
83 | # Robin style load balancer. This means |
|
|||
84 | # that all webheads take an equal share of |
|
|||
85 | # of the load. |
|
|||
86 | ProxySet stickysession=ROUTEID |
|
|||
87 |
|
||||
88 | </Proxy> |
|
|||
89 |
|
||||
90 | # balancer-manager |
|
|||
91 | # This tool is built into the mod_proxy_balancer |
|
|||
92 | # module and will allow you to do some simple |
|
|||
93 | # modifications to the balanced group via a gui |
|
|||
94 | # web interface. |
|
|||
95 | <Location /balancer-manager> |
|
|||
96 | SetHandler balancer-manager |
|
|||
97 |
|
||||
98 | # recommend locking this one down to your |
|
|||
99 | # your office |
|
|||
100 | Order deny,allow |
|
|||
101 | Allow from all |
|
|||
102 | </Location> |
|
|||
103 |
|
||||
104 | # Point of Balance |
|
|||
105 | # This setting will allow to explicitly name the |
|
|||
106 | # the location in the site that we want to be |
|
|||
107 | # balanced, in this example we will balance "/" |
|
|||
108 | # or everything in the site. |
|
|||
109 | ProxyPass /balancer-manager ! |
|
|||
110 | ProxyPass / balancer://mycluster/ |
|
|||
111 |
|
||||
112 | ProxyPassReverse / balancer://mycluster/ |
|
|||
113 |
|
||||
114 | </VirtualHost> |
|
@@ -9,7 +9,6 b' the information in the following section' | |||||
9 | .. toctree:: |
|
9 | .. toctree:: | |
10 |
|
10 | |||
11 | apache-diffie-hellman |
|
11 | apache-diffie-hellman | |
12 |
apache-conf-example |
|
12 | apache-conf-example | |
13 | apache-subdirectory |
|
13 | apache-subdirectory | |
14 | apache-reverse-proxy |
|
|||
15 | apache-wsgi-coding |
|
14 | apache-wsgi-coding |
@@ -7,7 +7,8 b' Use the following example to configure A' | |||||
7 |
|
7 | |||
8 | .. code-block:: apache |
|
8 | .. code-block:: apache | |
9 |
|
9 | |||
10 |
|
|
10 | # Change someprefix into your chosen prefix | |
|
11 | <Location /someprefix > | |||
11 | ProxyPreserveHost On |
|
12 | ProxyPreserveHost On | |
12 | ProxyPass "http://127.0.0.1:5000/" |
|
13 | ProxyPass "http://127.0.0.1:5000/" | |
13 | ProxyPassReverse "http://127.0.0.1:5000/" |
|
14 | ProxyPassReverse "http://127.0.0.1:5000/" |
@@ -3,6 +3,7 b' Nginx Configuration Example' | |||||
3 |
|
3 | |||
4 | Use the following example to configure Nginx as a your web server. |
|
4 | Use the following example to configure Nginx as a your web server. | |
5 |
|
5 | |||
|
6 | ||||
6 | .. code-block:: nginx |
|
7 | .. code-block:: nginx | |
7 |
|
8 | |||
8 | log_format log_custom '$remote_addr - $remote_user [$time_local] ' |
|
9 | log_format log_custom '$remote_addr - $remote_user [$time_local] ' | |
@@ -10,8 +11,10 b' Use the following example to configure N' | |||||
10 | '"$http_referer" "$http_user_agent" ' |
|
11 | '"$http_referer" "$http_user_agent" ' | |
11 | '$request_time $upstream_response_time $pipe'; |
|
12 | '$request_time $upstream_response_time $pipe'; | |
12 |
|
13 | |||
|
14 | ## define upstream (local RhodeCode instance) to connect to | |||
13 | upstream rc { |
|
15 | upstream rc { | |
14 |
|
16 | # Url to running RhodeCode instance. | ||
|
17 | # This is shown as `- URL:` in output from rccontrol status. | |||
15 | server 127.0.0.1:10002; |
|
18 | server 127.0.0.1:10002; | |
16 |
|
19 | |||
17 | # add more instances for load balancing |
|
20 | # add more instances for load balancing | |
@@ -19,8 +22,17 b' Use the following example to configure N' | |||||
19 | # server 127.0.0.1:10004; |
|
22 | # server 127.0.0.1:10004; | |
20 | } |
|
23 | } | |
21 |
|
24 | |||
22 | ## gist alias server, for serving nicer GIST urls |
|
25 | ## HTTP to HTTPS rewrite | |
|
26 | server { | |||
|
27 | listen 80; | |||
|
28 | server_name rhodecode.myserver.com; | |||
23 |
|
|
29 | ||
|
30 | if ($http_host = rhodecode.myserver.com) { | |||
|
31 | rewrite (.*) https://rhodecode.myserver.com$1 permanent; | |||
|
32 | } | |||
|
33 | } | |||
|
34 | ||||
|
35 | ## Optional gist alias server, for serving nicer GIST urls. | |||
24 | server { |
|
36 | server { | |
25 | listen 443; |
|
37 | listen 443; | |
26 | server_name gist.myserver.com; |
|
38 | server_name gist.myserver.com; | |
@@ -37,6 +49,7 b' Use the following example to configure N' | |||||
37 | ssl_prefer_server_ciphers on; |
|
49 | ssl_prefer_server_ciphers on; | |
38 | ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA'; |
|
50 | ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA'; | |
39 |
|
51 | |||
|
52 | # strict http prevents from https -> http downgrade | |||
40 | add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;"; |
|
53 | add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;"; | |
41 |
|
54 | |||
42 | # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits |
|
55 | # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits | |
@@ -46,15 +59,6 b' Use the following example to configure N' | |||||
46 | rewrite (.*) https://rhodecode.myserver.com/_admin/gists; |
|
59 | rewrite (.*) https://rhodecode.myserver.com/_admin/gists; | |
47 | } |
|
60 | } | |
48 |
|
61 | |||
49 | ## HTTP to HTTPS rewrite |
|
|||
50 | server { |
|
|||
51 | listen 80; |
|
|||
52 | server_name rhodecode.myserver.com; |
|
|||
53 |
|
||||
54 | if ($http_host = rhodecode.myserver.com) { |
|
|||
55 | rewrite (.*) https://rhodecode.myserver.com$1 permanent; |
|
|||
56 | } |
|
|||
57 | } |
|
|||
58 |
|
62 | |||
59 | ## MAIN SSL enabled server |
|
63 | ## MAIN SSL enabled server | |
60 | server { |
|
64 | server { | |
@@ -79,14 +83,15 b' Use the following example to configure N' | |||||
79 |
|
83 | |||
80 | include /etc/nginx/proxy.conf; |
|
84 | include /etc/nginx/proxy.conf; | |
81 |
|
85 | |||
82 |
## serve static files by |
|
86 | ## serve static files by Nginx, recommended for performance | |
83 | # location /_static/rhodecode { |
|
87 | # location /_static/rhodecode { | |
84 | # alias /path/to/.rccontrol/enterprise-1/static; |
|
88 | # alias /path/to/.rccontrol/enterprise-1/static; | |
85 | # } |
|
89 | # } | |
86 |
|
90 | |||
87 |
## channel |
|
91 | ## channelstream websocket handling | |
88 | location /_channelstream { |
|
92 | location /_channelstream { | |
89 | rewrite /_channelstream/(.*) /$1 break; |
|
93 | rewrite /_channelstream/(.*) /$1 break; | |
|
94 | ||||
90 | proxy_pass http://127.0.0.1:9800; |
|
95 | proxy_pass http://127.0.0.1:9800; | |
91 |
|
96 | |||
92 | proxy_connect_timeout 10; |
|
97 | proxy_connect_timeout 10; |
@@ -1,7 +1,7 b'' | |||||
1 | .. _nginx-ws-ref: |
|
1 | .. _nginx-ws-ref: | |
2 |
|
2 | |||
3 | Nginx Configuration |
|
3 | Nginx HTTP Server Configuration | |
4 | =================== |
|
4 | ------------------------------- | |
5 |
|
5 | |||
6 | To set up your Nginx Web Server for optimal performance and security, use |
|
6 | To set up your Nginx Web Server for optimal performance and security, use | |
7 | the information in the following sections. |
|
7 | the information in the following sections. |
@@ -12,6 +12,7 b' it somehow becomes unavailable you can u' | |||||
12 | Logging into the |RCE| database with ``iShell`` should only be done by an |
|
12 | Logging into the |RCE| database with ``iShell`` should only be done by an | |
13 | experienced and knowledgeable database administrator. |
|
13 | experienced and knowledgeable database administrator. | |
14 |
|
14 | |||
|
15 | ||||
15 | Reset Admin Account Privileges |
|
16 | Reset Admin Account Privileges | |
16 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
|
17 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
17 |
|
18 | |||
@@ -22,8 +23,7 b' account permissions.' | |||||
22 | .. code-block:: bash |
|
23 | .. code-block:: bash | |
23 |
|
24 | |||
24 | # Open iShell from the terminal |
|
25 | # Open iShell from the terminal | |
25 |
$ |
|
26 | $ rccontrol ishell enterprise-1 | |
26 | ishell .rccontrol/enterprise-1/rhodecode.ini |
|
|||
27 |
|
27 | |||
28 | .. code-block:: mysql |
|
28 | .. code-block:: mysql | |
29 |
|
29 | |||
@@ -33,6 +33,7 b' account permissions.' | |||||
33 | In [3]: Session().add(adminuser);Session().commit() |
|
33 | In [3]: Session().add(adminuser);Session().commit() | |
34 | In [4]: exit() |
|
34 | In [4]: exit() | |
35 |
|
35 | |||
|
36 | ||||
36 | Set to read global ``.hgrc`` file |
|
37 | Set to read global ``.hgrc`` file | |
37 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
|
38 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
38 |
|
39 | |||
@@ -46,8 +47,7 b' following example to make changes to thi' | |||||
46 | .. code-block:: bash |
|
47 | .. code-block:: bash | |
47 |
|
48 | |||
48 | # Open iShell from the terminal |
|
49 | # Open iShell from the terminal | |
49 | $ .rccontrol/enterprise-5/profile/bin/paster \ |
|
50 | $ rccontrol ishell enterprise-1 | |
50 | ishell.rccontrol/enterprise-5/rhodecode.ini |
|
|||
51 |
|
51 | |||
52 | .. code-block:: mysql |
|
52 | .. code-block:: mysql | |
53 |
|
53 | |||
@@ -59,6 +59,7 b' following example to make changes to thi' | |||||
59 | In [5]: Session().add(new_option);Session().commit() |
|
59 | In [5]: Session().add(new_option);Session().commit() | |
60 | In [6]: exit() |
|
60 | In [6]: exit() | |
61 |
|
61 | |||
|
62 | ||||
62 | Manually Reset Password |
|
63 | Manually Reset Password | |
63 | ^^^^^^^^^^^^^^^^^^^^^^^ |
|
64 | ^^^^^^^^^^^^^^^^^^^^^^^ | |
64 |
|
65 | |||
@@ -73,8 +74,7 b' Use the following code example to carry ' | |||||
73 | .. code-block:: bash |
|
74 | .. code-block:: bash | |
74 |
|
75 | |||
75 | # starts the ishell interactive prompt |
|
76 | # starts the ishell interactive prompt | |
76 |
$ |
|
77 | $ rccontrol ishell enterprise-1 | |
77 | ishell .rccontrol/enterprise-1/rhodecode.ini |
|
|||
78 |
|
78 | |||
79 | .. code-block:: mysql |
|
79 | .. code-block:: mysql | |
80 |
|
80 | |||
@@ -91,7 +91,6 b' Use the following code example to carry ' | |||||
91 | In [8]: exit() |
|
91 | In [8]: exit() | |
92 |
|
92 | |||
93 |
|
93 | |||
94 |
|
||||
95 | Change user details |
|
94 | Change user details | |
96 | ^^^^^^^^^^^^^^^^^^^ |
|
95 | ^^^^^^^^^^^^^^^^^^^ | |
97 |
|
96 | |||
@@ -106,8 +105,7 b' Use the following code example to carry ' | |||||
106 | .. code-block:: bash |
|
105 | .. code-block:: bash | |
107 |
|
106 | |||
108 | # starts the ishell interactive prompt |
|
107 | # starts the ishell interactive prompt | |
109 |
$ |
|
108 | $ rccontrol ishell enterprise-1 | |
110 | ishell .rccontrol/enterprise-1/rhodecode.ini |
|
|||
111 |
|
109 | |||
112 | .. code-block:: mysql |
|
110 | .. code-block:: mysql | |
113 |
|
111 | |||
@@ -117,3 +115,37 b' Use the following code example to carry ' | |||||
117 | In [3]: my_user.username = 'SomeUser' |
|
115 | In [3]: my_user.username = 'SomeUser' | |
118 | In [4]: Session().add(my_user);Session().commit() |
|
116 | In [4]: Session().add(my_user);Session().commit() | |
119 | In [5]: exit() |
|
117 | In [5]: exit() | |
|
118 | ||||
|
119 | ||||
|
120 | Change user login type | |||
|
121 | ^^^^^^^^^^^^^^^^^^^^^^ | |||
|
122 | ||||
|
123 | Sometimes it's required to change account type from RhodeCode to LDAP or | |||
|
124 | other external authentication type. | |||
|
125 | If you need to manually change the method of login, use the following steps. | |||
|
126 | ||||
|
127 | 1. Navigate to your |RCE| install location. | |||
|
128 | 2. Run the interactive ``ishell`` prompt. | |||
|
129 | 3. Set a new arguments for users. | |||
|
130 | ||||
|
131 | Use the following code example to carry out these steps. | |||
|
132 | Available values for new_extern_type can be found when browsing available | |||
|
133 | authentication types in RhodeCode admin interface for authentication. | |||
|
134 | Use the text which is shown after '#' sign, eg. | |||
|
135 | ` LDAP (egg:rhodecode-enterprise-ce#ldap)` it's type is 'ldap' | |||
|
136 | ||||
|
137 | .. code-block:: bash | |||
|
138 | ||||
|
139 | # starts the ishell interactive prompt | |||
|
140 | $ rccontrol ishell enterprise-1 | |||
|
141 | ||||
|
142 | .. code-block:: mysql | |||
|
143 | ||||
|
144 | # Use this example to change users from authentication | |||
|
145 | # using rhodecode internal to ldap | |||
|
146 | In [1]: new_extern_type = 'ldap' | |||
|
147 | In [2]: my_user = User.get_by_username('some_username') | |||
|
148 | In [3]: my_user.extern_type = new_extern_type | |||
|
149 | In [4]: my_user.extern_name = new_extern_type | |||
|
150 | In [5]: Session().add(my_user);Session().commit() | |||
|
151 | In [6]: exit() |
@@ -27,6 +27,7 b' Once installed you need to enable ``dav_' | |||||
27 |
|
27 | |||
28 | $ sudo a2enmod dav_svn |
|
28 | $ sudo a2enmod dav_svn | |
29 | $ sudo a2enmod headers |
|
29 | $ sudo a2enmod headers | |
|
30 | $ sudo a2enmod authn_anon | |||
30 |
|
31 | |||
31 |
|
32 | |||
32 | Configuring Apache Setup |
|
33 | Configuring Apache Setup | |
@@ -55,7 +56,7 b' permission issues could occur. To do thi' | |||||
55 | export APACHE_RUN_GROUP=rhodecode |
|
56 | export APACHE_RUN_GROUP=rhodecode | |
56 |
|
57 | |||
57 | 1. To configure Apache, create and edit a virtual hosts file, for example |
|
58 | 1. To configure Apache, create and edit a virtual hosts file, for example | |
58 |
:file:`/etc/apache2/sites- |
|
59 | :file:`/etc/apache2/sites-enabled/default.conf`. Below is an example | |
59 | how to use one with auto-generated config ```mod_dav_svn.conf``` |
|
60 | how to use one with auto-generated config ```mod_dav_svn.conf``` | |
60 | from configured |RCE| instance. |
|
61 | from configured |RCE| instance. | |
61 |
|
62 |
@@ -13,7 +13,7 b' 1. Open ishell from the terminal and use' | |||||
13 | .. code-block:: bash |
|
13 | .. code-block:: bash | |
14 |
|
14 | |||
15 | # Open iShell from the terminal and set ini file |
|
15 | # Open iShell from the terminal and set ini file | |
16 | $ .rccontrol/enterprise-1/profile/bin/paster ishell .rccontrol/enterprise-1/rhodecode.ini |
|
16 | $ rccontrol ishell enterprise-1 | |
17 |
|
17 | |||
18 | 2. Run the following commands, and ensure that |RCE| has write access to the |
|
18 | 2. Run the following commands, and ensure that |RCE| has write access to the | |
19 | new directory: |
|
19 | new directory: |
@@ -3,21 +3,6 b'' | |||||
3 | Increase Database Performance |
|
3 | Increase Database Performance | |
4 | ----------------------------- |
|
4 | ----------------------------- | |
5 |
|
5 | |||
6 | To increase database performance switch to database-based user sessions. |
|
6 | For tuning PostgreSQL we recommend reading: http://www.revsys.com/writings/postgresql-performance.html | |
7 | File-based sessions are only suitable for smaller setups. The most common |
|
|||
8 | issue being file limit errors which occur if there are lots of session files. |
|
|||
9 | Therefore, in a large scale deployment, to give better performance, |
|
|||
10 | scalability, and maintainability we recommend switching from file-based |
|
|||
11 | sessions to database-based user sessions. |
|
|||
12 |
|
7 | |||
13 | To switch to database-based user sessions uncomment the following section in |
|
8 | For tuning MySQL we recommend reading: http://www.tecmint.com/mysql-mariadb-performance-tuning-and-optimization/ No newline at end of file | |
14 | your :file:`/home/{user}/.rccontrol/{instance-id}/rhodecode.ini` file. |
|
|||
15 |
|
||||
16 | .. code-block:: ini |
|
|||
17 |
|
||||
18 | # db session |
|
|||
19 | beaker.session.type = ext:database |
|
|||
20 |
|
||||
21 | # adjust this property to include your database credentials |
|
|||
22 | beaker.session.sa.url = postgresql://postgres:<pass>@localhost/rhodecode |
|
|||
23 | beaker.session.table_name = db_session |
|
@@ -34,8 +34,8 b' performance boost.' | |||||
34 |
|
34 | |||
35 | .. code-block:: bash |
|
35 | .. code-block:: bash | |
36 |
|
36 | |||
37 |
# mount tmp to memory with 2GB limit and 7 |
|
37 | # mount tmp to memory with 2GB limit and 1777 write permissions | |
38 |
mount -t tmpfs -o size=2G,mode= |
|
38 | mount -t tmpfs -o size=2G,mode=1777 tmpfs /tmp | |
39 |
|
39 | |||
40 | For more information about TMPFS, see the documentation `here`_. |
|
40 | For more information about TMPFS, see the documentation `here`_. | |
41 |
|
41 |
@@ -10,6 +10,7 b' may find some of the following methods u' | |||||
10 |
|
10 | |||
11 | tuning-gunicorn |
|
11 | tuning-gunicorn | |
12 | tuning-vcs-memory-cache |
|
12 | tuning-vcs-memory-cache | |
|
13 | tuning-user-sessions-performance | |||
13 | tuning-increase-db-performance |
|
14 | tuning-increase-db-performance | |
14 | tuning-scale-horizontally |
|
15 | tuning-scale-horizontally | |
15 | tuning-increase-cache-size |
|
16 | tuning-increase-cache-size |
@@ -36,7 +36,7 b' close_pull_request' | |||||
36 | comment_pull_request |
|
36 | comment_pull_request | |
37 | -------------------- |
|
37 | -------------------- | |
38 |
|
38 | |||
39 | .. py:function:: comment_pull_request(apiuser, repoid, pullrequestid, message=<Optional:None>, status=<Optional:None>, userid=<Optional:<OptionalAttr:apiuser>>) |
|
39 | .. py:function:: comment_pull_request(apiuser, repoid, pullrequestid, message=<Optional:None>, commit_id=<Optional:None>, status=<Optional:None>, comment_type=<Optional:u'note'>, resolves_comment_id=<Optional:None>, userid=<Optional:<OptionalAttr:apiuser>>) | |
40 |
|
40 | |||
41 | Comment on the pull request specified with the `pullrequestid`, |
|
41 | Comment on the pull request specified with the `pullrequestid`, | |
42 | in the |repo| specified by the `repoid`, and optionally change the |
|
42 | in the |repo| specified by the `repoid`, and optionally change the | |
@@ -48,15 +48,18 b' comment_pull_request' | |||||
48 | :type repoid: str or int |
|
48 | :type repoid: str or int | |
49 | :param pullrequestid: The pull request ID. |
|
49 | :param pullrequestid: The pull request ID. | |
50 | :type pullrequestid: int |
|
50 | :type pullrequestid: int | |
|
51 | :param commit_id: Specify the commit_id for which to set a comment. If | |||
|
52 | given commit_id is different than latest in the PR status | |||
|
53 | change won't be performed. | |||
|
54 | :type commit_id: str | |||
51 | :param message: The text content of the comment. |
|
55 | :param message: The text content of the comment. | |
52 | :type message: str |
|
56 | :type message: str | |
53 | :param status: (**Optional**) Set the approval status of the pull |
|
57 | :param status: (**Optional**) Set the approval status of the pull | |
54 | request. Valid options are: |
|
58 | request. One of: 'not_reviewed', 'approved', 'rejected', | |
55 |
|
|
59 | 'under_review' | |
56 | * approved |
|
|||
57 | * rejected |
|
|||
58 | * under_review |
|
|||
59 | :type status: str |
|
60 | :type status: str | |
|
61 | :param comment_type: Comment type, one of: 'note', 'todo' | |||
|
62 | :type comment_type: Optional(str), default: 'note' | |||
60 | :param userid: Comment on the pull request as this user |
|
63 | :param userid: Comment on the pull request as this user | |
61 | :type userid: Optional(str or int) |
|
64 | :type userid: Optional(str or int) | |
62 |
|
65 | |||
@@ -68,7 +71,9 b' comment_pull_request' | |||||
68 | result : |
|
71 | result : | |
69 | { |
|
72 | { | |
70 | "pull_request_id": "<Integer>", |
|
73 | "pull_request_id": "<Integer>", | |
71 | "comment_id": "<Integer>" |
|
74 | "comment_id": "<Integer>", | |
|
75 | "status": {"given": <given_status>, | |||
|
76 | "was_changed": <bool status_was_actually_changed> }, | |||
72 | } |
|
77 | } | |
73 | error : null |
|
78 | error : null | |
74 |
|
79 |
@@ -28,7 +28,7 b' add_field_to_repo' | |||||
28 | comment_commit |
|
28 | comment_commit | |
29 | -------------- |
|
29 | -------------- | |
30 |
|
30 | |||
31 |
.. py:function:: comment_commit(apiuser, repoid, commit_id, message, userid=<Optional:<OptionalAttr:apiuser> |
|
31 | .. py:function:: comment_commit(apiuser, repoid, commit_id, message, status=<Optional:None>, comment_type=<Optional:u'note'>, resolves_comment_id=<Optional:None>, userid=<Optional:<OptionalAttr:apiuser>>) | |
32 |
|
32 | |||
33 | Set a commit comment, and optionally change the status of the commit. |
|
33 | Set a commit comment, and optionally change the status of the commit. | |
34 |
|
34 | |||
@@ -40,15 +40,17 b' comment_commit' | |||||
40 | :type commit_id: str |
|
40 | :type commit_id: str | |
41 | :param message: The comment text. |
|
41 | :param message: The comment text. | |
42 | :type message: str |
|
42 | :type message: str | |
|
43 | :param status: (**Optional**) status of commit, one of: 'not_reviewed', | |||
|
44 | 'approved', 'rejected', 'under_review' | |||
|
45 | :type status: str | |||
|
46 | :param comment_type: Comment type, one of: 'note', 'todo' | |||
|
47 | :type comment_type: Optional(str), default: 'note' | |||
43 | :param userid: Set the user name of the comment creator. |
|
48 | :param userid: Set the user name of the comment creator. | |
44 | :type userid: Optional(str or int) |
|
49 | :type userid: Optional(str or int) | |
45 | :param status: status, one of 'not_reviewed', 'approved', 'rejected', |
|
|||
46 | 'under_review' |
|
|||
47 | :type status: str |
|
|||
48 |
|
50 | |||
49 | Example error output: |
|
51 | Example error output: | |
50 |
|
52 | |||
51 |
.. code-block:: |
|
53 | .. code-block:: bash | |
52 |
|
54 | |||
53 | { |
|
55 | { | |
54 | "id" : <id_given_in_input>, |
|
56 | "id" : <id_given_in_input>, | |
@@ -539,7 +541,7 b' get_repo_settings' | |||||
539 | get_repos |
|
541 | get_repos | |
540 | --------- |
|
542 | --------- | |
541 |
|
543 | |||
542 | .. py:function:: get_repos(apiuser) |
|
544 | .. py:function:: get_repos(apiuser, root=<Optional:None>, traverse=<Optional:True>) | |
543 |
|
545 | |||
544 | Lists all existing repositories. |
|
546 | Lists all existing repositories. | |
545 |
|
547 | |||
@@ -548,6 +550,14 b' get_repos' | |||||
548 |
|
550 | |||
549 | :param apiuser: This is filled automatically from the |authtoken|. |
|
551 | :param apiuser: This is filled automatically from the |authtoken|. | |
550 | :type apiuser: AuthUser |
|
552 | :type apiuser: AuthUser | |
|
553 | :param root: specify root repository group to fetch repositories. | |||
|
554 | filters the returned repositories to be members of given root group. | |||
|
555 | :type root: Optional(None) | |||
|
556 | :param traverse: traverse given root into subrepositories. With this flag | |||
|
557 | set to False, it will only return top-level repositories from `root`. | |||
|
558 | if root is empty it will return just top-level repositories. | |||
|
559 | :type traverse: Optional(True) | |||
|
560 | ||||
551 |
|
561 | |||
552 | Example output: |
|
562 | Example output: | |
553 |
|
563 |
@@ -3,6 +3,49 b'' | |||||
3 | server methods |
|
3 | server methods | |
4 | ============== |
|
4 | ============== | |
5 |
|
5 | |||
|
6 | cleanup_sessions | |||
|
7 | ---------------- | |||
|
8 | ||||
|
9 | .. py:function:: cleanup_sessions(apiuser, older_then=<Optional:60>) | |||
|
10 | ||||
|
11 | Triggers a session cleanup action. | |||
|
12 | ||||
|
13 | If the ``older_then`` option is set, only sessions that hasn't been | |||
|
14 | accessed in the given number of days will be removed. | |||
|
15 | ||||
|
16 | This command can only be run using an |authtoken| with admin rights to | |||
|
17 | the specified repository. | |||
|
18 | ||||
|
19 | This command takes the following options: | |||
|
20 | ||||
|
21 | :param apiuser: This is filled automatically from the |authtoken|. | |||
|
22 | :type apiuser: AuthUser | |||
|
23 | :param older_then: Deletes session that hasn't been accessed | |||
|
24 | in given number of days. | |||
|
25 | :type older_then: Optional(int) | |||
|
26 | ||||
|
27 | Example output: | |||
|
28 | ||||
|
29 | .. code-block:: bash | |||
|
30 | ||||
|
31 | id : <id_given_in_input> | |||
|
32 | result: { | |||
|
33 | "backend": "<type of backend>", | |||
|
34 | "sessions_removed": <number_of_removed_sessions> | |||
|
35 | } | |||
|
36 | error : null | |||
|
37 | ||||
|
38 | Example error output: | |||
|
39 | ||||
|
40 | .. code-block:: bash | |||
|
41 | ||||
|
42 | id : <id_given_in_input> | |||
|
43 | result : null | |||
|
44 | error : { | |||
|
45 | 'Error occurred during session cleanup' | |||
|
46 | } | |||
|
47 | ||||
|
48 | ||||
6 | get_ip |
|
49 | get_ip | |
7 | ------ |
|
50 | ------ | |
8 |
|
51 |
@@ -47,6 +47,17 b' Followed by::' | |||||
47 | nix-channel --update |
|
47 | nix-channel --update | |
48 |
|
48 | |||
49 |
|
49 | |||
|
50 | Install required binaries | |||
|
51 | ------------------------- | |||
|
52 | ||||
|
53 | We need some handy tools first. | |||
|
54 | ||||
|
55 | run:: | |||
|
56 | ||||
|
57 | nix-env -i nix-prefetch-hg | |||
|
58 | nix-env -i nix-prefetch-git | |||
|
59 | ||||
|
60 | ||||
50 | Clone the required repositories |
|
61 | Clone the required repositories | |
51 | ------------------------------- |
|
62 | ------------------------------- | |
52 |
|
63 | |||
@@ -64,6 +75,21 b' To do this, use the following example::' | |||||
64 | via support@rhodecode.com |
|
75 | via support@rhodecode.com | |
65 |
|
76 | |||
66 |
|
77 | |||
|
78 | Install some required libraries | |||
|
79 | ------------------------------- | |||
|
80 | ||||
|
81 | There are some required drivers that we need to install to test RhodeCode | |||
|
82 | under different types of databases. For example in Ubuntu we need to install | |||
|
83 | the following. | |||
|
84 | ||||
|
85 | required libraries:: | |||
|
86 | ||||
|
87 | sudo apt-get install libapr1-dev libaprutil1-dev | |||
|
88 | sudo apt-get install libsvn-dev | |||
|
89 | sudo apt-get install mysql-server libmysqlclient-dev | |||
|
90 | sudo apt-get install postgresql postgresql-contrib libpq-dev | |||
|
91 | sudo apt-get install libcurl4-openssl-dev | |||
|
92 | ||||
67 |
|
|
93 | ||
68 | Enter the Development Shell |
|
94 | Enter the Development Shell | |
69 | --------------------------- |
|
95 | --------------------------- |
@@ -9,6 +9,7 b' Release Notes' | |||||
9 | .. toctree:: |
|
9 | .. toctree:: | |
10 | :maxdepth: 1 |
|
10 | :maxdepth: 1 | |
11 |
|
11 | |||
|
12 | release-notes-4.6.0.rst | |||
12 | release-notes-4.5.2.rst |
|
13 | release-notes-4.5.2.rst | |
13 | release-notes-4.5.1.rst |
|
14 | release-notes-4.5.1.rst | |
14 | release-notes-4.5.0.rst |
|
15 | release-notes-4.5.0.rst |
@@ -68,6 +68,7 b'' | |||||
68 | "<%= dirs.js.src %>/rhodecode/utils/os.js", |
|
68 | "<%= dirs.js.src %>/rhodecode/utils/os.js", | |
69 | "<%= dirs.js.src %>/rhodecode/utils/topics.js", |
|
69 | "<%= dirs.js.src %>/rhodecode/utils/topics.js", | |
70 | "<%= dirs.js.src %>/rhodecode/init.js", |
|
70 | "<%= dirs.js.src %>/rhodecode/init.js", | |
|
71 | "<%= dirs.js.src %>/rhodecode/changelog.js", | |||
71 | "<%= dirs.js.src %>/rhodecode/codemirror.js", |
|
72 | "<%= dirs.js.src %>/rhodecode/codemirror.js", | |
72 | "<%= dirs.js.src %>/rhodecode/comments.js", |
|
73 | "<%= dirs.js.src %>/rhodecode/comments.js", | |
73 | "<%= dirs.js.src %>/rhodecode/constants.js", |
|
74 | "<%= dirs.js.src %>/rhodecode/constants.js", |
@@ -100,11 +100,7 b' self: super: {' | |||||
100 | }); |
|
100 | }); | |
101 |
|
101 | |||
102 | py-gfm = super.py-gfm.override { |
|
102 | py-gfm = super.py-gfm.override { | |
103 | src = pkgs.fetchgit { |
|
103 | name = "py-gfm-0.1.3.rhodecode-upstream1"; | |
104 | url = "https://code.rhodecode.com/upstream/py-gfm"; |
|
|||
105 | rev = "0d66a19bc16e3d49de273c0f797d4e4781e8c0f2"; |
|
|||
106 | sha256 = "0ryp74jyihd3ckszq31bml5jr3bciimhfp7va7kw6ld92930ksv3"; |
|
|||
107 | }; |
|
|||
108 | }; |
|
104 | }; | |
109 |
|
105 | |||
110 | pycurl = super.pycurl.override (attrs: { |
|
106 | pycurl = super.pycurl.override (attrs: { | |
@@ -123,12 +119,7 b' self: super: {' | |||||
123 | }); |
|
119 | }); | |
124 |
|
120 | |||
125 | Pylons = super.Pylons.override (attrs: { |
|
121 | Pylons = super.Pylons.override (attrs: { | |
126 |
name = "Pylons-1.0. |
|
122 | name = "Pylons-1.0.2.rhodecode-patch1"; | |
127 | src = pkgs.fetchgit { |
|
|||
128 | url = "https://code.rhodecode.com/upstream/pylons"; |
|
|||
129 | rev = "707354ee4261b9c10450404fc9852ccea4fd667d"; |
|
|||
130 | sha256 = "b2763274c2780523a335f83a1df65be22ebe4ff413a7bc9e9288d23c1f62032e"; |
|
|||
131 | }; |
|
|||
132 | }); |
|
123 | }); | |
133 |
|
124 | |||
134 | pyramid = super.pyramid.override (attrs: { |
|
125 | pyramid = super.pyramid.override (attrs: { | |
@@ -149,16 +140,6 b' self: super: {' | |||||
149 | }; |
|
140 | }; | |
150 | }); |
|
141 | }); | |
151 |
|
142 | |||
152 | Pyro4 = super.Pyro4.override (attrs: { |
|
|||
153 | # TODO: Was not able to generate this version, needs further |
|
|||
154 | # investigation. |
|
|||
155 | name = "Pyro4-4.35"; |
|
|||
156 | src = pkgs.fetchurl { |
|
|||
157 | url = "https://pypi.python.org/packages/source/P/Pyro4/Pyro4-4.35.src.tar.gz"; |
|
|||
158 | md5 = "cbe6cb855f086a0f092ca075005855f3"; |
|
|||
159 | }; |
|
|||
160 | }); |
|
|||
161 |
|
||||
162 | pysqlite = super.pysqlite.override (attrs: { |
|
143 | pysqlite = super.pysqlite.override (attrs: { | |
163 | propagatedBuildInputs = [ |
|
144 | propagatedBuildInputs = [ | |
164 | pkgs.sqlite |
|
145 | pkgs.sqlite | |
@@ -202,12 +183,6 b' self: super: {' | |||||
202 | ''; |
|
183 | ''; | |
203 | }); |
|
184 | }); | |
204 |
|
185 | |||
205 | rhodecode-tools = super.rhodecode-tools.override (attrs: { |
|
|||
206 | patches = [ |
|
|||
207 | ./patch-rhodecode-tools-setup.diff |
|
|||
208 | ]; |
|
|||
209 | }); |
|
|||
210 |
|
||||
211 | URLObject = super.URLObject.override (attrs: { |
|
186 | URLObject = super.URLObject.override (attrs: { | |
212 | meta = { |
|
187 | meta = { | |
213 | license = { |
|
188 | license = { |
@@ -81,26 +81,26 b'' | |||||
81 | }; |
|
81 | }; | |
82 | }; |
|
82 | }; | |
83 | Mako = super.buildPythonPackage { |
|
83 | Mako = super.buildPythonPackage { | |
84 |
name = "Mako-1.0. |
|
84 | name = "Mako-1.0.6"; | |
85 | buildInputs = with self; []; |
|
85 | buildInputs = with self; []; | |
86 | doCheck = false; |
|
86 | doCheck = false; | |
87 | propagatedBuildInputs = with self; [MarkupSafe]; |
|
87 | propagatedBuildInputs = with self; [MarkupSafe]; | |
88 | src = fetchurl { |
|
88 | src = fetchurl { | |
89 | url = "https://pypi.python.org/packages/8e/a4/aa56533ecaa5f22ca92428f74e074d0c9337282933c722391902c8f9e0f8/Mako-1.0.1.tar.gz"; |
|
89 | url = "https://pypi.python.org/packages/56/4b/cb75836863a6382199aefb3d3809937e21fa4cb0db15a4f4ba0ecc2e7e8e/Mako-1.0.6.tar.gz"; | |
90 | md5 = "9f0aafd177b039ef67b90ea350497a54"; |
|
90 | md5 = "a28e22a339080316b2acc352b9ee631c"; | |
91 | }; |
|
91 | }; | |
92 | meta = { |
|
92 | meta = { | |
93 | license = [ pkgs.lib.licenses.mit ]; |
|
93 | license = [ pkgs.lib.licenses.mit ]; | |
94 | }; |
|
94 | }; | |
95 | }; |
|
95 | }; | |
96 | Markdown = super.buildPythonPackage { |
|
96 | Markdown = super.buildPythonPackage { | |
97 |
name = "Markdown-2.6. |
|
97 | name = "Markdown-2.6.7"; | |
98 | buildInputs = with self; []; |
|
98 | buildInputs = with self; []; | |
99 | doCheck = false; |
|
99 | doCheck = false; | |
100 | propagatedBuildInputs = with self; []; |
|
100 | propagatedBuildInputs = with self; []; | |
101 | src = fetchurl { |
|
101 | src = fetchurl { | |
102 |
url = "https://pypi.python.org/packages/ |
|
102 | url = "https://pypi.python.org/packages/48/a4/fc6b002789c2239ac620ca963694c95b8f74e4747769cdf6021276939e74/Markdown-2.6.7.zip"; | |
103 | md5 = "256d19afcc564dc4ce4c229bb762f7ae"; |
|
103 | md5 = "632710a7474bbb74a82084392251061f"; | |
104 | }; |
|
104 | }; | |
105 | meta = { |
|
105 | meta = { | |
106 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
|
106 | license = [ pkgs.lib.licenses.bsdOriginal ]; | |
@@ -133,13 +133,13 b'' | |||||
133 | }; |
|
133 | }; | |
134 | }; |
|
134 | }; | |
135 | Paste = super.buildPythonPackage { |
|
135 | Paste = super.buildPythonPackage { | |
136 |
name = "Paste-2.0. |
|
136 | name = "Paste-2.0.3"; | |
137 | buildInputs = with self; []; |
|
137 | buildInputs = with self; []; | |
138 | doCheck = false; |
|
138 | doCheck = false; | |
139 | propagatedBuildInputs = with self; [six]; |
|
139 | propagatedBuildInputs = with self; [six]; | |
140 | src = fetchurl { |
|
140 | src = fetchurl { | |
141 | url = "https://pypi.python.org/packages/d5/8d/0f8ac40687b97ff3e07ebd1369be20bdb3f93864d2dc3c2ff542edb4ce50/Paste-2.0.2.tar.gz"; |
|
141 | url = "https://pypi.python.org/packages/30/c3/5c2f7c7a02e4f58d4454353fa1c32c94f79fa4e36d07a67c0ac295ea369e/Paste-2.0.3.tar.gz"; | |
142 | md5 = "4bfc8a7eaf858f6309d2ac0f40fc951c"; |
|
142 | md5 = "1231e14eae62fa7ed76e9130b04bc61e"; | |
143 | }; |
|
143 | }; | |
144 | meta = { |
|
144 | meta = { | |
145 | license = [ pkgs.lib.licenses.mit ]; |
|
145 | license = [ pkgs.lib.licenses.mit ]; | |
@@ -172,26 +172,26 b'' | |||||
172 | }; |
|
172 | }; | |
173 | }; |
|
173 | }; | |
174 | Pygments = super.buildPythonPackage { |
|
174 | Pygments = super.buildPythonPackage { | |
175 |
name = "Pygments-2. |
|
175 | name = "Pygments-2.2.0"; | |
176 | buildInputs = with self; []; |
|
176 | buildInputs = with self; []; | |
177 | doCheck = false; |
|
177 | doCheck = false; | |
178 | propagatedBuildInputs = with self; []; |
|
178 | propagatedBuildInputs = with self; []; | |
179 | src = fetchurl { |
|
179 | src = fetchurl { | |
180 |
url = "https://pypi.python.org/packages/ |
|
180 | url = "https://pypi.python.org/packages/71/2a/2e4e77803a8bd6408a2903340ac498cb0a2181811af7c9ec92cb70b0308a/Pygments-2.2.0.tar.gz"; | |
181 | md5 = "ed3fba2467c8afcda4d317e4ef2c6150"; |
|
181 | md5 = "13037baca42f16917cbd5ad2fab50844"; | |
182 | }; |
|
182 | }; | |
183 | meta = { |
|
183 | meta = { | |
184 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
|
184 | license = [ pkgs.lib.licenses.bsdOriginal ]; | |
185 | }; |
|
185 | }; | |
186 | }; |
|
186 | }; | |
187 | Pylons = super.buildPythonPackage { |
|
187 | Pylons = super.buildPythonPackage { | |
188 | name = "Pylons-1.0.1"; |
|
188 | name = "Pylons-1.0.2.dev20161213"; | |
189 | buildInputs = with self; []; |
|
189 | buildInputs = with self; []; | |
190 | doCheck = false; |
|
190 | doCheck = false; | |
191 | propagatedBuildInputs = with self; [Routes WebHelpers Beaker Paste PasteDeploy PasteScript FormEncode simplejson decorator nose Mako WebError WebTest Tempita MarkupSafe WebOb]; |
|
191 | propagatedBuildInputs = with self; [Routes WebHelpers Beaker Paste PasteDeploy PasteScript FormEncode simplejson decorator nose Mako WebError WebTest Tempita MarkupSafe WebOb]; | |
192 | src = fetchurl { |
|
192 | src = fetchurl { | |
193 | url = "https://pypi.python.org/packages/a2/69/b835a6bad00acbfeed3f33c6e44fa3f936efc998c795bfb15c61a79ecf62/Pylons-1.0.1.tar.gz"; |
|
193 | url = "https://code.rhodecode.com/upstream/pylons/archive/707354ee4261b9c10450404fc9852ccea4fd667d.tar.gz?md5=f26633726fa2cd3a340316ee6a5d218f"; | |
194 | md5 = "6cb880d75fa81213192142b07a6e4915"; |
|
194 | md5 = "f26633726fa2cd3a340316ee6a5d218f"; | |
195 | }; |
|
195 | }; | |
196 | meta = { |
|
196 | meta = { | |
197 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
|
197 | license = [ pkgs.lib.licenses.bsdOriginal ]; | |
@@ -341,13 +341,13 b'' | |||||
341 | }; |
|
341 | }; | |
342 | }; |
|
342 | }; | |
343 | Whoosh = super.buildPythonPackage { |
|
343 | Whoosh = super.buildPythonPackage { | |
344 |
name = "Whoosh-2.7. |
|
344 | name = "Whoosh-2.7.4"; | |
345 | buildInputs = with self; []; |
|
345 | buildInputs = with self; []; | |
346 | doCheck = false; |
|
346 | doCheck = false; | |
347 | propagatedBuildInputs = with self; []; |
|
347 | propagatedBuildInputs = with self; []; | |
348 | src = fetchurl { |
|
348 | src = fetchurl { | |
349 |
url = "https://pypi.python.org/packages/ |
|
349 | url = "https://pypi.python.org/packages/25/2b/6beed2107b148edc1321da0d489afc4617b9ed317ef7b72d4993cad9b684/Whoosh-2.7.4.tar.gz"; | |
350 | md5 = "7abfd970f16fadc7311960f3fa0bc7a9"; |
|
350 | md5 = "c2710105f20b3e29936bd2357383c325"; | |
351 | }; |
|
351 | }; | |
352 | meta = { |
|
352 | meta = { | |
353 | license = [ pkgs.lib.licenses.bsdOriginal pkgs.lib.licenses.bsd2 ]; |
|
353 | license = [ pkgs.lib.licenses.bsdOriginal pkgs.lib.licenses.bsd2 ]; | |
@@ -639,19 +639,6 b'' | |||||
639 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
|
639 | license = [ pkgs.lib.licenses.bsdOriginal ]; | |
640 | }; |
|
640 | }; | |
641 | }; |
|
641 | }; | |
642 | dulwich = super.buildPythonPackage { |
|
|||
643 | name = "dulwich-0.12.0"; |
|
|||
644 | buildInputs = with self; []; |
|
|||
645 | doCheck = false; |
|
|||
646 | propagatedBuildInputs = with self; []; |
|
|||
647 | src = fetchurl { |
|
|||
648 | url = "https://pypi.python.org/packages/6f/04/fbe561b6d45c0ec758330d5b7f5ba4b6cb4f1ca1ab49859d2fc16320da75/dulwich-0.12.0.tar.gz"; |
|
|||
649 | md5 = "f3a8a12bd9f9dd8c233e18f3d49436fa"; |
|
|||
650 | }; |
|
|||
651 | meta = { |
|
|||
652 | license = [ pkgs.lib.licenses.gpl2Plus ]; |
|
|||
653 | }; |
|
|||
654 | }; |
|
|||
655 | ecdsa = super.buildPythonPackage { |
|
642 | ecdsa = super.buildPythonPackage { | |
656 | name = "ecdsa-0.11"; |
|
643 | name = "ecdsa-0.11"; | |
657 | buildInputs = with self; []; |
|
644 | buildInputs = with self; []; | |
@@ -679,13 +666,13 b'' | |||||
679 | }; |
|
666 | }; | |
680 | }; |
|
667 | }; | |
681 | elasticsearch-dsl = super.buildPythonPackage { |
|
668 | elasticsearch-dsl = super.buildPythonPackage { | |
682 |
name = "elasticsearch-dsl-2. |
|
669 | name = "elasticsearch-dsl-2.2.0"; | |
683 | buildInputs = with self; []; |
|
670 | buildInputs = with self; []; | |
684 | doCheck = false; |
|
671 | doCheck = false; | |
685 | propagatedBuildInputs = with self; [six python-dateutil elasticsearch]; |
|
672 | propagatedBuildInputs = with self; [six python-dateutil elasticsearch]; | |
686 | src = fetchurl { |
|
673 | src = fetchurl { | |
687 |
url = "https://pypi.python.org/packages/ |
|
674 | url = "https://pypi.python.org/packages/66/2f/52a086968788e58461641570f45c3207a52d46ebbe9b77dc22b6a8ffda66/elasticsearch-dsl-2.2.0.tar.gz"; | |
688 | md5 = "4cdfec81bb35383dd3b7d02d7dc5ee68"; |
|
675 | md5 = "fa6bd3c87ea3caa8f0f051bc37c53221"; | |
689 | }; |
|
676 | }; | |
690 | meta = { |
|
677 | meta = { | |
691 | license = [ pkgs.lib.licenses.asl20 ]; |
|
678 | license = [ pkgs.lib.licenses.asl20 ]; | |
@@ -731,13 +718,13 b'' | |||||
731 | }; |
|
718 | }; | |
732 | }; |
|
719 | }; | |
733 | gevent = super.buildPythonPackage { |
|
720 | gevent = super.buildPythonPackage { | |
734 |
name = "gevent-1.1. |
|
721 | name = "gevent-1.1.2"; | |
735 | buildInputs = with self; []; |
|
722 | buildInputs = with self; []; | |
736 | doCheck = false; |
|
723 | doCheck = false; | |
737 | propagatedBuildInputs = with self; [greenlet]; |
|
724 | propagatedBuildInputs = with self; [greenlet]; | |
738 | src = fetchurl { |
|
725 | src = fetchurl { | |
739 |
url = "https://pypi.python.org/packages/ |
|
726 | url = "https://pypi.python.org/packages/43/8f/cb3224a0e6ab663547f45c10d0651cfd52633fde4283bf68d627084df8cc/gevent-1.1.2.tar.gz"; | |
740 | md5 = "1532f5396ab4d07a231f1935483be7c3"; |
|
727 | md5 = "bb32a2f852a4997138014d5007215c6e"; | |
741 | }; |
|
728 | }; | |
742 | meta = { |
|
729 | meta = { | |
743 | license = [ pkgs.lib.licenses.mit ]; |
|
730 | license = [ pkgs.lib.licenses.mit ]; | |
@@ -757,26 +744,26 b'' | |||||
757 | }; |
|
744 | }; | |
758 | }; |
|
745 | }; | |
759 | gprof2dot = super.buildPythonPackage { |
|
746 | gprof2dot = super.buildPythonPackage { | |
760 |
name = "gprof2dot-201 |
|
747 | name = "gprof2dot-2016.10.13"; | |
761 | buildInputs = with self; []; |
|
748 | buildInputs = with self; []; | |
762 | doCheck = false; |
|
749 | doCheck = false; | |
763 | propagatedBuildInputs = with self; []; |
|
750 | propagatedBuildInputs = with self; []; | |
764 | src = fetchurl { |
|
751 | src = fetchurl { | |
765 |
url = "https://pypi.python.org/packages/ |
|
752 | url = "https://pypi.python.org/packages/a0/e0/73c71baed306f0402a00a94ffc7b2be94ad1296dfcb8b46912655b93154c/gprof2dot-2016.10.13.tar.gz"; | |
766 | md5 = "e23bf4e2f94db032750c193384b4165b"; |
|
753 | md5 = "0125401f15fd2afe1df686a76c64a4fd"; | |
767 | }; |
|
754 | }; | |
768 | meta = { |
|
755 | meta = { | |
769 | license = [ { fullName = "LGPL"; } ]; |
|
756 | license = [ { fullName = "LGPL"; } ]; | |
770 | }; |
|
757 | }; | |
771 | }; |
|
758 | }; | |
772 | greenlet = super.buildPythonPackage { |
|
759 | greenlet = super.buildPythonPackage { | |
773 |
name = "greenlet-0.4. |
|
760 | name = "greenlet-0.4.10"; | |
774 | buildInputs = with self; []; |
|
761 | buildInputs = with self; []; | |
775 | doCheck = false; |
|
762 | doCheck = false; | |
776 | propagatedBuildInputs = with self; []; |
|
763 | propagatedBuildInputs = with self; []; | |
777 | src = fetchurl { |
|
764 | src = fetchurl { | |
778 | url = "https://pypi.python.org/packages/4e/3d/9d421539b74e33608b245092870156b2e171fb49f2b51390aa4641eecb4a/greenlet-0.4.9.zip"; |
|
765 | url = "https://pypi.python.org/packages/67/62/ca2a95648666eaa2ffeb6a9b3964f21d419ae27f82f2e66b53da5b943fc4/greenlet-0.4.10.zip"; | |
779 | md5 = "c6659cdb2a5e591723e629d2eef22e82"; |
|
766 | md5 = "bed0c4b3b896702131f4d5c72f87c41d"; | |
780 | }; |
|
767 | }; | |
781 | meta = { |
|
768 | meta = { | |
782 | license = [ pkgs.lib.licenses.mit ]; |
|
769 | license = [ pkgs.lib.licenses.mit ]; | |
@@ -939,13 +926,13 b'' | |||||
939 | }; |
|
926 | }; | |
940 | }; |
|
927 | }; | |
941 | msgpack-python = super.buildPythonPackage { |
|
928 | msgpack-python = super.buildPythonPackage { | |
942 |
name = "msgpack-python-0.4. |
|
929 | name = "msgpack-python-0.4.8"; | |
943 | buildInputs = with self; []; |
|
930 | buildInputs = with self; []; | |
944 | doCheck = false; |
|
931 | doCheck = false; | |
945 | propagatedBuildInputs = with self; []; |
|
932 | propagatedBuildInputs = with self; []; | |
946 | src = fetchurl { |
|
933 | src = fetchurl { | |
947 |
url = "https://pypi.python.org/packages/ |
|
934 | url = "https://pypi.python.org/packages/21/27/8a1d82041c7a2a51fcc73675875a5f9ea06c2663e02fcfeb708be1d081a0/msgpack-python-0.4.8.tar.gz"; | |
948 | md5 = "8b317669314cf1bc881716cccdaccb30"; |
|
935 | md5 = "dcd854fb41ee7584ebbf35e049e6be98"; | |
949 | }; |
|
936 | }; | |
950 | meta = { |
|
937 | meta = { | |
951 | license = [ pkgs.lib.licenses.asl20 ]; |
|
938 | license = [ pkgs.lib.licenses.asl20 ]; | |
@@ -1108,13 +1095,13 b'' | |||||
1108 | }; |
|
1095 | }; | |
1109 | }; |
|
1096 | }; | |
1110 | py = super.buildPythonPackage { |
|
1097 | py = super.buildPythonPackage { | |
1111 |
name = "py-1.4. |
|
1098 | name = "py-1.4.31"; | |
1112 | buildInputs = with self; []; |
|
1099 | buildInputs = with self; []; | |
1113 | doCheck = false; |
|
1100 | doCheck = false; | |
1114 | propagatedBuildInputs = with self; []; |
|
1101 | propagatedBuildInputs = with self; []; | |
1115 | src = fetchurl { |
|
1102 | src = fetchurl { | |
1116 | url = "https://pypi.python.org/packages/2a/bc/a1a4a332ac10069b8e5e25136a35e08a03f01fd6ab03d819889d79a1fd65/py-1.4.29.tar.gz"; |
|
1103 | url = "https://pypi.python.org/packages/f4/9a/8dfda23f36600dd701c6722316ba8a3ab4b990261f83e7d3ffc6dfedf7ef/py-1.4.31.tar.gz"; | |
1117 | md5 = "c28e0accba523a29b35a48bb703fb96c"; |
|
1104 | md5 = "5d2c63c56dc3f2115ec35c066ecd582b"; | |
1118 | }; |
|
1105 | }; | |
1119 | meta = { |
|
1106 | meta = { | |
1120 | license = [ pkgs.lib.licenses.mit ]; |
|
1107 | license = [ pkgs.lib.licenses.mit ]; | |
@@ -1139,8 +1126,8 b'' | |||||
1139 | doCheck = false; |
|
1126 | doCheck = false; | |
1140 | propagatedBuildInputs = with self; [setuptools Markdown]; |
|
1127 | propagatedBuildInputs = with self; [setuptools Markdown]; | |
1141 | src = fetchurl { |
|
1128 | src = fetchurl { | |
1142 | url = "https://pypi.python.org/packages/12/e4/6b3d8678da04f97d7490d8264d8de51c2dc9fb91209ccee9c515c95e14c5/py-gfm-0.1.3.tar.gz"; |
|
1129 | url = "https://code.rhodecode.com/upstream/py-gfm/archive/0d66a19bc16e3d49de273c0f797d4e4781e8c0f2.tar.gz?md5=0d0d5385bfb629eea636a80b9c2bfd16"; | |
1143 | md5 = "e588d9e69640a241b97e2c59c22527a6"; |
|
1130 | md5 = "0d0d5385bfb629eea636a80b9c2bfd16"; | |
1144 | }; |
|
1131 | }; | |
1145 | meta = { |
|
1132 | meta = { | |
1146 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
|
1133 | license = [ pkgs.lib.licenses.bsdOriginal ]; | |
@@ -1290,13 +1277,13 b'' | |||||
1290 | }; |
|
1277 | }; | |
1291 | }; |
|
1278 | }; | |
1292 | pytest = super.buildPythonPackage { |
|
1279 | pytest = super.buildPythonPackage { | |
1293 |
name = "pytest- |
|
1280 | name = "pytest-3.0.5"; | |
1294 | buildInputs = with self; []; |
|
1281 | buildInputs = with self; []; | |
1295 | doCheck = false; |
|
1282 | doCheck = false; | |
1296 | propagatedBuildInputs = with self; [py]; |
|
1283 | propagatedBuildInputs = with self; [py]; | |
1297 | src = fetchurl { |
|
1284 | src = fetchurl { | |
1298 | url = "https://pypi.python.org/packages/b1/3d/d7ea9b0c51e0cacded856e49859f0a13452747491e842c236bbab3714afe/pytest-2.8.5.zip"; |
|
1285 | url = "https://pypi.python.org/packages/a8/87/b7ca49efe52d2b4169f2bfc49aa5e384173c4619ea8e635f123a0dac5b75/pytest-3.0.5.tar.gz"; | |
1299 | md5 = "8493b06f700862f1294298d6c1b715a9"; |
|
1286 | md5 = "cefd527b59332688bf5db4a10aa8a7cb"; | |
1300 | }; |
|
1287 | }; | |
1301 | meta = { |
|
1288 | meta = { | |
1302 | license = [ pkgs.lib.licenses.mit ]; |
|
1289 | license = [ pkgs.lib.licenses.mit ]; | |
@@ -1316,52 +1303,65 b'' | |||||
1316 | }; |
|
1303 | }; | |
1317 | }; |
|
1304 | }; | |
1318 | pytest-cov = super.buildPythonPackage { |
|
1305 | pytest-cov = super.buildPythonPackage { | |
1319 |
name = "pytest-cov- |
|
1306 | name = "pytest-cov-2.4.0"; | |
1320 | buildInputs = with self; []; |
|
1307 | buildInputs = with self; []; | |
1321 | doCheck = false; |
|
1308 | doCheck = false; | |
1322 |
propagatedBuildInputs = with self; [ |
|
1309 | propagatedBuildInputs = with self; [pytest coverage]; | |
1323 | src = fetchurl { |
|
1310 | src = fetchurl { | |
1324 | url = "https://pypi.python.org/packages/11/4b/b04646e97f1721878eb21e9f779102d84dd044d324382263b1770a3e4838/pytest-cov-1.8.1.tar.gz"; |
|
1311 | url = "https://pypi.python.org/packages/00/c0/2bfd1fcdb9d407b8ac8185b1cb5ff458105c6b207a9a7f0e13032de9828f/pytest-cov-2.4.0.tar.gz"; | |
1325 | md5 = "76c778afa2494088270348be42d759fc"; |
|
1312 | md5 = "2fda09677d232acc99ec1b3c5831e33f"; | |
1326 | }; |
|
1313 | }; | |
1327 | meta = { |
|
1314 | meta = { | |
1328 | license = [ pkgs.lib.licenses.mit ]; |
|
1315 | license = [ pkgs.lib.licenses.bsdOriginal pkgs.lib.licenses.mit ]; | |
1329 | }; |
|
1316 | }; | |
1330 | }; |
|
1317 | }; | |
1331 | pytest-profiling = super.buildPythonPackage { |
|
1318 | pytest-profiling = super.buildPythonPackage { | |
1332 |
name = "pytest-profiling-1. |
|
1319 | name = "pytest-profiling-1.2.2"; | |
1333 | buildInputs = with self; []; |
|
1320 | buildInputs = with self; []; | |
1334 | doCheck = false; |
|
1321 | doCheck = false; | |
1335 | propagatedBuildInputs = with self; [six pytest gprof2dot]; |
|
1322 | propagatedBuildInputs = with self; [six pytest gprof2dot]; | |
1336 | src = fetchurl { |
|
1323 | src = fetchurl { | |
1337 |
url = "https://pypi.python.org/packages/ |
|
1324 | url = "https://pypi.python.org/packages/73/e8/804681323bac0bc45c520ec34185ba8469008942266d0074699b204835c1/pytest-profiling-1.2.2.tar.gz"; | |
1338 | md5 = "354404eb5b3fd4dc5eb7fffbb3d9b68b"; |
|
1325 | md5 = "0a16d7dda2d23b91e9730fa4558cf728"; | |
1339 | }; |
|
1326 | }; | |
1340 | meta = { |
|
1327 | meta = { | |
1341 | license = [ pkgs.lib.licenses.mit ]; |
|
1328 | license = [ pkgs.lib.licenses.mit ]; | |
1342 | }; |
|
1329 | }; | |
1343 | }; |
|
1330 | }; | |
1344 | pytest-runner = super.buildPythonPackage { |
|
1331 | pytest-runner = super.buildPythonPackage { | |
1345 |
name = "pytest-runner-2. |
|
1332 | name = "pytest-runner-2.9"; | |
1346 | buildInputs = with self; []; |
|
1333 | buildInputs = with self; []; | |
1347 | doCheck = false; |
|
1334 | doCheck = false; | |
1348 | propagatedBuildInputs = with self; []; |
|
1335 | propagatedBuildInputs = with self; []; | |
1349 | src = fetchurl { |
|
1336 | src = fetchurl { | |
1350 |
url = "https://pypi.python.org/packages/ |
|
1337 | url = "https://pypi.python.org/packages/11/d4/c335ddf94463e451109e3494e909765c3e5205787b772e3b25ee8601b86a/pytest-runner-2.9.tar.gz"; | |
1351 | md5 = "e56f0bc8d79a6bd91772b44ef4215c7e"; |
|
1338 | md5 = "2212a2e34404b0960b2fdc2c469247b2"; | |
1352 | }; |
|
1339 | }; | |
1353 | meta = { |
|
1340 | meta = { | |
1354 | license = [ pkgs.lib.licenses.mit ]; |
|
1341 | license = [ pkgs.lib.licenses.mit ]; | |
1355 | }; |
|
1342 | }; | |
1356 | }; |
|
1343 | }; | |
|
1344 | pytest-sugar = super.buildPythonPackage { | |||
|
1345 | name = "pytest-sugar-0.7.1"; | |||
|
1346 | buildInputs = with self; []; | |||
|
1347 | doCheck = false; | |||
|
1348 | propagatedBuildInputs = with self; [pytest termcolor]; | |||
|
1349 | src = fetchurl { | |||
|
1350 | url = "https://pypi.python.org/packages/03/97/05d988b4fa870e7373e8ee4582408543b9ca2bd35c3c67b569369c6f9c49/pytest-sugar-0.7.1.tar.gz"; | |||
|
1351 | md5 = "7400f7c11f3d572b2c2a3b60352d35fe"; | |||
|
1352 | }; | |||
|
1353 | meta = { | |||
|
1354 | license = [ pkgs.lib.licenses.bsdOriginal ]; | |||
|
1355 | }; | |||
|
1356 | }; | |||
1357 | pytest-timeout = super.buildPythonPackage { |
|
1357 | pytest-timeout = super.buildPythonPackage { | |
1358 |
name = "pytest-timeout- |
|
1358 | name = "pytest-timeout-1.2.0"; | |
1359 | buildInputs = with self; []; |
|
1359 | buildInputs = with self; []; | |
1360 | doCheck = false; |
|
1360 | doCheck = false; | |
1361 | propagatedBuildInputs = with self; [pytest]; |
|
1361 | propagatedBuildInputs = with self; [pytest]; | |
1362 | src = fetchurl { |
|
1362 | src = fetchurl { | |
1363 |
url = "https://pypi.python.org/packages/ |
|
1363 | url = "https://pypi.python.org/packages/cc/b7/b2a61365ea6b6d2e8881360ae7ed8dad0327ad2df89f2f0be4a02304deb2/pytest-timeout-1.2.0.tar.gz"; | |
1364 | md5 = "03b28aff69cbbfb959ed35ade5fde262"; |
|
1364 | md5 = "83607d91aa163562c7ee835da57d061d"; | |
1365 | }; |
|
1365 | }; | |
1366 | meta = { |
|
1366 | meta = { | |
1367 | license = [ pkgs.lib.licenses.mit { fullName = "DFSG approved"; } ]; |
|
1367 | license = [ pkgs.lib.licenses.mit { fullName = "DFSG approved"; } ]; | |
@@ -1498,36 +1498,36 b'' | |||||
1498 | }; |
|
1498 | }; | |
1499 | }; |
|
1499 | }; | |
1500 | rhodecode-enterprise-ce = super.buildPythonPackage { |
|
1500 | rhodecode-enterprise-ce = super.buildPythonPackage { | |
1501 |
name = "rhodecode-enterprise-ce-4. |
|
1501 | name = "rhodecode-enterprise-ce-4.6.0"; | |
1502 | buildInputs = with self; [WebTest configobj cssselect lxml mock pytest pytest-cov pytest-runner pytest-sugar]; |
|
1502 | buildInputs = with self; [pytest py pytest-cov pytest-sugar pytest-runner pytest-catchlog pytest-profiling gprof2dot pytest-timeout mock WebTest cov-core coverage cssselect lxml configobj]; | |
1503 | doCheck = true; |
|
1503 | doCheck = true; | |
1504 | propagatedBuildInputs = with self; [Babel Beaker FormEncode Mako Markdown MarkupSafe MySQL-python Paste PasteDeploy PasteScript Pygments pygments-markdown-lexer Pylons Pyro4 Routes SQLAlchemy Tempita URLObject WebError WebHelpers WebHelpers2 WebOb WebTest Whoosh alembic amqplib anyjson appenlight-client authomatic backport-ipaddress celery channelstream colander decorator deform docutils gevent gunicorn infrae.cache ipython iso8601 kombu msgpack-python packaging psycopg2 py-gfm pycrypto pycurl pyparsing pyramid pyramid-debugtoolbar pyramid-mako pyramid-beaker pysqlite python-dateutil python-ldap python-memcached python-pam recaptcha-client repoze.lru requests simplejson subprocess32 waitress zope.cachedescriptors dogpile.cache dogpile.core psutil py-bcrypt]; |
|
1504 | propagatedBuildInputs = with self; [Babel Beaker FormEncode Mako Markdown MarkupSafe MySQL-python Paste PasteDeploy PasteScript Pygments pygments-markdown-lexer Pylons Pyro4 Routes SQLAlchemy Tempita URLObject WebError WebHelpers WebHelpers2 WebOb WebTest Whoosh alembic amqplib anyjson appenlight-client authomatic backport-ipaddress celery channelstream colander decorator deform docutils gevent gunicorn infrae.cache ipython iso8601 kombu msgpack-python packaging psycopg2 py-gfm pycrypto pycurl pyparsing pyramid pyramid-debugtoolbar pyramid-mako pyramid-beaker pysqlite python-dateutil python-ldap python-memcached python-pam recaptcha-client repoze.lru requests simplejson subprocess32 waitress zope.cachedescriptors dogpile.cache dogpile.core psutil py-bcrypt]; | |
1505 | src = ./.; |
|
1505 | src = ./.; | |
1506 | meta = { |
|
1506 | meta = { | |
1507 | license = [ { fullName = "AGPLv3, and Commercial License"; } ]; |
|
1507 | license = [ { fullName = "Affero GNU General Public License v3 or later (AGPLv3+)"; } { fullName = "AGPLv3, and Commercial License"; } ]; | |
1508 | }; |
|
1508 | }; | |
1509 | }; |
|
1509 | }; | |
1510 | rhodecode-tools = super.buildPythonPackage { |
|
1510 | rhodecode-tools = super.buildPythonPackage { | |
1511 |
name = "rhodecode-tools-0.1 |
|
1511 | name = "rhodecode-tools-0.11.0"; | |
1512 | buildInputs = with self; []; |
|
1512 | buildInputs = with self; []; | |
1513 | doCheck = false; |
|
1513 | doCheck = false; | |
1514 |
propagatedBuildInputs = with self; [click future six Mako MarkupSafe requests |
|
1514 | propagatedBuildInputs = with self; [click future six Mako MarkupSafe requests elasticsearch elasticsearch-dsl urllib3 Whoosh]; | |
1515 | src = fetchurl { |
|
1515 | src = fetchurl { | |
1516 |
url = "https://code.rhodecode.com/rhodecode-tools-ce/archive/v0.1 |
|
1516 | url = "https://code.rhodecode.com/rhodecode-tools-ce/archive/v0.11.0.tar.gz?md5=e5fd0a8363af08a0ced71b50ca9cce15"; | |
1517 | md5 = "d2af3985a1a32a678944d4d48870cb04"; |
|
1517 | md5 = "e5fd0a8363af08a0ced71b50ca9cce15"; | |
1518 | }; |
|
1518 | }; | |
1519 | meta = { |
|
1519 | meta = { | |
1520 | license = [ { fullName = "AGPLv3 and Proprietary"; } ]; |
|
1520 | license = [ { fullName = "AGPLv3 and Proprietary"; } ]; | |
1521 | }; |
|
1521 | }; | |
1522 | }; |
|
1522 | }; | |
1523 | serpent = super.buildPythonPackage { |
|
1523 | serpent = super.buildPythonPackage { | |
1524 |
name = "serpent-1.1 |
|
1524 | name = "serpent-1.15"; | |
1525 | buildInputs = with self; []; |
|
1525 | buildInputs = with self; []; | |
1526 | doCheck = false; |
|
1526 | doCheck = false; | |
1527 | propagatedBuildInputs = with self; []; |
|
1527 | propagatedBuildInputs = with self; []; | |
1528 | src = fetchurl { |
|
1528 | src = fetchurl { | |
1529 |
url = "https://pypi.python.org/packages/ |
|
1529 | url = "https://pypi.python.org/packages/7b/38/b2b27673a882ff2ea5871bb3e3e6b496ebbaafd1612e51990ffb158b9254/serpent-1.15.tar.gz"; | |
1530 | md5 = "05869ac7b062828b34f8f927f0457b65"; |
|
1530 | md5 = "e27b1aad5c218e16442f52abb7c7053a"; | |
1531 | }; |
|
1531 | }; | |
1532 | meta = { |
|
1532 | meta = { | |
1533 | license = [ pkgs.lib.licenses.mit ]; |
|
1533 | license = [ pkgs.lib.licenses.mit ]; | |
@@ -1547,26 +1547,26 b'' | |||||
1547 | }; |
|
1547 | }; | |
1548 | }; |
|
1548 | }; | |
1549 | setuptools = super.buildPythonPackage { |
|
1549 | setuptools = super.buildPythonPackage { | |
1550 |
name = "setuptools- |
|
1550 | name = "setuptools-30.1.0"; | |
1551 | buildInputs = with self; []; |
|
1551 | buildInputs = with self; []; | |
1552 | doCheck = false; |
|
1552 | doCheck = false; | |
1553 | propagatedBuildInputs = with self; []; |
|
1553 | propagatedBuildInputs = with self; []; | |
1554 | src = fetchurl { |
|
1554 | src = fetchurl { | |
1555 | url = "https://pypi.python.org/packages/c4/19/c1bdc88b53da654df43770f941079dbab4e4788c2dcb5658fb86259894c7/setuptools-20.8.1.zip"; |
|
1555 | url = "https://pypi.python.org/packages/1e/43/002c8616db9a3e7be23c2556e39b90a32bb40ba0dc652de1999d5334d372/setuptools-30.1.0.tar.gz"; | |
1556 | md5 = "fe58a5cac0df20bb83942b252a4b0543"; |
|
1556 | md5 = "cac497f42e5096ac8df29e38d3f81c3e"; | |
1557 | }; |
|
1557 | }; | |
1558 | meta = { |
|
1558 | meta = { | |
1559 | license = [ pkgs.lib.licenses.mit ]; |
|
1559 | license = [ pkgs.lib.licenses.mit ]; | |
1560 | }; |
|
1560 | }; | |
1561 | }; |
|
1561 | }; | |
1562 | setuptools-scm = super.buildPythonPackage { |
|
1562 | setuptools-scm = super.buildPythonPackage { | |
1563 |
name = "setuptools-scm-1.1 |
|
1563 | name = "setuptools-scm-1.15.0"; | |
1564 | buildInputs = with self; []; |
|
1564 | buildInputs = with self; []; | |
1565 | doCheck = false; |
|
1565 | doCheck = false; | |
1566 | propagatedBuildInputs = with self; []; |
|
1566 | propagatedBuildInputs = with self; []; | |
1567 | src = fetchurl { |
|
1567 | src = fetchurl { | |
1568 |
url = "https://pypi.python.org/packages/ |
|
1568 | url = "https://pypi.python.org/packages/80/b7/31b6ae5fcb188e37f7e31abe75f9be90490a5456a72860fa6e643f8a3cbc/setuptools_scm-1.15.0.tar.gz"; | |
1569 | md5 = "4c5c896ba52e134bbc3507bac6400087"; |
|
1569 | md5 = "b6916c78ed6253d6602444fad4279c5b"; | |
1570 | }; |
|
1570 | }; | |
1571 | meta = { |
|
1571 | meta = { | |
1572 | license = [ pkgs.lib.licenses.mit ]; |
|
1572 | license = [ pkgs.lib.licenses.mit ]; | |
@@ -1625,18 +1625,31 b'' | |||||
1625 | }; |
|
1625 | }; | |
1626 | }; |
|
1626 | }; | |
1627 | supervisor = super.buildPythonPackage { |
|
1627 | supervisor = super.buildPythonPackage { | |
1628 |
name = "supervisor-3.3. |
|
1628 | name = "supervisor-3.3.1"; | |
1629 | buildInputs = with self; []; |
|
1629 | buildInputs = with self; []; | |
1630 | doCheck = false; |
|
1630 | doCheck = false; | |
1631 | propagatedBuildInputs = with self; [meld3]; |
|
1631 | propagatedBuildInputs = with self; [meld3]; | |
1632 | src = fetchurl { |
|
1632 | src = fetchurl { | |
1633 |
url = "https://pypi.python.org/packages/ |
|
1633 | url = "https://pypi.python.org/packages/80/37/964c0d53cbd328796b1aeb7abea4c0f7b0e8c7197ea9b0b9967b7d004def/supervisor-3.3.1.tar.gz"; | |
1634 | md5 = "46bac00378d1eddb616752b990c67416"; |
|
1634 | md5 = "202f760f9bf4930ec06557bac73e5cf2"; | |
1635 | }; |
|
1635 | }; | |
1636 | meta = { |
|
1636 | meta = { | |
1637 | license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ]; |
|
1637 | license = [ { fullName = "BSD-derived (http://www.repoze.org/LICENSE.txt)"; } ]; | |
1638 | }; |
|
1638 | }; | |
1639 | }; |
|
1639 | }; | |
|
1640 | termcolor = super.buildPythonPackage { | |||
|
1641 | name = "termcolor-1.1.0"; | |||
|
1642 | buildInputs = with self; []; | |||
|
1643 | doCheck = false; | |||
|
1644 | propagatedBuildInputs = with self; []; | |||
|
1645 | src = fetchurl { | |||
|
1646 | url = "https://pypi.python.org/packages/8a/48/a76be51647d0eb9f10e2a4511bf3ffb8cc1e6b14e9e4fab46173aa79f981/termcolor-1.1.0.tar.gz"; | |||
|
1647 | md5 = "043e89644f8909d462fbbfa511c768df"; | |||
|
1648 | }; | |||
|
1649 | meta = { | |||
|
1650 | license = [ pkgs.lib.licenses.mit ]; | |||
|
1651 | }; | |||
|
1652 | }; | |||
1640 | traitlets = super.buildPythonPackage { |
|
1653 | traitlets = super.buildPythonPackage { | |
1641 | name = "traitlets-4.3.1"; |
|
1654 | name = "traitlets-4.3.1"; | |
1642 | buildInputs = with self; []; |
|
1655 | buildInputs = with self; []; | |
@@ -1729,13 +1742,13 b'' | |||||
1729 | }; |
|
1742 | }; | |
1730 | }; |
|
1743 | }; | |
1731 | waitress = super.buildPythonPackage { |
|
1744 | waitress = super.buildPythonPackage { | |
1732 |
name = "waitress- |
|
1745 | name = "waitress-1.0.1"; | |
1733 | buildInputs = with self; []; |
|
1746 | buildInputs = with self; []; | |
1734 | doCheck = false; |
|
1747 | doCheck = false; | |
1735 |
propagatedBuildInputs = with self; [ |
|
1748 | propagatedBuildInputs = with self; []; | |
1736 | src = fetchurl { |
|
1749 | src = fetchurl { | |
1737 |
url = "https://pypi.python.org/packages/ |
|
1750 | url = "https://pypi.python.org/packages/78/7d/84d11b96c3f60164dec3bef4a859a03aeae0231aa93f57fbe0d05fa4ff36/waitress-1.0.1.tar.gz"; | |
1738 | md5 = "da3f2e62b3676be5dd630703a68e2a04"; |
|
1751 | md5 = "dda92358a7569669086155923a46e57c"; | |
1739 | }; |
|
1752 | }; | |
1740 | meta = { |
|
1753 | meta = { | |
1741 | license = [ pkgs.lib.licenses.zpt21 ]; |
|
1754 | license = [ pkgs.lib.licenses.zpt21 ]; | |
@@ -1835,30 +1848,5 b'' | |||||
1835 |
|
1848 | |||
1836 | ### Test requirements |
|
1849 | ### Test requirements | |
1837 |
|
1850 | |||
1838 | pytest-sugar = super.buildPythonPackage { |
|
1851 | ||
1839 | name = "pytest-sugar-0.7.1"; |
|
|||
1840 | buildInputs = with self; []; |
|
|||
1841 | doCheck = false; |
|
|||
1842 | propagatedBuildInputs = with self; [pytest termcolor]; |
|
|||
1843 | src = fetchurl { |
|
|||
1844 | url = "https://pypi.python.org/packages/03/97/05d988b4fa870e7373e8ee4582408543b9ca2bd35c3c67b569369c6f9c49/pytest-sugar-0.7.1.tar.gz"; |
|
|||
1845 | md5 = "7400f7c11f3d572b2c2a3b60352d35fe"; |
|
|||
1846 | }; |
|
|||
1847 | meta = { |
|
|||
1848 | license = [ pkgs.lib.licenses.bsdOriginal ]; |
|
|||
1849 | }; |
|
|||
1850 | }; |
|
|||
1851 | termcolor = super.buildPythonPackage { |
|
|||
1852 | name = "termcolor-1.1.0"; |
|
|||
1853 | buildInputs = with self; []; |
|
|||
1854 | doCheck = false; |
|
|||
1855 | propagatedBuildInputs = with self; []; |
|
|||
1856 | src = fetchurl { |
|
|||
1857 | url = "https://pypi.python.org/packages/8a/48/a76be51647d0eb9f10e2a4511bf3ffb8cc1e6b14e9e4fab46173aa79f981/termcolor-1.1.0.tar.gz"; |
|
|||
1858 | md5 = "043e89644f8909d462fbbfa511c768df"; |
|
|||
1859 | }; |
|
|||
1860 | meta = { |
|
|||
1861 | license = [ pkgs.lib.licenses.mit ]; |
|
|||
1862 | }; |
|
|||
1863 | }; |
|
|||
1864 | } |
|
1852 | } |
@@ -1,150 +1,131 b'' | |||||
1 | Babel==1.3 |
|
1 | ## core | |
2 | Beaker==1.7.0 |
|
2 | setuptools==30.1.0 | |
3 | Chameleon==2.24 |
|
3 | setuptools-scm==1.15.0 | |
4 | CProfileV==1.0.6 |
|
|||
5 | FormEncode==1.2.4 |
|
|||
6 | Jinja2==2.7.3 |
|
|||
7 | Mako==1.0.1 |
|
|||
8 | Markdown==2.6.2 |
|
|||
9 | MarkupSafe==0.23 |
|
|||
10 | MySQL-python==1.2.5 |
|
|||
11 | Paste==2.0.2 |
|
|||
12 | PasteDeploy==1.5.2 |
|
|||
13 | PasteScript==1.7.5 |
|
|||
14 | Pygments==2.1.3 |
|
|||
15 | pygments-markdown-lexer==0.1.0.dev39 |
|
|||
16 |
|
||||
17 | # TODO: This version is not available on PyPI |
|
|||
18 | # Pylons==1.0.2.dev20160108 |
|
|||
19 | Pylons==1.0.1 |
|
|||
20 |
|
4 | |||
21 | # TODO: This version is not available, but newer ones are |
|
|||
22 | # Pyro4==4.35 |
|
|||
23 | Pyro4==4.41 |
|
|||
24 |
|
||||
25 | # TODO: This should probably not be in here |
|
|||
26 | # -e hg+https://johbo@code.rhodecode.com/johbo/rhodecode-fork@3a454bd1f17c0b2b2a951cf2b111e0320d7942a9#egg=RhodeCodeEnterprise-dev |
|
|||
27 |
|
||||
28 | Routes==1.13 |
|
|||
29 | SQLAlchemy==0.9.9 |
|
|||
30 | Sphinx==1.2.2 |
|
|||
31 | Tempita==0.5.2 |
|
|||
32 | URLObject==2.4.0 |
|
|||
33 | WebError==0.10.3 |
|
|||
34 |
|
||||
35 | # TODO: This is modified by us, needs a better integration. For now |
|
|||
36 | # using the latest version before. |
|
|||
37 | # WebHelpers==1.3.dev20150807 |
|
|||
38 | WebHelpers==1.3 |
|
|||
39 |
|
||||
40 | WebHelpers2==2.0 |
|
|||
41 | WebOb==1.3.1 |
|
|||
42 | WebTest==1.4.3 |
|
|||
43 | Whoosh==2.7.0 |
|
|||
44 | alembic==0.8.4 |
|
|||
45 | amqplib==1.0.2 |
|
5 | amqplib==1.0.2 | |
46 | anyjson==0.3.3 |
|
6 | anyjson==0.3.3 | |
47 | appenlight-client==0.6.14 |
|
7 | authomatic==0.1.0.post1 | |
48 | authomatic==0.1.0.post1; |
|
8 | Babel==1.3 | |
49 | backport-ipaddress==0.1 |
|
9 | backport-ipaddress==0.1 | |
50 | bottle==0.12.8 |
|
10 | Beaker==1.7.0 | |
51 | bumpversion==0.5.3 |
|
|||
52 | celery==2.2.10 |
|
11 | celery==2.2.10 | |
|
12 | Chameleon==2.24 | |||
53 | channelstream==0.5.2 |
|
13 | channelstream==0.5.2 | |
54 | click==5.1 |
|
14 | click==5.1 | |
55 | colander==1.2 |
|
15 | colander==1.2 | |
56 | configobj==5.0.6 |
|
16 | configobj==5.0.6 | |
57 | cov-core==1.15.0 |
|
|||
58 | coverage==3.7.1 |
|
|||
59 | cssselect==0.9.1 |
|
|||
60 | decorator==3.4.2 |
|
17 | decorator==3.4.2 | |
61 | deform==2.0a2 |
|
18 | deform==2.0a2 | |
62 | docutils==0.12 |
|
19 | docutils==0.12 | |
63 | dogpile.cache==0.6.1 |
|
20 | dogpile.cache==0.6.1 | |
64 | dogpile.core==0.4.1 |
|
21 | dogpile.core==0.4.1 | |
65 | dulwich==0.12.0 |
|
|||
66 | ecdsa==0.11 |
|
22 | ecdsa==0.11 | |
|
23 | FormEncode==1.2.4 | |||
67 | future==0.14.3 |
|
24 | future==0.14.3 | |
68 | futures==3.0.2 |
|
25 | futures==3.0.2 | |
69 | gevent==1.1.1 |
|
|||
70 | gprof2dot==2015.12.1 |
|
|||
71 | greenlet==0.4.9 |
|
|||
72 | gunicorn==19.6.0 |
|
|||
73 |
|
||||
74 | # TODO: Needs subvertpy and blows up without Subversion headers, |
|
|||
75 | # actually we should not need this for Enterprise at all. |
|
|||
76 | # hgsubversion==1.8.2 |
|
|||
77 |
|
||||
78 | gnureadline==6.3.3 |
|
26 | gnureadline==6.3.3 | |
79 | infrae.cache==1.0.1 |
|
27 | infrae.cache==1.0.1 | |
80 | invoke==0.13.0 |
|
|||
81 | ipdb==0.10.1 |
|
|||
82 | ipython==5.1.0 |
|
|||
83 | iso8601==0.1.11 |
|
28 | iso8601==0.1.11 | |
84 | itsdangerous==0.24 |
|
29 | itsdangerous==0.24 | |
|
30 | Jinja2==2.7.3 | |||
85 | kombu==1.5.1 |
|
31 | kombu==1.5.1 | |
86 | lxml==3.4.4 |
|
32 | Mako==1.0.6 | |
|
33 | Markdown==2.6.7 | |||
|
34 | MarkupSafe==0.23 | |||
87 | meld3==1.0.2 |
|
35 | meld3==1.0.2 | |
88 | mock==1.0.1 |
|
36 | msgpack-python==0.4.8 | |
89 | msgpack-python==0.4.6 |
|
37 | MySQL-python==1.2.5 | |
90 | nose==1.3.6 |
|
38 | nose==1.3.6 | |
91 | objgraph==2.0.0 |
|
39 | objgraph==2.0.0 | |
92 | packaging==15.2 |
|
40 | packaging==15.2 | |
93 | paramiko==1.15.1 |
|
41 | paramiko==1.15.1 | |
|
42 | Paste==2.0.3 | |||
|
43 | PasteDeploy==1.5.2 | |||
|
44 | PasteScript==1.7.5 | |||
94 | psutil==4.3.1 |
|
45 | psutil==4.3.1 | |
95 | psycopg2==2.6.1 |
|
46 | psycopg2==2.6.1 | |
96 | py==1.4.29 |
|
|||
97 | py-bcrypt==0.4 |
|
47 | py-bcrypt==0.4 | |
98 | py-gfm==0.1.3 |
|
|||
99 | pycrypto==2.6.1 |
|
48 | pycrypto==2.6.1 | |
100 | pycurl==7.19.5 |
|
49 | pycurl==7.19.5 | |
101 | pyflakes==0.8.1 |
|
50 | pyflakes==0.8.1 | |
|
51 | pygments-markdown-lexer==0.1.0.dev39 | |||
|
52 | Pygments==2.2.0 | |||
102 | pyparsing==1.5.7 |
|
53 | pyparsing==1.5.7 | |
103 | pyramid==1.6.1 |
|
|||
104 | pyramid-beaker==0.8 |
|
54 | pyramid-beaker==0.8 | |
105 | pyramid-debugtoolbar==2.4.2 |
|
55 | pyramid-debugtoolbar==2.4.2 | |
106 | pyramid-jinja2==2.5 |
|
56 | pyramid-jinja2==2.5 | |
107 | pyramid-mako==1.0.2 |
|
57 | pyramid-mako==1.0.2 | |
|
58 | pyramid==1.6.1 | |||
108 | pysqlite==2.6.3 |
|
59 | pysqlite==2.6.3 | |
109 | pytest==2.8.5 |
|
|||
110 | pytest-runner==2.7.1 |
|
|||
111 | pytest-catchlog==1.2.2 |
|
|||
112 | pytest-cov==1.8.1 |
|
|||
113 | pytest-profiling==1.0.1 |
|
|||
114 | pytest-timeout==0.4 |
|
|||
115 | python-dateutil==1.5 |
|
60 | python-dateutil==1.5 | |
116 | python-ldap==2.4.19 |
|
61 | python-ldap==2.4.19 | |
117 | python-memcached==1.57 |
|
62 | python-memcached==1.57 | |
118 | python-pam==1.8.2 |
|
63 | python-pam==1.8.2 | |
119 | pytz==2015.4 |
|
64 | pytz==2015.4 | |
120 | pyzmq==14.6.0 |
|
65 | pyzmq==14.6.0 | |
121 |
|
||||
122 | # TODO: This is not available in public |
|
|||
123 | # rc-testdata==0.2.0 |
|
|||
124 |
|
||||
125 | https://code.rhodecode.com/rhodecode-tools-ce/archive/v0.10.2.zip#md5=d2af3985a1a32a678944d4d48870cb04 |
|
|||
126 |
|
||||
127 |
|
||||
128 | recaptcha-client==1.0.6 |
|
66 | recaptcha-client==1.0.6 | |
129 | repoze.lru==0.6 |
|
67 | repoze.lru==0.6 | |
130 | requests==2.9.1 |
|
68 | requests==2.9.1 | |
131 | serpent==1.12 |
|
69 | Routes==1.13 | |
132 | setproctitle==1.1.8 |
|
70 | setproctitle==1.1.8 | |
133 | setuptools==20.8.1 |
|
|||
134 | setuptools-scm==1.11.0 |
|
|||
135 | simplejson==3.7.2 |
|
71 | simplejson==3.7.2 | |
136 | six==1.9.0 |
|
72 | six==1.9.0 | |
|
73 | Sphinx==1.2.2 | |||
|
74 | SQLAlchemy==0.9.9 | |||
137 | subprocess32==3.2.6 |
|
75 | subprocess32==3.2.6 | |
138 |
supervisor==3.3. |
|
76 | supervisor==3.3.1 | |
139 | transifex-client==0.10 |
|
77 | Tempita==0.5.2 | |
140 | translationstring==1.3 |
|
78 | translationstring==1.3 | |
141 | trollius==1.0.4 |
|
79 | trollius==1.0.4 | |
142 | uWSGI==2.0.11.2 |
|
|||
143 | urllib3==1.16 |
|
80 | urllib3==1.16 | |
|
81 | URLObject==2.4.0 | |||
144 | venusian==1.0 |
|
82 | venusian==1.0 | |
145 | waitress==0.8.9 |
|
83 | WebError==0.10.3 | |
|
84 | WebHelpers2==2.0 | |||
|
85 | WebHelpers==1.3 | |||
|
86 | WebOb==1.3.1 | |||
|
87 | Whoosh==2.7.4 | |||
146 | wsgiref==0.1.2 |
|
88 | wsgiref==0.1.2 | |
147 | zope.cachedescriptors==4.0.0 |
|
89 | zope.cachedescriptors==4.0.0 | |
148 | zope.deprecation==4.1.2 |
|
90 | zope.deprecation==4.1.2 | |
149 | zope.event==4.0.3 |
|
91 | zope.event==4.0.3 | |
150 | zope.interface==4.1.3 |
|
92 | zope.interface==4.1.3 | |
|
93 | ||||
|
94 | ## customized/patched libs | |||
|
95 | # our patched version of Pylons==1.0.2 | |||
|
96 | https://code.rhodecode.com/upstream/pylons/archive/707354ee4261b9c10450404fc9852ccea4fd667d.tar.gz?md5=f26633726fa2cd3a340316ee6a5d218f#egg=Pylons==1.0.2.rhodecode-patch-1 | |||
|
97 | # not released py-gfm==0.1.3 | |||
|
98 | https://code.rhodecode.com/upstream/py-gfm/archive/0d66a19bc16e3d49de273c0f797d4e4781e8c0f2.tar.gz?md5=0d0d5385bfb629eea636a80b9c2bfd16#egg=py-gfm==0.1.3.rhodecode-upstream1 | |||
|
99 | ||||
|
100 | ||||
|
101 | ## cli tools | |||
|
102 | alembic==0.8.4 | |||
|
103 | invoke==0.13.0 | |||
|
104 | bumpversion==0.5.3 | |||
|
105 | transifex-client==0.10 | |||
|
106 | ||||
|
107 | ## http servers | |||
|
108 | gevent==1.1.2 | |||
|
109 | greenlet==0.4.10 | |||
|
110 | gunicorn==19.6.0 | |||
|
111 | waitress==1.0.1 | |||
|
112 | uWSGI==2.0.11.2 | |||
|
113 | ||||
|
114 | ## debug | |||
|
115 | ipdb==0.10.1 | |||
|
116 | ipython==5.1.0 | |||
|
117 | CProfileV==1.0.6 | |||
|
118 | bottle==0.12.8 | |||
|
119 | ||||
|
120 | ## rhodecode-tools, special case | |||
|
121 | https://code.rhodecode.com/rhodecode-tools-ce/archive/v0.11.0.tar.gz?md5=e5fd0a8363af08a0ced71b50ca9cce15#egg=rhodecode-tools==0.11.0 | |||
|
122 | ||||
|
123 | ## appenlight | |||
|
124 | appenlight-client==0.6.14 | |||
|
125 | ||||
|
126 | # Pyro/Deprecated TODO(Marcink): remove in 4.7 release. | |||
|
127 | Pyro4==4.41 | |||
|
128 | serpent==1.15 | |||
|
129 | ||||
|
130 | ## test related requirements | |||
|
131 | -r requirements_test.txt |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -51,11 +51,11 b' PYRAMID_SETTINGS = {}' | |||||
51 | EXTENSIONS = {} |
|
51 | EXTENSIONS = {} | |
52 |
|
52 | |||
53 | __version__ = ('.'.join((str(each) for each in VERSION[:3]))) |
|
53 | __version__ = ('.'.join((str(each) for each in VERSION[:3]))) | |
54 |
__dbversion__ = 6 |
|
54 | __dbversion__ = 64 # defines current db version for migrations | |
55 | __platform__ = platform.system() |
|
55 | __platform__ = platform.system() | |
56 | __license__ = 'AGPLv3, and Commercial License' |
|
56 | __license__ = 'AGPLv3, and Commercial License' | |
57 | __author__ = 'RhodeCode GmbH' |
|
57 | __author__ = 'RhodeCode GmbH' | |
58 | __url__ = 'http://rhodecode.com' |
|
58 | __url__ = 'https://code.rhodecode.com' | |
59 |
|
59 | |||
60 | is_windows = __platform__ in ['Windows'] |
|
60 | is_windows = __platform__ in ['Windows'] | |
61 | is_unix = not is_windows |
|
61 | is_unix = not is_windows |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -39,5 +39,19 b' def includeme(config):' | |||||
39 | name='admin_settings_vcs_svn_generate_cfg', |
|
39 | name='admin_settings_vcs_svn_generate_cfg', | |
40 | pattern=ADMIN_PREFIX + '/settings/vcs/svn_generate_cfg') |
|
40 | pattern=ADMIN_PREFIX + '/settings/vcs/svn_generate_cfg') | |
41 |
|
41 | |||
|
42 | config.add_route( | |||
|
43 | name='admin_settings_system', | |||
|
44 | pattern=ADMIN_PREFIX + '/settings/system') | |||
|
45 | config.add_route( | |||
|
46 | name='admin_settings_system_update', | |||
|
47 | pattern=ADMIN_PREFIX + '/settings/system/updates') | |||
|
48 | ||||
|
49 | config.add_route( | |||
|
50 | name='admin_settings_sessions', | |||
|
51 | pattern=ADMIN_PREFIX + '/settings/sessions') | |||
|
52 | config.add_route( | |||
|
53 | name='admin_settings_sessions_cleanup', | |||
|
54 | pattern=ADMIN_PREFIX + '/settings/sessions/cleanup') | |||
|
55 | ||||
42 | # Scan module for configuration decorators. |
|
56 | # Scan module for configuration decorators. | |
43 | config.scan() |
|
57 | config.scan() |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -66,6 +66,15 b' class NavEntry(object):' | |||||
66 | else: |
|
66 | else: | |
67 | return url(self.view_name) |
|
67 | return url(self.view_name) | |
68 |
|
68 | |||
|
69 | def get_localized_name(self, request): | |||
|
70 | if hasattr(request, 'translate'): | |||
|
71 | return request.translate(self.name) | |||
|
72 | else: | |||
|
73 | # TODO(marcink): Remove this after migrating to pyramid | |||
|
74 | from pyramid.threadlocal import get_current_request | |||
|
75 | pyramid_request = get_current_request() | |||
|
76 | return pyramid_request.translate(self.name) | |||
|
77 | ||||
69 |
|
78 | |||
70 | @implementer(IAdminNavigationRegistry) |
|
79 | @implementer(IAdminNavigationRegistry) | |
71 | class NavigationRegistry(object): |
|
80 | class NavigationRegistry(object): | |
@@ -80,18 +89,22 b' class NavigationRegistry(object):' | |||||
80 | NavEntry('email', _('Email'), 'admin_settings_email'), |
|
89 | NavEntry('email', _('Email'), 'admin_settings_email'), | |
81 | NavEntry('hooks', _('Hooks'), 'admin_settings_hooks'), |
|
90 | NavEntry('hooks', _('Hooks'), 'admin_settings_hooks'), | |
82 | NavEntry('search', _('Full Text Search'), 'admin_settings_search'), |
|
91 | NavEntry('search', _('Full Text Search'), 'admin_settings_search'), | |
|
92 | ||||
83 | NavEntry('integrations', _('Integrations'), |
|
93 | NavEntry('integrations', _('Integrations'), | |
84 | 'global_integrations_home', pyramid=True), |
|
94 | 'global_integrations_home', pyramid=True), | |
85 |
NavEntry('system', _('System Info'), |
|
95 | NavEntry('system', _('System Info'), | |
|
96 | 'admin_settings_system', pyramid=True), | |||
|
97 | NavEntry('sessions', _('User Sessions'), | |||
|
98 | 'admin_settings_sessions', pyramid=True), | |||
86 | NavEntry('open_source', _('Open Source Licenses'), |
|
99 | NavEntry('open_source', _('Open Source Licenses'), | |
87 | 'admin_settings_open_source', pyramid=True), |
|
100 | 'admin_settings_open_source', pyramid=True), | |
|
101 | ||||
88 | # TODO: marcink: we disable supervisor now until the supervisor stats |
|
102 | # TODO: marcink: we disable supervisor now until the supervisor stats | |
89 | # page is fixed in the nix configuration |
|
103 | # page is fixed in the nix configuration | |
90 | # NavEntry('supervisor', _('Supervisor'), 'admin_settings_supervisor'), |
|
104 | # NavEntry('supervisor', _('Supervisor'), 'admin_settings_supervisor'), | |
91 | ] |
|
105 | ] | |
92 |
|
106 | |||
93 | _labs_entry = NavEntry('labs', _('Labs'), |
|
107 | _labs_entry = NavEntry('labs', _('Labs'), 'admin_settings_labs') | |
94 | 'admin_settings_labs') |
|
|||
95 |
|
108 | |||
96 | def __init__(self, labs_active=False): |
|
109 | def __init__(self, labs_active=False): | |
97 | self._registered_entries = collections.OrderedDict([ |
|
110 | self._registered_entries = collections.OrderedDict([ | |
@@ -105,7 +118,8 b' class NavigationRegistry(object):' | |||||
105 | self._registered_entries[entry.key] = entry |
|
118 | self._registered_entries[entry.key] = entry | |
106 |
|
119 | |||
107 | def get_navlist(self, request): |
|
120 | def get_navlist(self, request): | |
108 |
navlist = [NavListEntry(i.key, i. |
|
121 | navlist = [NavListEntry(i.key, i.get_localized_name(request), | |
|
122 | i.generate_url(request)) | |||
109 | for i in self._registered_entries.values()] |
|
123 | for i in self._registered_entries.values()] | |
110 | return navlist |
|
124 | return navlist | |
111 |
|
125 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -132,7 +132,7 b' def exception_view(exc, request):' | |||||
132 | log.debug('json-rpc error rpc_id:%s "%s"', rpc_id, fault_message) |
|
132 | log.debug('json-rpc error rpc_id:%s "%s"', rpc_id, fault_message) | |
133 | elif isinstance(exc, JSONRPCValidationError): |
|
133 | elif isinstance(exc, JSONRPCValidationError): | |
134 | colander_exc = exc.colander_exception |
|
134 | colander_exc = exc.colander_exception | |
135 | #TODO: think maybe of nicer way to serialize errors ? |
|
135 | # TODO(marcink): think maybe of nicer way to serialize errors ? | |
136 | fault_message = colander_exc.asdict() |
|
136 | fault_message = colander_exc.asdict() | |
137 | log.debug('json-rpc error rpc_id:%s "%s"', rpc_id, fault_message) |
|
137 | log.debug('json-rpc error rpc_id:%s "%s"', rpc_id, fault_message) | |
138 | elif isinstance(exc, JSONRPCForbidden): |
|
138 | elif isinstance(exc, JSONRPCForbidden): | |
@@ -240,7 +240,7 b' def request_view(request):' | |||||
240 | message=('Missing non optional `%s` arg in JSON DATA' % arg) |
|
240 | message=('Missing non optional `%s` arg in JSON DATA' % arg) | |
241 | ) |
|
241 | ) | |
242 |
|
242 | |||
243 | # sanitze extra passed arguments |
|
243 | # sanitize extra passed arguments | |
244 | for k in request.rpc_params.keys()[:]: |
|
244 | for k in request.rpc_params.keys()[:]: | |
245 | if k not in func_kwargs: |
|
245 | if k not in func_kwargs: | |
246 | del request.rpc_params[k] |
|
246 | del request.rpc_params[k] | |
@@ -256,7 +256,7 b' def request_view(request):' | |||||
256 | except JSONRPCBaseError: |
|
256 | except JSONRPCBaseError: | |
257 | raise |
|
257 | raise | |
258 | except Exception: |
|
258 | except Exception: | |
259 | log.exception('Unhandled exception occured on api call: %s', func) |
|
259 | log.exception('Unhandled exception occurred on api call: %s', func) | |
260 | return jsonrpc_error(request, retid=request.rpc_id, |
|
260 | return jsonrpc_error(request, retid=request.rpc_id, | |
261 | message='Internal server error') |
|
261 | message='Internal server error') | |
262 |
|
262 | |||
@@ -269,9 +269,10 b' def setup_request(request):' | |||||
269 | We need to raise JSONRPCError here if we want to return some errors back to |
|
269 | We need to raise JSONRPCError here if we want to return some errors back to | |
270 | user. |
|
270 | user. | |
271 | """ |
|
271 | """ | |
|
272 | ||||
272 | log.debug('Executing setup request: %r', request) |
|
273 | log.debug('Executing setup request: %r', request) | |
273 | request.rpc_ip_addr = get_ip_addr(request.environ) |
|
274 | request.rpc_ip_addr = get_ip_addr(request.environ) | |
274 |
# TODO |
|
275 | # TODO(marcink): deprecate GET at some point | |
275 | if request.method not in ['POST', 'GET']: |
|
276 | if request.method not in ['POST', 'GET']: | |
276 | log.debug('unsupported request method "%s"', request.method) |
|
277 | log.debug('unsupported request method "%s"', request.method) | |
277 | raise JSONRPCError( |
|
278 | raise JSONRPCError( | |
@@ -308,6 +309,8 b' def setup_request(request):' | |||||
308 | if not api_key: |
|
309 | if not api_key: | |
309 | raise KeyError('api_key or auth_token') |
|
310 | raise KeyError('api_key or auth_token') | |
310 |
|
311 | |||
|
312 | # TODO(marcink): support passing in token in request header | |||
|
313 | ||||
311 | request.rpc_api_key = api_key |
|
314 | request.rpc_api_key = api_key | |
312 | request.rpc_id = json_body['id'] |
|
315 | request.rpc_id = json_body['id'] | |
313 | request.rpc_method = json_body['method'] |
|
316 | request.rpc_method = json_body['method'] | |
@@ -485,8 +488,7 b' def includeme(config):' | |||||
485 | config.registry.jsonrpc_methods = OrderedDict() |
|
488 | config.registry.jsonrpc_methods = OrderedDict() | |
486 |
|
489 | |||
487 | # match filter by given method only |
|
490 | # match filter by given method only | |
488 | config.add_view_predicate( |
|
491 | config.add_view_predicate('jsonrpc_method', MethodPredicate) | |
489 | 'jsonrpc_method', MethodPredicate) |
|
|||
490 |
|
492 | |||
491 | config.add_renderer(DEFAULT_RENDERER, ExtJsonRenderer( |
|
493 | config.add_renderer(DEFAULT_RENDERER, ExtJsonRenderer( | |
492 | serializer=json.dumps, indent=4)) |
|
494 | serializer=json.dumps, indent=4)) |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -20,7 +20,7 b'' | |||||
20 |
|
20 | |||
21 | import pytest |
|
21 | import pytest | |
22 |
|
22 | |||
23 |
from rhodecode.model.comment import |
|
23 | from rhodecode.model.comment import CommentsModel | |
24 | from rhodecode.model.db import UserLog |
|
24 | from rhodecode.model.db import UserLog | |
25 | from rhodecode.model.pull_request import PullRequestModel |
|
25 | from rhodecode.model.pull_request import PullRequestModel | |
26 | from rhodecode.tests import TEST_USER_ADMIN_LOGIN |
|
26 | from rhodecode.tests import TEST_USER_ADMIN_LOGIN | |
@@ -52,13 +52,13 b' class TestCommentPullRequest(object):' | |||||
52 | response = api_call(self.app, params) |
|
52 | response = api_call(self.app, params) | |
53 | pull_request = PullRequestModel().get(pull_request.pull_request_id) |
|
53 | pull_request = PullRequestModel().get(pull_request.pull_request_id) | |
54 |
|
54 | |||
55 |
comments = |
|
55 | comments = CommentsModel().get_comments( | |
56 | pull_request.target_repo.repo_id, pull_request=pull_request) |
|
56 | pull_request.target_repo.repo_id, pull_request=pull_request) | |
57 |
|
57 | |||
58 | expected = { |
|
58 | expected = { | |
59 | 'pull_request_id': pull_request.pull_request_id, |
|
59 | 'pull_request_id': pull_request.pull_request_id, | |
60 | 'comment_id': comments[-1].comment_id, |
|
60 | 'comment_id': comments[-1].comment_id, | |
61 | 'status': None |
|
61 | 'status': {'given': None, 'was_changed': None} | |
62 | } |
|
62 | } | |
63 | assert_ok(id_, expected, response.body) |
|
63 | assert_ok(id_, expected, response.body) | |
64 |
|
64 | |||
@@ -83,12 +83,61 b' class TestCommentPullRequest(object):' | |||||
83 | response = api_call(self.app, params) |
|
83 | response = api_call(self.app, params) | |
84 | pull_request = PullRequestModel().get(pull_request_id) |
|
84 | pull_request = PullRequestModel().get(pull_request_id) | |
85 |
|
85 | |||
86 |
comments = |
|
86 | comments = CommentsModel().get_comments( | |
87 | pull_request.target_repo.repo_id, pull_request=pull_request) |
|
87 | pull_request.target_repo.repo_id, pull_request=pull_request) | |
88 | expected = { |
|
88 | expected = { | |
89 | 'pull_request_id': pull_request.pull_request_id, |
|
89 | 'pull_request_id': pull_request.pull_request_id, | |
90 | 'comment_id': comments[-1].comment_id, |
|
90 | 'comment_id': comments[-1].comment_id, | |
91 | 'status': 'rejected' |
|
91 | 'status': {'given': 'rejected', 'was_changed': True} | |
|
92 | } | |||
|
93 | assert_ok(id_, expected, response.body) | |||
|
94 | ||||
|
95 | @pytest.mark.backends("git", "hg") | |||
|
96 | def test_api_comment_pull_request_change_status_with_specific_commit_id( | |||
|
97 | self, pr_util, no_notifications): | |||
|
98 | pull_request = pr_util.create_pull_request() | |||
|
99 | pull_request_id = pull_request.pull_request_id | |||
|
100 | latest_commit_id = 'test_commit' | |||
|
101 | # inject additional revision, to fail test the status change on | |||
|
102 | # non-latest commit | |||
|
103 | pull_request.revisions = pull_request.revisions + ['test_commit'] | |||
|
104 | ||||
|
105 | id_, params = build_data( | |||
|
106 | self.apikey, 'comment_pull_request', | |||
|
107 | repoid=pull_request.target_repo.repo_name, | |||
|
108 | pullrequestid=pull_request.pull_request_id, | |||
|
109 | status='approved', commit_id=latest_commit_id) | |||
|
110 | response = api_call(self.app, params) | |||
|
111 | pull_request = PullRequestModel().get(pull_request_id) | |||
|
112 | ||||
|
113 | expected = { | |||
|
114 | 'pull_request_id': pull_request.pull_request_id, | |||
|
115 | 'comment_id': None, | |||
|
116 | 'status': {'given': 'approved', 'was_changed': False} | |||
|
117 | } | |||
|
118 | assert_ok(id_, expected, response.body) | |||
|
119 | ||||
|
120 | @pytest.mark.backends("git", "hg") | |||
|
121 | def test_api_comment_pull_request_change_status_with_specific_commit_id( | |||
|
122 | self, pr_util, no_notifications): | |||
|
123 | pull_request = pr_util.create_pull_request() | |||
|
124 | pull_request_id = pull_request.pull_request_id | |||
|
125 | latest_commit_id = pull_request.revisions[0] | |||
|
126 | ||||
|
127 | id_, params = build_data( | |||
|
128 | self.apikey, 'comment_pull_request', | |||
|
129 | repoid=pull_request.target_repo.repo_name, | |||
|
130 | pullrequestid=pull_request.pull_request_id, | |||
|
131 | status='approved', commit_id=latest_commit_id) | |||
|
132 | response = api_call(self.app, params) | |||
|
133 | pull_request = PullRequestModel().get(pull_request_id) | |||
|
134 | ||||
|
135 | comments = CommentsModel().get_comments( | |||
|
136 | pull_request.target_repo.repo_id, pull_request=pull_request) | |||
|
137 | expected = { | |||
|
138 | 'pull_request_id': pull_request.pull_request_id, | |||
|
139 | 'comment_id': comments[-1].comment_id, | |||
|
140 | 'status': {'given': 'approved', 'was_changed': True} | |||
92 | } |
|
141 | } | |
93 | assert_ok(id_, expected, response.body) |
|
142 | assert_ok(id_, expected, response.body) | |
94 |
|
143 | |||
@@ -103,7 +152,7 b' class TestCommentPullRequest(object):' | |||||
103 | pullrequestid=pull_request_id) |
|
152 | pullrequestid=pull_request_id) | |
104 | response = api_call(self.app, params) |
|
153 | response = api_call(self.app, params) | |
105 |
|
154 | |||
106 | expected = 'message and status parameter missing' |
|
155 | expected = 'Both message and status parameters are missing. At least one is required.' | |
107 | assert_error(id_, expected, given=response.body) |
|
156 | assert_error(id_, expected, given=response.body) | |
108 |
|
157 | |||
109 | @pytest.mark.backends("git", "hg") |
|
158 | @pytest.mark.backends("git", "hg") | |
@@ -118,7 +167,7 b' class TestCommentPullRequest(object):' | |||||
118 | status='42') |
|
167 | status='42') | |
119 | response = api_call(self.app, params) |
|
168 | response = api_call(self.app, params) | |
120 |
|
169 | |||
121 |
expected = ' |
|
170 | expected = 'Unknown comment status: `42`' | |
122 | assert_error(id_, expected, given=response.body) |
|
171 | assert_error(id_, expected, given=response.body) | |
123 |
|
172 | |||
124 | @pytest.mark.backends("git", "hg") |
|
173 | @pytest.mark.backends("git", "hg") | |
@@ -144,3 +193,17 b' class TestCommentPullRequest(object):' | |||||
144 |
|
193 | |||
145 | expected = 'userid is not the same as your user' |
|
194 | expected = 'userid is not the same as your user' | |
146 | assert_error(id_, expected, given=response.body) |
|
195 | assert_error(id_, expected, given=response.body) | |
|
196 | ||||
|
197 | @pytest.mark.backends("git", "hg") | |||
|
198 | def test_api_comment_pull_request_wrong_commit_id_error(self, pr_util): | |||
|
199 | pull_request = pr_util.create_pull_request() | |||
|
200 | id_, params = build_data( | |||
|
201 | self.apikey_regular, 'comment_pull_request', | |||
|
202 | repoid=pull_request.target_repo.repo_name, | |||
|
203 | status='approved', | |||
|
204 | pullrequestid=pull_request.pull_request_id, | |||
|
205 | commit_id='XXX') | |||
|
206 | response = api_call(self.app, params) | |||
|
207 | ||||
|
208 | expected = 'Invalid commit_id `XXX` for this pull request.' | |||
|
209 | assert_error(id_, expected, given=response.body) |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -22,7 +22,8 b'' | |||||
22 | import pytest |
|
22 | import pytest | |
23 |
|
23 | |||
24 | from rhodecode.model.repo import RepoModel |
|
24 | from rhodecode.model.repo import RepoModel | |
25 |
from rhodecode.api.tests.utils import |
|
25 | from rhodecode.api.tests.utils import ( | |
|
26 | build_data, api_call, assert_ok, assert_error, jsonify) | |||
26 | from rhodecode.model.db import User |
|
27 | from rhodecode.model.db import User | |
27 |
|
28 | |||
28 |
|
29 | |||
@@ -40,6 +41,76 b' class TestGetRepos(object):' | |||||
40 | expected = ret |
|
41 | expected = ret | |
41 | assert_ok(id_, expected, given=response.body) |
|
42 | assert_ok(id_, expected, given=response.body) | |
42 |
|
43 | |||
|
44 | def test_api_get_repos_only_toplevel(self, user_util): | |||
|
45 | repo_group = user_util.create_repo_group(auto_cleanup=True) | |||
|
46 | user_util.create_repo(parent=repo_group) | |||
|
47 | ||||
|
48 | id_, params = build_data(self.apikey, 'get_repos', traverse=0) | |||
|
49 | response = api_call(self.app, params) | |||
|
50 | ||||
|
51 | result = [] | |||
|
52 | for repo in RepoModel().get_repos_for_root(root=None): | |||
|
53 | result.append(repo.get_api_data(include_secrets=True)) | |||
|
54 | expected = jsonify(result) | |||
|
55 | ||||
|
56 | assert_ok(id_, expected, given=response.body) | |||
|
57 | ||||
|
58 | def test_api_get_repos_with_wrong_root(self): | |||
|
59 | id_, params = build_data(self.apikey, 'get_repos', root='abracadabra') | |||
|
60 | response = api_call(self.app, params) | |||
|
61 | ||||
|
62 | expected = 'Root repository group `abracadabra` does not exist' | |||
|
63 | assert_error(id_, expected, given=response.body) | |||
|
64 | ||||
|
65 | def test_api_get_repos_with_root(self, user_util): | |||
|
66 | repo_group = user_util.create_repo_group(auto_cleanup=True) | |||
|
67 | repo_group_name = repo_group.group_name | |||
|
68 | ||||
|
69 | user_util.create_repo(parent=repo_group) | |||
|
70 | user_util.create_repo(parent=repo_group) | |||
|
71 | ||||
|
72 | # nested, should not show up | |||
|
73 | user_util._test_name = '{}/'.format(repo_group_name) | |||
|
74 | sub_repo_group = user_util.create_repo_group(auto_cleanup=True) | |||
|
75 | user_util.create_repo(parent=sub_repo_group) | |||
|
76 | ||||
|
77 | id_, params = build_data(self.apikey, 'get_repos', | |||
|
78 | root=repo_group_name, traverse=0) | |||
|
79 | response = api_call(self.app, params) | |||
|
80 | ||||
|
81 | result = [] | |||
|
82 | for repo in RepoModel().get_repos_for_root(repo_group): | |||
|
83 | result.append(repo.get_api_data(include_secrets=True)) | |||
|
84 | ||||
|
85 | assert len(result) == 2 | |||
|
86 | expected = jsonify(result) | |||
|
87 | assert_ok(id_, expected, given=response.body) | |||
|
88 | ||||
|
89 | def test_api_get_repos_with_root_and_traverse(self, user_util): | |||
|
90 | repo_group = user_util.create_repo_group(auto_cleanup=True) | |||
|
91 | repo_group_name = repo_group.group_name | |||
|
92 | ||||
|
93 | user_util.create_repo(parent=repo_group) | |||
|
94 | user_util.create_repo(parent=repo_group) | |||
|
95 | ||||
|
96 | # nested, should not show up | |||
|
97 | user_util._test_name = '{}/'.format(repo_group_name) | |||
|
98 | sub_repo_group = user_util.create_repo_group(auto_cleanup=True) | |||
|
99 | user_util.create_repo(parent=sub_repo_group) | |||
|
100 | ||||
|
101 | id_, params = build_data(self.apikey, 'get_repos', | |||
|
102 | root=repo_group_name, traverse=1) | |||
|
103 | response = api_call(self.app, params) | |||
|
104 | ||||
|
105 | result = [] | |||
|
106 | for repo in RepoModel().get_repos_for_root( | |||
|
107 | repo_group_name, traverse=True): | |||
|
108 | result.append(repo.get_api_data(include_secrets=True)) | |||
|
109 | ||||
|
110 | assert len(result) == 3 | |||
|
111 | expected = jsonify(result) | |||
|
112 | assert_ok(id_, expected, given=response.body) | |||
|
113 | ||||
43 | def test_api_get_repos_non_admin(self): |
|
114 | def test_api_get_repos_non_admin(self): | |
44 | id_, params = build_data(self.apikey_regular, 'get_repos') |
|
115 | id_, params = build_data(self.apikey_regular, 'get_repos') | |
45 | response = api_call(self.app, params) |
|
116 | response = api_call(self.app, params) |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -20,18 +20,17 b'' | |||||
20 |
|
20 | |||
21 | import pytest |
|
21 | import pytest | |
22 |
|
22 | |||
23 | from rhodecode.model.db import UserLog |
|
23 | from rhodecode.model.db import UserLog, PullRequest | |
24 | from rhodecode.model.meta import Session |
|
24 | from rhodecode.model.meta import Session | |
25 | from rhodecode.model.pull_request import PullRequestModel |
|
|||
26 | from rhodecode.tests import TEST_USER_ADMIN_LOGIN |
|
25 | from rhodecode.tests import TEST_USER_ADMIN_LOGIN | |
27 | from rhodecode.api.tests.utils import ( |
|
26 | from rhodecode.api.tests.utils import ( | |
28 | build_data, api_call, assert_error) |
|
27 | build_data, api_call, assert_error, assert_ok) | |
29 |
|
28 | |||
30 |
|
29 | |||
31 | @pytest.mark.usefixtures("testuser_api", "app") |
|
30 | @pytest.mark.usefixtures("testuser_api", "app") | |
32 | class TestMergePullRequest(object): |
|
31 | class TestMergePullRequest(object): | |
33 | @pytest.mark.backends("git", "hg") |
|
32 | @pytest.mark.backends("git", "hg") | |
34 | def test_api_merge_pull_request(self, pr_util, no_notifications): |
|
33 | def test_api_merge_pull_request_merge_failed(self, pr_util, no_notifications): | |
35 | pull_request = pr_util.create_pull_request(mergeable=True) |
|
34 | pull_request = pr_util.create_pull_request(mergeable=True) | |
36 | author = pull_request.user_id |
|
35 | author = pull_request.user_id | |
37 | repo = pull_request.target_repo.repo_id |
|
36 | repo = pull_request.target_repo.repo_id | |
@@ -51,6 +50,41 b' class TestMergePullRequest(object):' | |||||
51 | # it. |
|
50 | # it. | |
52 | Session().add(pull_request) |
|
51 | Session().add(pull_request) | |
53 |
|
52 | |||
|
53 | expected = 'merge not possible for following reasons: ' \ | |||
|
54 | 'Pull request reviewer approval is pending.' | |||
|
55 | assert_error(id_, expected, given=response.body) | |||
|
56 | ||||
|
57 | @pytest.mark.backends("git", "hg") | |||
|
58 | def test_api_merge_pull_request(self, pr_util, no_notifications): | |||
|
59 | pull_request = pr_util.create_pull_request(mergeable=True, approved=True) | |||
|
60 | author = pull_request.user_id | |||
|
61 | repo = pull_request.target_repo.repo_id | |||
|
62 | pull_request_id = pull_request.pull_request_id | |||
|
63 | pull_request_repo = pull_request.target_repo.repo_name | |||
|
64 | ||||
|
65 | id_, params = build_data( | |||
|
66 | self.apikey, 'comment_pull_request', | |||
|
67 | repoid=pull_request_repo, | |||
|
68 | pullrequestid=pull_request_id, | |||
|
69 | status='approved') | |||
|
70 | ||||
|
71 | response = api_call(self.app, params) | |||
|
72 | expected = { | |||
|
73 | 'comment_id': response.json.get('result', {}).get('comment_id'), | |||
|
74 | 'pull_request_id': pull_request_id, | |||
|
75 | 'status': {'given': 'approved', 'was_changed': True} | |||
|
76 | } | |||
|
77 | assert_ok(id_, expected, given=response.body) | |||
|
78 | ||||
|
79 | id_, params = build_data( | |||
|
80 | self.apikey, 'merge_pull_request', | |||
|
81 | repoid=pull_request_repo, | |||
|
82 | pullrequestid=pull_request_id) | |||
|
83 | ||||
|
84 | response = api_call(self.app, params) | |||
|
85 | ||||
|
86 | pull_request = PullRequest.get(pull_request_id) | |||
|
87 | ||||
54 | expected = { |
|
88 | expected = { | |
55 | 'executed': True, |
|
89 | 'executed': True, | |
56 | 'failure_reason': 0, |
|
90 | 'failure_reason': 0, | |
@@ -59,8 +93,7 b' class TestMergePullRequest(object):' | |||||
59 | 'merge_ref': pull_request.shadow_merge_ref._asdict() |
|
93 | 'merge_ref': pull_request.shadow_merge_ref._asdict() | |
60 | } |
|
94 | } | |
61 |
|
95 | |||
62 | response_json = response.json['result'] |
|
96 | assert_ok(id_, expected, response.body) | |
63 | assert response_json == expected |
|
|||
64 |
|
97 | |||
65 | action = 'user_merged_pull_request:%d' % (pull_request_id, ) |
|
98 | action = 'user_merged_pull_request:%d' % (pull_request_id, ) | |
66 | journal = UserLog.query()\ |
|
99 | journal = UserLog.query()\ | |
@@ -75,8 +108,7 b' class TestMergePullRequest(object):' | |||||
75 | repoid=pull_request_repo, pullrequestid=pull_request_id) |
|
108 | repoid=pull_request_repo, pullrequestid=pull_request_id) | |
76 | response = api_call(self.app, params) |
|
109 | response = api_call(self.app, params) | |
77 |
|
110 | |||
78 |
expected = ' |
|
111 | expected = 'merge not possible for following reasons: This pull request is closed.' | |
79 | pull_request_id) |
|
|||
80 | assert_error(id_, expected, given=response.body) |
|
112 | assert_error(id_, expected, given=response.body) | |
81 |
|
113 | |||
82 | @pytest.mark.backends("git", "hg") |
|
114 | @pytest.mark.backends("git", "hg") |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -24,7 +24,8 b' from rhodecode.lib.vcs.nodes import File' | |||||
24 | from rhodecode.model.db import User |
|
24 | from rhodecode.model.db import User | |
25 | from rhodecode.model.pull_request import PullRequestModel |
|
25 | from rhodecode.model.pull_request import PullRequestModel | |
26 | from rhodecode.tests import TEST_USER_ADMIN_LOGIN |
|
26 | from rhodecode.tests import TEST_USER_ADMIN_LOGIN | |
27 |
from rhodecode.api.tests.utils import ( |
|
27 | from rhodecode.api.tests.utils import ( | |
|
28 | build_data, api_call, assert_ok, assert_error) | |||
28 |
|
29 | |||
29 |
|
30 | |||
30 | @pytest.mark.usefixtures("testuser_api", "app") |
|
31 | @pytest.mark.usefixtures("testuser_api", "app") | |
@@ -74,8 +75,7 b' class TestUpdatePullRequest(object):' | |||||
74 | expected = 'pull request `{}` update failed, pull request ' \ |
|
75 | expected = 'pull request `{}` update failed, pull request ' \ | |
75 | 'is closed'.format(pull_request.pull_request_id) |
|
76 | 'is closed'.format(pull_request.pull_request_id) | |
76 |
|
77 | |||
77 | response_json = response.json['error'] |
|
78 | assert_error(id_, expected, response.body) | |
78 | assert response_json == expected |
|
|||
79 |
|
79 | |||
80 | @pytest.mark.backends("git", "hg") |
|
80 | @pytest.mark.backends("git", "hg") | |
81 | def test_api_update_update_commits( |
|
81 | def test_api_update_update_commits( | |
@@ -90,9 +90,11 b' class TestUpdatePullRequest(object):' | |||||
90 | pr_util.update_source_repository(head='c') |
|
90 | pr_util.update_source_repository(head='c') | |
91 | repo = pull_request.source_repo.scm_instance() |
|
91 | repo = pull_request.source_repo.scm_instance() | |
92 | commits = [x for x in repo.get_commits()] |
|
92 | commits = [x for x in repo.get_commits()] | |
|
93 | print commits | |||
93 |
|
94 | |||
94 | added_commit_id = commits[-1].raw_id # c commit |
|
95 | added_commit_id = commits[-1].raw_id # c commit | |
95 |
common_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 | id_, params = build_data( |
|
99 | id_, params = build_data( | |
98 | self.apikey, 'update_pull_request', |
|
100 | self.apikey, 'update_pull_request', | |
@@ -107,12 +109,13 b' class TestUpdatePullRequest(object):' | |||||
107 | pull_request.pull_request_id), |
|
109 | pull_request.pull_request_id), | |
108 | "pull_request": response.json['result']['pull_request'], |
|
110 | "pull_request": response.json['result']['pull_request'], | |
109 | "updated_commits": {"added": [added_commit_id], |
|
111 | "updated_commits": {"added": [added_commit_id], | |
110 |
"common": [common_commit |
|
112 | "common": [common_commit_id], | |
|
113 | "total": total_commits, | |||
|
114 | "removed": []}, | |||
111 | "updated_reviewers": {"added": [], "removed": []}, |
|
115 | "updated_reviewers": {"added": [], "removed": []}, | |
112 | } |
|
116 | } | |
113 |
|
117 | |||
114 | response_json = response.json['result'] |
|
118 | assert_ok(id_, expected, response.body) | |
115 | assert response_json == expected |
|
|||
116 |
|
119 | |||
117 | @pytest.mark.backends("git", "hg") |
|
120 | @pytest.mark.backends("git", "hg") | |
118 | def test_api_update_change_reviewers( |
|
121 | def test_api_update_change_reviewers( | |
@@ -139,8 +142,7 b' class TestUpdatePullRequest(object):' | |||||
139 | "updated_reviewers": {"added": added, "removed": removed}, |
|
142 | "updated_reviewers": {"added": added, "removed": removed}, | |
140 | } |
|
143 | } | |
141 |
|
144 | |||
142 | response_json = response.json['result'] |
|
145 | assert_ok(id_, expected, response.body) | |
143 | assert response_json == expected |
|
|||
144 |
|
146 | |||
145 | @pytest.mark.backends("git", "hg") |
|
147 | @pytest.mark.backends("git", "hg") | |
146 | def test_api_update_bad_user_in_reviewers(self, pr_util): |
|
148 | def test_api_update_bad_user_in_reviewers(self, pr_util): | |
@@ -155,8 +157,7 b' class TestUpdatePullRequest(object):' | |||||
155 |
|
157 | |||
156 | expected = 'user `bad_name` does not exist' |
|
158 | expected = 'user `bad_name` does not exist' | |
157 |
|
159 | |||
158 | response_json = response.json['error'] |
|
160 | assert_error(id_, expected, response.body) | |
159 | assert response_json == expected |
|
|||
160 |
|
161 | |||
161 | @pytest.mark.backends("git", "hg") |
|
162 | @pytest.mark.backends("git", "hg") | |
162 | def test_api_update_repo_error(self, pr_util): |
|
163 | def test_api_update_repo_error(self, pr_util): | |
@@ -184,9 +185,7 b' class TestUpdatePullRequest(object):' | |||||
184 | response = api_call(self.app, params) |
|
185 | response = api_call(self.app, params) | |
185 |
|
186 | |||
186 | expected = 'pull request `999999` does not exist' |
|
187 | expected = 'pull request `999999` does not exist' | |
187 |
|
188 | assert_error(id_, expected, response.body) | ||
188 | response_json = response.json['error'] |
|
|||
189 | assert response_json == expected |
|
|||
190 |
|
189 | |||
191 | @pytest.mark.backends("git", "hg") |
|
190 | @pytest.mark.backends("git", "hg") | |
192 | def test_api_update_pull_request_no_perms_to_update( |
|
191 | def test_api_update_pull_request_no_perms_to_update( | |
@@ -203,5 +202,4 b' class TestUpdatePullRequest(object):' | |||||
203 | expected = ('pull request `%s` update failed, ' |
|
202 | expected = ('pull request `%s` update failed, ' | |
204 | 'no permission to update.') % pull_request.pull_request_id |
|
203 | 'no permission to update.') % pull_request.pull_request_id | |
205 |
|
204 | |||
206 | response_json = response.json['error'] |
|
205 | assert_error(id_, expected, response.body) | |
207 | assert response_json == expected |
|
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2014-201 |
|
3 | # Copyright (C) 2014-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -26,11 +26,12 b' import collections' | |||||
26 | import logging |
|
26 | import logging | |
27 |
|
27 | |||
28 | from rhodecode.api.exc import JSONRPCError |
|
28 | from rhodecode.api.exc import JSONRPCError | |
29 | from rhodecode.lib.auth import HasPermissionAnyApi, HasRepoPermissionAnyApi, \ |
|
29 | from rhodecode.lib.auth import ( | |
30 | HasRepoGroupPermissionAnyApi |
|
30 | HasPermissionAnyApi, HasRepoPermissionAnyApi, HasRepoGroupPermissionAnyApi) | |
31 | from rhodecode.lib.utils import safe_unicode |
|
31 | from rhodecode.lib.utils import safe_unicode | |
|
32 | from rhodecode.lib.vcs.exceptions import RepositoryError | |||
32 | from rhodecode.controllers.utils import get_commit_from_ref_name |
|
33 | from rhodecode.controllers.utils import get_commit_from_ref_name | |
33 |
from rhodecode.lib. |
|
34 | from rhodecode.lib.utils2 import str2bool | |
34 |
|
35 | |||
35 | log = logging.getLogger(__name__) |
|
36 | log = logging.getLogger(__name__) | |
36 |
|
37 | |||
@@ -92,7 +93,7 b' class Optional(object):' | |||||
92 | return self.type_ |
|
93 | return self.type_ | |
93 |
|
94 | |||
94 | @classmethod |
|
95 | @classmethod | |
95 | def extract(cls, val, evaluate_locals=None): |
|
96 | def extract(cls, val, evaluate_locals=None, binary=None): | |
96 | """ |
|
97 | """ | |
97 | Extracts value from Optional() instance |
|
98 | Extracts value from Optional() instance | |
98 |
|
99 | |||
@@ -101,7 +102,11 b' class Optional(object):' | |||||
101 | value of instance |
|
102 | value of instance | |
102 | """ |
|
103 | """ | |
103 | if isinstance(val, cls): |
|
104 | if isinstance(val, cls): | |
104 |
|
|
105 | val = val.getval(evaluate_locals) | |
|
106 | ||||
|
107 | if binary: | |||
|
108 | val = str2bool(val) | |||
|
109 | ||||
105 | return val |
|
110 | return val | |
106 |
|
111 | |||
107 |
|
112 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2015-201 |
|
3 | # Copyright (C) 2015-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -30,9 +30,9 b' from rhodecode.lib.auth import (HasRepoP' | |||||
30 | from rhodecode.lib.base import vcs_operation_context |
|
30 | from rhodecode.lib.base import vcs_operation_context | |
31 | from rhodecode.lib.utils2 import str2bool |
|
31 | from rhodecode.lib.utils2 import str2bool | |
32 | from rhodecode.model.changeset_status import ChangesetStatusModel |
|
32 | from rhodecode.model.changeset_status import ChangesetStatusModel | |
33 |
from rhodecode.model.comment import |
|
33 | from rhodecode.model.comment import CommentsModel | |
34 | from rhodecode.model.db import Session, ChangesetStatus |
|
34 | from rhodecode.model.db import Session, ChangesetStatus, ChangesetComment | |
35 | from rhodecode.model.pull_request import PullRequestModel |
|
35 | from rhodecode.model.pull_request import PullRequestModel, MergeCheck | |
36 | from rhodecode.model.settings import SettingsModel |
|
36 | from rhodecode.model.settings import SettingsModel | |
37 |
|
37 | |||
38 | log = logging.getLogger(__name__) |
|
38 | log = logging.getLogger(__name__) | |
@@ -270,13 +270,14 b' def merge_pull_request(request, apiuser,' | |||||
270 | raise JSONRPCError('userid is not the same as your user') |
|
270 | raise JSONRPCError('userid is not the same as your user') | |
271 |
|
271 | |||
272 | pull_request = get_pull_request_or_error(pullrequestid) |
|
272 | pull_request = get_pull_request_or_error(pullrequestid) | |
273 | if not PullRequestModel().check_user_merge( |
|
273 | ||
274 | pull_request, apiuser, api=True): |
|
274 | check = MergeCheck.validate(pull_request, user=apiuser) | |
275 | raise JSONRPCError('repository `%s` does not exist' % (repoid,)) |
|
275 | merge_possible = not check.failed | |
276 | if pull_request.is_closed(): |
|
276 | ||
|
277 | if not merge_possible: | |||
|
278 | reasons = ','.join([msg for _e, msg in check.errors]) | |||
277 | raise JSONRPCError( |
|
279 | raise JSONRPCError( | |
278 | 'pull request `%s` merge failed, pull request is closed' % ( |
|
280 | 'merge not possible for following reasons: {}'.format(reasons)) | |
279 | pullrequestid,)) |
|
|||
280 |
|
281 | |||
281 | target_repo = pull_request.target_repo |
|
282 | target_repo = pull_request.target_repo | |
282 | extras = vcs_operation_context( |
|
283 | extras = vcs_operation_context( | |
@@ -359,8 +360,11 b' def close_pull_request(request, apiuser,' | |||||
359 |
|
360 | |||
360 |
|
361 | |||
361 | @jsonrpc_method() |
|
362 | @jsonrpc_method() | |
362 | def comment_pull_request(request, apiuser, repoid, pullrequestid, |
|
363 | def comment_pull_request( | |
363 | message=Optional(None), status=Optional(None), |
|
364 | request, apiuser, repoid, pullrequestid, message=Optional(None), | |
|
365 | commit_id=Optional(None), status=Optional(None), | |||
|
366 | comment_type=Optional(ChangesetComment.COMMENT_TYPE_NOTE), | |||
|
367 | resolves_comment_id=Optional(None), | |||
364 |
|
|
368 | userid=Optional(OAttr('apiuser'))): | |
365 | """ |
|
369 | """ | |
366 | Comment on the pull request specified with the `pullrequestid`, |
|
370 | Comment on the pull request specified with the `pullrequestid`, | |
@@ -373,15 +377,18 b' def comment_pull_request(request, apiuse' | |||||
373 | :type repoid: str or int |
|
377 | :type repoid: str or int | |
374 | :param pullrequestid: The pull request ID. |
|
378 | :param pullrequestid: The pull request ID. | |
375 | :type pullrequestid: int |
|
379 | :type pullrequestid: int | |
|
380 | :param commit_id: Specify the commit_id for which to set a comment. If | |||
|
381 | given commit_id is different than latest in the PR status | |||
|
382 | change won't be performed. | |||
|
383 | :type commit_id: str | |||
376 | :param message: The text content of the comment. |
|
384 | :param message: The text content of the comment. | |
377 | :type message: str |
|
385 | :type message: str | |
378 | :param status: (**Optional**) Set the approval status of the pull |
|
386 | :param status: (**Optional**) Set the approval status of the pull | |
379 | request. Valid options are: |
|
387 | request. One of: 'not_reviewed', 'approved', 'rejected', | |
380 |
|
|
388 | 'under_review' | |
381 | * approved |
|
|||
382 | * rejected |
|
|||
383 | * under_review |
|
|||
384 | :type status: str |
|
389 | :type status: str | |
|
390 | :param comment_type: Comment type, one of: 'note', 'todo' | |||
|
391 | :type comment_type: Optional(str), default: 'note' | |||
385 | :param userid: Comment on the pull request as this user |
|
392 | :param userid: Comment on the pull request as this user | |
386 | :type userid: Optional(str or int) |
|
393 | :type userid: Optional(str or int) | |
387 |
|
394 | |||
@@ -393,7 +400,9 b' def comment_pull_request(request, apiuse' | |||||
393 | result : |
|
400 | result : | |
394 | { |
|
401 | { | |
395 | "pull_request_id": "<Integer>", |
|
402 | "pull_request_id": "<Integer>", | |
396 | "comment_id": "<Integer>" |
|
403 | "comment_id": "<Integer>", | |
|
404 | "status": {"given": <given_status>, | |||
|
405 | "was_changed": <bool status_was_actually_changed> }, | |||
397 | } |
|
406 | } | |
398 | error : null |
|
407 | error : null | |
399 | """ |
|
408 | """ | |
@@ -412,37 +421,68 b' def comment_pull_request(request, apiuse' | |||||
412 | raise JSONRPCError('repository `%s` does not exist' % (repoid,)) |
|
421 | raise JSONRPCError('repository `%s` does not exist' % (repoid,)) | |
413 | message = Optional.extract(message) |
|
422 | message = Optional.extract(message) | |
414 | status = Optional.extract(status) |
|
423 | status = Optional.extract(status) | |
|
424 | commit_id = Optional.extract(commit_id) | |||
|
425 | comment_type = Optional.extract(comment_type) | |||
|
426 | resolves_comment_id = Optional.extract(resolves_comment_id) | |||
|
427 | ||||
415 | if not message and not status: |
|
428 | if not message and not status: | |
416 | raise JSONRPCError('message and status parameter missing') |
|
429 | raise JSONRPCError( | |
|
430 | 'Both message and status parameters are missing. ' | |||
|
431 | 'At least one is required.') | |||
417 |
|
432 | |||
418 | if (status not in (st[0] for st in ChangesetStatus.STATUSES) and |
|
433 | if (status not in (st[0] for st in ChangesetStatus.STATUSES) and | |
419 | status is not None): |
|
434 | status is not None): | |
420 |
raise JSONRPCError(' |
|
435 | raise JSONRPCError('Unknown comment status: `%s`' % status) | |
|
436 | ||||
|
437 | if commit_id and commit_id not in pull_request.revisions: | |||
|
438 | raise JSONRPCError( | |||
|
439 | 'Invalid commit_id `%s` for this pull request.' % commit_id) | |||
421 |
|
440 | |||
422 | allowed_to_change_status = PullRequestModel().check_user_change_status( |
|
441 | allowed_to_change_status = PullRequestModel().check_user_change_status( | |
423 | pull_request, apiuser) |
|
442 | pull_request, apiuser) | |
|
443 | ||||
|
444 | # if commit_id is passed re-validated if user is allowed to change status | |||
|
445 | # based on latest commit_id from the PR | |||
|
446 | if commit_id: | |||
|
447 | commit_idx = pull_request.revisions.index(commit_id) | |||
|
448 | if commit_idx != 0: | |||
|
449 | allowed_to_change_status = False | |||
|
450 | ||||
|
451 | if resolves_comment_id: | |||
|
452 | comment = ChangesetComment.get(resolves_comment_id) | |||
|
453 | if not comment: | |||
|
454 | raise JSONRPCError( | |||
|
455 | 'Invalid resolves_comment_id `%s` for this pull request.' | |||
|
456 | % resolves_comment_id) | |||
|
457 | if comment.comment_type != ChangesetComment.COMMENT_TYPE_TODO: | |||
|
458 | raise JSONRPCError( | |||
|
459 | 'Comment `%s` is wrong type for setting status to resolved.' | |||
|
460 | % resolves_comment_id) | |||
|
461 | ||||
424 | text = message |
|
462 | text = message | |
|
463 | status_label = ChangesetStatus.get_status_lbl(status) | |||
425 | if status and allowed_to_change_status: |
|
464 | if status and allowed_to_change_status: | |
426 |
st_message = ( |
|
465 | st_message = ('Status change %(transition_icon)s %(status)s' | |
427 | % {'transition_icon': '>', |
|
466 | % {'transition_icon': '>', 'status': status_label}) | |
428 | 'status': ChangesetStatus.get_status_lbl(status)}) |
|
|||
429 | text = message or st_message |
|
467 | text = message or st_message | |
430 |
|
468 | |||
431 | rc_config = SettingsModel().get_all_settings() |
|
469 | rc_config = SettingsModel().get_all_settings() | |
432 | renderer = rc_config.get('rhodecode_markup_renderer', 'rst') |
|
470 | renderer = rc_config.get('rhodecode_markup_renderer', 'rst') | |
433 | comment = ChangesetCommentsModel().create( |
|
471 | ||
|
472 | status_change = status and allowed_to_change_status | |||
|
473 | comment = CommentsModel().create( | |||
434 | text=text, |
|
474 | text=text, | |
435 | repo=pull_request.target_repo.repo_id, |
|
475 | repo=pull_request.target_repo.repo_id, | |
436 | user=apiuser.user_id, |
|
476 | user=apiuser.user_id, | |
437 | pull_request=pull_request.pull_request_id, |
|
477 | pull_request=pull_request.pull_request_id, | |
438 | f_path=None, |
|
478 | f_path=None, | |
439 | line_no=None, |
|
479 | line_no=None, | |
440 |
status_change=( |
|
480 | status_change=(status_label if status_change else None), | |
441 | if status and allowed_to_change_status else None), |
|
481 | status_change_type=(status if status_change else None), | |
442 | status_change_type=(status |
|
|||
443 | if status and allowed_to_change_status else None), |
|
|||
444 | closing_pr=False, |
|
482 | closing_pr=False, | |
445 | renderer=renderer |
|
483 | renderer=renderer, | |
|
484 | comment_type=comment_type, | |||
|
485 | resolves_comment_id=resolves_comment_id | |||
446 | ) |
|
486 | ) | |
447 |
|
487 | |||
448 | if allowed_to_change_status and status: |
|
488 | if allowed_to_change_status and status: | |
@@ -458,8 +498,8 b' def comment_pull_request(request, apiuse' | |||||
458 | Session().commit() |
|
498 | Session().commit() | |
459 | data = { |
|
499 | data = { | |
460 | 'pull_request_id': pull_request.pull_request_id, |
|
500 | 'pull_request_id': pull_request.pull_request_id, | |
461 | 'comment_id': comment.comment_id, |
|
501 | 'comment_id': comment.comment_id if comment else None, | |
462 | 'status': status |
|
502 | 'status': {'given': status, 'was_changed': status_change}, | |
463 | } |
|
503 | } | |
464 | return data |
|
504 | return data | |
465 |
|
505 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -34,9 +34,10 b' from rhodecode.lib.exceptions import Sta' | |||||
34 | from rhodecode.lib.utils2 import str2bool, time_to_datetime |
|
34 | from rhodecode.lib.utils2 import str2bool, time_to_datetime | |
35 | from rhodecode.lib.ext_json import json |
|
35 | from rhodecode.lib.ext_json import json | |
36 | from rhodecode.model.changeset_status import ChangesetStatusModel |
|
36 | from rhodecode.model.changeset_status import ChangesetStatusModel | |
37 |
from rhodecode.model.comment import |
|
37 | from rhodecode.model.comment import CommentsModel | |
38 | from rhodecode.model.db import ( |
|
38 | from rhodecode.model.db import ( | |
39 |
Session, ChangesetStatus, RepositoryField, Repository |
|
39 | Session, ChangesetStatus, RepositoryField, Repository, RepoGroup, | |
|
40 | ChangesetComment) | |||
40 | from rhodecode.model.repo import RepoModel |
|
41 | from rhodecode.model.repo import RepoModel | |
41 | from rhodecode.model.scm import ScmModel, RepoList |
|
42 | from rhodecode.model.scm import ScmModel, RepoList | |
42 | from rhodecode.model.settings import SettingsModel, VcsSettingsModel |
|
43 | from rhodecode.model.settings import SettingsModel, VcsSettingsModel | |
@@ -217,7 +218,7 b' def get_repo(request, apiuser, repoid, c' | |||||
217 |
|
218 | |||
218 |
|
219 | |||
219 | @jsonrpc_method() |
|
220 | @jsonrpc_method() | |
220 | def get_repos(request, apiuser): |
|
221 | def get_repos(request, apiuser, root=Optional(None), traverse=Optional(True)): | |
221 | """ |
|
222 | """ | |
222 | Lists all existing repositories. |
|
223 | Lists all existing repositories. | |
223 |
|
224 | |||
@@ -226,6 +227,14 b' def get_repos(request, apiuser):' | |||||
226 |
|
227 | |||
227 | :param apiuser: This is filled automatically from the |authtoken|. |
|
228 | :param apiuser: This is filled automatically from the |authtoken|. | |
228 | :type apiuser: AuthUser |
|
229 | :type apiuser: AuthUser | |
|
230 | :param root: specify root repository group to fetch repositories. | |||
|
231 | filters the returned repositories to be members of given root group. | |||
|
232 | :type root: Optional(None) | |||
|
233 | :param traverse: traverse given root into subrepositories. With this flag | |||
|
234 | set to False, it will only return top-level repositories from `root`. | |||
|
235 | if root is empty it will return just top-level repositories. | |||
|
236 | :type traverse: Optional(True) | |||
|
237 | ||||
229 |
|
238 | |||
230 | Example output: |
|
239 | Example output: | |
231 |
|
240 | |||
@@ -257,8 +266,28 b' def get_repos(request, apiuser):' | |||||
257 | _perms = ('repository.read', 'repository.write', 'repository.admin',) |
|
266 | _perms = ('repository.read', 'repository.write', 'repository.admin',) | |
258 | extras = {'user': apiuser} |
|
267 | extras = {'user': apiuser} | |
259 |
|
268 | |||
260 | repo_list = RepoList( |
|
269 | root = Optional.extract(root) | |
261 | RepoModel().get_all(), perm_set=_perms, extra_kwargs=extras) |
|
270 | traverse = Optional.extract(traverse, binary=True) | |
|
271 | ||||
|
272 | if root: | |||
|
273 | # verify parent existance, if it's empty return an error | |||
|
274 | parent = RepoGroup.get_by_group_name(root) | |||
|
275 | if not parent: | |||
|
276 | raise JSONRPCError( | |||
|
277 | 'Root repository group `{}` does not exist'.format(root)) | |||
|
278 | ||||
|
279 | if traverse: | |||
|
280 | repos = RepoModel().get_repos_for_root(root=root, traverse=traverse) | |||
|
281 | else: | |||
|
282 | repos = RepoModel().get_repos_for_root(root=parent) | |||
|
283 | else: | |||
|
284 | if traverse: | |||
|
285 | repos = RepoModel().get_all() | |||
|
286 | else: | |||
|
287 | # return just top-level | |||
|
288 | repos = RepoModel().get_repos_for_root(root=None) | |||
|
289 | ||||
|
290 | repo_list = RepoList(repos, perm_set=_perms, extra_kwargs=extras) | |||
262 | return [repo.get_api_data(include_secrets=include_secrets) |
|
291 | return [repo.get_api_data(include_secrets=include_secrets) | |
263 | for repo in repo_list] |
|
292 | for repo in repo_list] | |
264 |
|
293 | |||
@@ -1354,8 +1383,10 b' def lock(request, apiuser, repoid, locke' | |||||
1354 |
|
1383 | |||
1355 | @jsonrpc_method() |
|
1384 | @jsonrpc_method() | |
1356 | def comment_commit( |
|
1385 | def comment_commit( | |
1357 | request, apiuser, repoid, commit_id, message, |
|
1386 | request, apiuser, repoid, commit_id, message, status=Optional(None), | |
1358 | userid=Optional(OAttr('apiuser')), status=Optional(None)): |
|
1387 | comment_type=Optional(ChangesetComment.COMMENT_TYPE_NOTE), | |
|
1388 | resolves_comment_id=Optional(None), | |||
|
1389 | userid=Optional(OAttr('apiuser'))): | |||
1359 | """ |
|
1390 | """ | |
1360 | Set a commit comment, and optionally change the status of the commit. |
|
1391 | Set a commit comment, and optionally change the status of the commit. | |
1361 |
|
1392 | |||
@@ -1367,15 +1398,17 b' def comment_commit(' | |||||
1367 | :type commit_id: str |
|
1398 | :type commit_id: str | |
1368 | :param message: The comment text. |
|
1399 | :param message: The comment text. | |
1369 | :type message: str |
|
1400 | :type message: str | |
|
1401 | :param status: (**Optional**) status of commit, one of: 'not_reviewed', | |||
|
1402 | 'approved', 'rejected', 'under_review' | |||
|
1403 | :type status: str | |||
|
1404 | :param comment_type: Comment type, one of: 'note', 'todo' | |||
|
1405 | :type comment_type: Optional(str), default: 'note' | |||
1370 | :param userid: Set the user name of the comment creator. |
|
1406 | :param userid: Set the user name of the comment creator. | |
1371 | :type userid: Optional(str or int) |
|
1407 | :type userid: Optional(str or int) | |
1372 | :param status: status, one of 'not_reviewed', 'approved', 'rejected', |
|
|||
1373 | 'under_review' |
|
|||
1374 | :type status: str |
|
|||
1375 |
|
1408 | |||
1376 | Example error output: |
|
1409 | Example error output: | |
1377 |
|
1410 | |||
1378 |
.. code-block:: |
|
1411 | .. code-block:: bash | |
1379 |
|
1412 | |||
1380 | { |
|
1413 | { | |
1381 | "id" : <id_given_in_input>, |
|
1414 | "id" : <id_given_in_input>, | |
@@ -1398,21 +1431,37 b' def comment_commit(' | |||||
1398 |
|
1431 | |||
1399 | user = get_user_or_error(userid) |
|
1432 | user = get_user_or_error(userid) | |
1400 | status = Optional.extract(status) |
|
1433 | status = Optional.extract(status) | |
|
1434 | comment_type = Optional.extract(comment_type) | |||
|
1435 | resolves_comment_id = Optional.extract(resolves_comment_id) | |||
1401 |
|
1436 | |||
1402 | allowed_statuses = [x[0] for x in ChangesetStatus.STATUSES] |
|
1437 | allowed_statuses = [x[0] for x in ChangesetStatus.STATUSES] | |
1403 | if status and status not in allowed_statuses: |
|
1438 | if status and status not in allowed_statuses: | |
1404 | raise JSONRPCError('Bad status, must be on ' |
|
1439 | raise JSONRPCError('Bad status, must be on ' | |
1405 | 'of %s got %s' % (allowed_statuses, status,)) |
|
1440 | 'of %s got %s' % (allowed_statuses, status,)) | |
1406 |
|
1441 | |||
|
1442 | if resolves_comment_id: | |||
|
1443 | comment = ChangesetComment.get(resolves_comment_id) | |||
|
1444 | if not comment: | |||
|
1445 | raise JSONRPCError( | |||
|
1446 | 'Invalid resolves_comment_id `%s` for this commit.' | |||
|
1447 | % resolves_comment_id) | |||
|
1448 | if comment.comment_type != ChangesetComment.COMMENT_TYPE_TODO: | |||
|
1449 | raise JSONRPCError( | |||
|
1450 | 'Comment `%s` is wrong type for setting status to resolved.' | |||
|
1451 | % resolves_comment_id) | |||
|
1452 | ||||
1407 | try: |
|
1453 | try: | |
1408 | rc_config = SettingsModel().get_all_settings() |
|
1454 | rc_config = SettingsModel().get_all_settings() | |
1409 | renderer = rc_config.get('rhodecode_markup_renderer', 'rst') |
|
1455 | renderer = rc_config.get('rhodecode_markup_renderer', 'rst') | |
1410 | status_change_label = ChangesetStatus.get_status_lbl(status) |
|
1456 | status_change_label = ChangesetStatus.get_status_lbl(status) | |
1411 |
comm = |
|
1457 | comm = CommentsModel().create( | |
1412 |
message, repo, user, |
|
1458 | message, repo, user, commit_id=commit_id, | |
1413 | status_change=status_change_label, |
|
1459 | status_change=status_change_label, | |
1414 | status_change_type=status, |
|
1460 | status_change_type=status, | |
1415 |
renderer=renderer |
|
1461 | renderer=renderer, | |
|
1462 | comment_type=comment_type, | |||
|
1463 | resolves_comment_id=resolves_comment_id | |||
|
1464 | ) | |||
1416 | if status: |
|
1465 | if status: | |
1417 | # also do a status change |
|
1466 | # also do a status change | |
1418 | try: |
|
1467 | try: |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -26,6 +26,8 b' from rhodecode.api import jsonrpc_method' | |||||
26 | from rhodecode.api.utils import ( |
|
26 | from rhodecode.api.utils import ( | |
27 | Optional, OAttr, has_superadmin_permission, get_user_or_error) |
|
27 | Optional, OAttr, has_superadmin_permission, get_user_or_error) | |
28 | from rhodecode.lib.utils import repo2db_mapper |
|
28 | from rhodecode.lib.utils import repo2db_mapper | |
|
29 | from rhodecode.lib import system_info | |||
|
30 | from rhodecode.lib import user_sessions | |||
29 | from rhodecode.model.db import UserIpMap |
|
31 | from rhodecode.model.db import UserIpMap | |
30 | from rhodecode.model.scm import ScmModel |
|
32 | from rhodecode.model.scm import ScmModel | |
31 |
|
33 | |||
@@ -176,3 +178,67 b' def rescan_repos(request, apiuser, remov' | |||||
176 | 'Error occurred during rescan repositories action' |
|
178 | 'Error occurred during rescan repositories action' | |
177 | ) |
|
179 | ) | |
178 |
|
180 | |||
|
181 | ||||
|
182 | @jsonrpc_method() | |||
|
183 | def cleanup_sessions(request, apiuser, older_then=Optional(60)): | |||
|
184 | """ | |||
|
185 | Triggers a session cleanup action. | |||
|
186 | ||||
|
187 | If the ``older_then`` option is set, only sessions that hasn't been | |||
|
188 | accessed in the given number of days will be removed. | |||
|
189 | ||||
|
190 | This command can only be run using an |authtoken| with admin rights to | |||
|
191 | the specified repository. | |||
|
192 | ||||
|
193 | This command takes the following options: | |||
|
194 | ||||
|
195 | :param apiuser: This is filled automatically from the |authtoken|. | |||
|
196 | :type apiuser: AuthUser | |||
|
197 | :param older_then: Deletes session that hasn't been accessed | |||
|
198 | in given number of days. | |||
|
199 | :type older_then: Optional(int) | |||
|
200 | ||||
|
201 | Example output: | |||
|
202 | ||||
|
203 | .. code-block:: bash | |||
|
204 | ||||
|
205 | id : <id_given_in_input> | |||
|
206 | result: { | |||
|
207 | "backend": "<type of backend>", | |||
|
208 | "sessions_removed": <number_of_removed_sessions> | |||
|
209 | } | |||
|
210 | error : null | |||
|
211 | ||||
|
212 | Example error output: | |||
|
213 | ||||
|
214 | .. code-block:: bash | |||
|
215 | ||||
|
216 | id : <id_given_in_input> | |||
|
217 | result : null | |||
|
218 | error : { | |||
|
219 | 'Error occurred during session cleanup' | |||
|
220 | } | |||
|
221 | ||||
|
222 | """ | |||
|
223 | if not has_superadmin_permission(apiuser): | |||
|
224 | raise JSONRPCForbidden() | |||
|
225 | ||||
|
226 | older_then = Optional.extract(older_then) | |||
|
227 | older_than_seconds = 60 * 60 * 24 * older_then | |||
|
228 | ||||
|
229 | config = system_info.rhodecode_config().get_value()['value']['config'] | |||
|
230 | session_model = user_sessions.get_session_handler( | |||
|
231 | config.get('beaker.session.type', 'memory'))(config) | |||
|
232 | ||||
|
233 | backend = session_model.SESSION_TYPE | |||
|
234 | try: | |||
|
235 | cleaned = session_model.clean_sessions( | |||
|
236 | older_than_seconds=older_than_seconds) | |||
|
237 | return {'sessions_removed': cleaned, 'backend': backend} | |||
|
238 | except user_sessions.CleanupCommand as msg: | |||
|
239 | return {'cleanup_command': msg.message, 'backend': backend} | |||
|
240 | except Exception as e: | |||
|
241 | log.exception('Failed session cleanup') | |||
|
242 | raise JSONRPCError( | |||
|
243 | 'Error occurred during session cleanup' | |||
|
244 | ) |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2012-201 |
|
3 | # Copyright (C) 2012-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2012-201 |
|
3 | # Copyright (C) 2012-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2012-201 |
|
3 | # Copyright (C) 2012-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -197,14 +197,14 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||||
197 | config.add_view( |
|
197 | config.add_view( | |
198 | 'rhodecode.authentication.views.AuthnPluginViewBase', |
|
198 | 'rhodecode.authentication.views.AuthnPluginViewBase', | |
199 | attr='settings_get', |
|
199 | attr='settings_get', | |
200 |
renderer='rhodecode:templates/admin/auth/plugin_settings. |
|
200 | renderer='rhodecode:templates/admin/auth/plugin_settings.mako', | |
201 | request_method='GET', |
|
201 | request_method='GET', | |
202 | route_name='auth_home', |
|
202 | route_name='auth_home', | |
203 | context=CrowdAuthnResource) |
|
203 | context=CrowdAuthnResource) | |
204 | config.add_view( |
|
204 | config.add_view( | |
205 | 'rhodecode.authentication.views.AuthnPluginViewBase', |
|
205 | 'rhodecode.authentication.views.AuthnPluginViewBase', | |
206 | attr='settings_post', |
|
206 | attr='settings_post', | |
207 |
renderer='rhodecode:templates/admin/auth/plugin_settings. |
|
207 | renderer='rhodecode:templates/admin/auth/plugin_settings.mako', | |
208 | request_method='POST', |
|
208 | request_method='POST', | |
209 | route_name='auth_home', |
|
209 | route_name='auth_home', | |
210 | context=CrowdAuthnResource) |
|
210 | context=CrowdAuthnResource) |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2012-201 |
|
3 | # Copyright (C) 2012-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -83,14 +83,14 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||||
83 | config.add_view( |
|
83 | config.add_view( | |
84 | 'rhodecode.authentication.views.AuthnPluginViewBase', |
|
84 | 'rhodecode.authentication.views.AuthnPluginViewBase', | |
85 | attr='settings_get', |
|
85 | attr='settings_get', | |
86 |
renderer='rhodecode:templates/admin/auth/plugin_settings. |
|
86 | renderer='rhodecode:templates/admin/auth/plugin_settings.mako', | |
87 | request_method='GET', |
|
87 | request_method='GET', | |
88 | route_name='auth_home', |
|
88 | route_name='auth_home', | |
89 | context=HeadersAuthnResource) |
|
89 | context=HeadersAuthnResource) | |
90 | config.add_view( |
|
90 | config.add_view( | |
91 | 'rhodecode.authentication.views.AuthnPluginViewBase', |
|
91 | 'rhodecode.authentication.views.AuthnPluginViewBase', | |
92 | attr='settings_post', |
|
92 | attr='settings_post', | |
93 |
renderer='rhodecode:templates/admin/auth/plugin_settings. |
|
93 | renderer='rhodecode:templates/admin/auth/plugin_settings.mako', | |
94 | request_method='POST', |
|
94 | request_method='POST', | |
95 | route_name='auth_home', |
|
95 | route_name='auth_home', | |
96 | context=HeadersAuthnResource) |
|
96 | context=HeadersAuthnResource) |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2012-201 |
|
3 | # Copyright (C) 2012-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -74,14 +74,14 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||||
74 | config.add_view( |
|
74 | config.add_view( | |
75 | 'rhodecode.authentication.views.AuthnPluginViewBase', |
|
75 | 'rhodecode.authentication.views.AuthnPluginViewBase', | |
76 | attr='settings_get', |
|
76 | attr='settings_get', | |
77 |
renderer='rhodecode:templates/admin/auth/plugin_settings. |
|
77 | renderer='rhodecode:templates/admin/auth/plugin_settings.mako', | |
78 | request_method='GET', |
|
78 | request_method='GET', | |
79 | route_name='auth_home', |
|
79 | route_name='auth_home', | |
80 | context=JasigCasAuthnResource) |
|
80 | context=JasigCasAuthnResource) | |
81 | config.add_view( |
|
81 | config.add_view( | |
82 | 'rhodecode.authentication.views.AuthnPluginViewBase', |
|
82 | 'rhodecode.authentication.views.AuthnPluginViewBase', | |
83 | attr='settings_post', |
|
83 | attr='settings_post', | |
84 |
renderer='rhodecode:templates/admin/auth/plugin_settings. |
|
84 | renderer='rhodecode:templates/admin/auth/plugin_settings.mako', | |
85 | request_method='POST', |
|
85 | request_method='POST', | |
86 | route_name='auth_home', |
|
86 | route_name='auth_home', | |
87 | context=JasigCasAuthnResource) |
|
87 | context=JasigCasAuthnResource) |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -332,14 +332,14 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||||
332 | config.add_view( |
|
332 | config.add_view( | |
333 | 'rhodecode.authentication.views.AuthnPluginViewBase', |
|
333 | 'rhodecode.authentication.views.AuthnPluginViewBase', | |
334 | attr='settings_get', |
|
334 | attr='settings_get', | |
335 |
renderer='rhodecode:templates/admin/auth/plugin_settings. |
|
335 | renderer='rhodecode:templates/admin/auth/plugin_settings.mako', | |
336 | request_method='GET', |
|
336 | request_method='GET', | |
337 | route_name='auth_home', |
|
337 | route_name='auth_home', | |
338 | context=LdapAuthnResource) |
|
338 | context=LdapAuthnResource) | |
339 | config.add_view( |
|
339 | config.add_view( | |
340 | 'rhodecode.authentication.views.AuthnPluginViewBase', |
|
340 | 'rhodecode.authentication.views.AuthnPluginViewBase', | |
341 | attr='settings_post', |
|
341 | attr='settings_post', | |
342 |
renderer='rhodecode:templates/admin/auth/plugin_settings. |
|
342 | renderer='rhodecode:templates/admin/auth/plugin_settings.mako', | |
343 | request_method='POST', |
|
343 | request_method='POST', | |
344 | route_name='auth_home', |
|
344 | route_name='auth_home', | |
345 | context=LdapAuthnResource) |
|
345 | context=LdapAuthnResource) |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2012-201 |
|
3 | # Copyright (C) 2012-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -82,14 +82,14 b' class RhodeCodeAuthPlugin(RhodeCodeExter' | |||||
82 | config.add_view( |
|
82 | config.add_view( | |
83 | 'rhodecode.authentication.views.AuthnPluginViewBase', |
|
83 | 'rhodecode.authentication.views.AuthnPluginViewBase', | |
84 | attr='settings_get', |
|
84 | attr='settings_get', | |
85 |
renderer='rhodecode:templates/admin/auth/plugin_settings. |
|
85 | renderer='rhodecode:templates/admin/auth/plugin_settings.mako', | |
86 | request_method='GET', |
|
86 | request_method='GET', | |
87 | route_name='auth_home', |
|
87 | route_name='auth_home', | |
88 | context=PamAuthnResource) |
|
88 | context=PamAuthnResource) | |
89 | config.add_view( |
|
89 | config.add_view( | |
90 | 'rhodecode.authentication.views.AuthnPluginViewBase', |
|
90 | 'rhodecode.authentication.views.AuthnPluginViewBase', | |
91 | attr='settings_post', |
|
91 | attr='settings_post', | |
92 |
renderer='rhodecode:templates/admin/auth/plugin_settings. |
|
92 | renderer='rhodecode:templates/admin/auth/plugin_settings.mako', | |
93 | request_method='POST', |
|
93 | request_method='POST', | |
94 | route_name='auth_home', |
|
94 | route_name='auth_home', | |
95 | context=PamAuthnResource) |
|
95 | context=PamAuthnResource) |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2012-201 |
|
3 | # Copyright (C) 2012-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -52,14 +52,14 b' class RhodeCodeAuthPlugin(RhodeCodeAuthP' | |||||
52 | config.add_view( |
|
52 | config.add_view( | |
53 | 'rhodecode.authentication.views.AuthnPluginViewBase', |
|
53 | 'rhodecode.authentication.views.AuthnPluginViewBase', | |
54 | attr='settings_get', |
|
54 | attr='settings_get', | |
55 |
renderer='rhodecode:templates/admin/auth/plugin_settings. |
|
55 | renderer='rhodecode:templates/admin/auth/plugin_settings.mako', | |
56 | request_method='GET', |
|
56 | request_method='GET', | |
57 | route_name='auth_home', |
|
57 | route_name='auth_home', | |
58 | context=RhodecodeAuthnResource) |
|
58 | context=RhodecodeAuthnResource) | |
59 | config.add_view( |
|
59 | config.add_view( | |
60 | 'rhodecode.authentication.views.AuthnPluginViewBase', |
|
60 | 'rhodecode.authentication.views.AuthnPluginViewBase', | |
61 | attr='settings_post', |
|
61 | attr='settings_post', | |
62 |
renderer='rhodecode:templates/admin/auth/plugin_settings. |
|
62 | renderer='rhodecode:templates/admin/auth/plugin_settings.mako', | |
63 | request_method='POST', |
|
63 | request_method='POST', | |
64 | route_name='auth_home', |
|
64 | route_name='auth_home', | |
65 | context=RhodecodeAuthnResource) |
|
65 | context=RhodecodeAuthnResource) |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -55,14 +55,14 b' class RhodeCodeAuthPlugin(RhodeCodeAuthP' | |||||
55 | config.add_view( |
|
55 | config.add_view( | |
56 | 'rhodecode.authentication.views.AuthnPluginViewBase', |
|
56 | 'rhodecode.authentication.views.AuthnPluginViewBase', | |
57 | attr='settings_get', |
|
57 | attr='settings_get', | |
58 |
renderer='rhodecode:templates/admin/auth/plugin_settings. |
|
58 | renderer='rhodecode:templates/admin/auth/plugin_settings.mako', | |
59 | request_method='GET', |
|
59 | request_method='GET', | |
60 | route_name='auth_home', |
|
60 | route_name='auth_home', | |
61 | context=RhodecodeAuthnResource) |
|
61 | context=RhodecodeAuthnResource) | |
62 | config.add_view( |
|
62 | config.add_view( | |
63 | 'rhodecode.authentication.views.AuthnPluginViewBase', |
|
63 | 'rhodecode.authentication.views.AuthnPluginViewBase', | |
64 | attr='settings_post', |
|
64 | attr='settings_post', | |
65 |
renderer='rhodecode:templates/admin/auth/plugin_settings. |
|
65 | renderer='rhodecode:templates/admin/auth/plugin_settings.mako', | |
66 | request_method='POST', |
|
66 | request_method='POST', | |
67 | route_name='auth_home', |
|
67 | route_name='auth_home', | |
68 | context=RhodecodeAuthnResource) |
|
68 | context=RhodecodeAuthnResource) |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2012-201 |
|
3 | # Copyright (C) 2012-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2012-201 |
|
3 | # Copyright (C) 2012-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2012-201 |
|
3 | # Copyright (C) 2012-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,4 +1,4 b'' | |||||
1 |
# Copyright (C) 201 |
|
1 | # Copyright (C) 2017 RhodeCode GmbH | |
2 | # |
|
2 | # | |
3 | # This program is free software: you can redistribute it and/or modify |
|
3 | # This program is free software: you can redistribute it and/or modify | |
4 | # it under the terms of the GNU Affero General Public License, version 3 |
|
4 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2012-201 |
|
3 | # Copyright (C) 2012-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -134,7 +134,7 b' class AuthSettingsView(object):' | |||||
134 | 'available_plugins': authn_registry.get_plugins(), |
|
134 | 'available_plugins': authn_registry.get_plugins(), | |
135 | 'enabled_plugins': enabled_plugins, |
|
135 | 'enabled_plugins': enabled_plugins, | |
136 | } |
|
136 | } | |
137 |
html = render('rhodecode:templates/admin/auth/auth_settings. |
|
137 | html = render('rhodecode:templates/admin/auth/auth_settings.mako', | |
138 | template_context, |
|
138 | template_context, | |
139 | request=self.request) |
|
139 | request=self.request) | |
140 |
|
140 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -46,7 +46,7 b' PLUGIN_DEFINITION = {' | |||||
46 | 'javascript': [], |
|
46 | 'javascript': [], | |
47 | 'css': [], |
|
47 | 'css': [], | |
48 | 'template_hooks': { |
|
48 | 'template_hooks': { | |
49 |
'plugin_init_template': 'rhodecode:templates/channelstream/plugin_init. |
|
49 | 'plugin_init_template': 'rhodecode:templates/channelstream/plugin_init.mako' | |
50 | }, |
|
50 | }, | |
51 | 'url_gen': url_gen, |
|
51 | 'url_gen': url_gen, | |
52 | 'static': None, |
|
52 | 'static': None, |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -62,7 +62,7 b' class ChannelstreamView(object):' | |||||
62 | registry = request.registry |
|
62 | registry = request.registry | |
63 | self.channelstream_config = registry.rhodecode_plugins['channelstream'] |
|
63 | self.channelstream_config = registry.rhodecode_plugins['channelstream'] | |
64 | if not self.channelstream_config.get('enabled'): |
|
64 | if not self.channelstream_config.get('enabled'): | |
65 |
log.e |
|
65 | log.error('Channelstream plugin is disabled') | |
66 | raise HTTPBadRequest() |
|
66 | raise HTTPBadRequest() | |
67 |
|
67 | |||
68 | @NotAnonymous() |
|
68 | @NotAnonymous() |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2013-201 |
|
3 | # Copyright (C) 2013-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -52,7 +52,8 b' from rhodecode.lib.middleware.https_fixu' | |||||
52 | from rhodecode.lib.middleware.vcs import VCSMiddleware |
|
52 | from rhodecode.lib.middleware.vcs import VCSMiddleware | |
53 | from rhodecode.lib.plugins.utils import register_rhodecode_plugin |
|
53 | from rhodecode.lib.plugins.utils import register_rhodecode_plugin | |
54 | from rhodecode.lib.utils2 import aslist as rhodecode_aslist |
|
54 | from rhodecode.lib.utils2 import aslist as rhodecode_aslist | |
55 |
from rhodecode.subscribers import |
|
55 | from rhodecode.subscribers import ( | |
|
56 | scan_repositories_if_enabled, write_metadata_if_needed) | |||
56 |
|
57 | |||
57 |
|
58 | |||
58 | log = logging.getLogger(__name__) |
|
59 | log = logging.getLogger(__name__) | |
@@ -232,6 +233,14 b' def error_handler(exception, request):' | |||||
232 | if isinstance(exception, HTTPError): |
|
233 | if isinstance(exception, HTTPError): | |
233 | base_response = exception |
|
234 | base_response = exception | |
234 |
|
235 | |||
|
236 | def is_http_error(response): | |||
|
237 | # error which should have traceback | |||
|
238 | return response.status_code > 499 | |||
|
239 | ||||
|
240 | if is_http_error(base_response): | |||
|
241 | log.exception( | |||
|
242 | 'error occurred handling this request for path: %s', request.path) | |||
|
243 | ||||
235 | c = AttributeDict() |
|
244 | c = AttributeDict() | |
236 | c.error_message = base_response.status |
|
245 | c.error_message = base_response.status | |
237 | c.error_explanation = base_response.explanation or str(base_response) |
|
246 | c.error_explanation = base_response.explanation or str(base_response) | |
@@ -251,7 +260,7 b' def error_handler(exception, request):' | |||||
251 | c.causes = base_response.causes |
|
260 | c.causes = base_response.causes | |
252 |
|
261 | |||
253 | response = render_to_response( |
|
262 | response = render_to_response( | |
254 |
'/errors/error_document. |
|
263 | '/errors/error_document.mako', {'c': c}, request=request, | |
255 | response=base_response) |
|
264 | response=base_response) | |
256 |
|
265 | |||
257 | return response |
|
266 | return response | |
@@ -283,8 +292,12 b' def includeme(config):' | |||||
283 | config.add_route( |
|
292 | config.add_route( | |
284 | 'rhodecode_support', 'https://rhodecode.com/help/', static=True) |
|
293 | 'rhodecode_support', 'https://rhodecode.com/help/', static=True) | |
285 |
|
294 | |||
|
295 | config.add_translation_dirs('rhodecode:i18n/') | |||
|
296 | settings['default_locale_name'] = settings.get('lang', 'en') | |||
|
297 | ||||
286 | # Add subscribers. |
|
298 | # Add subscribers. | |
287 | config.add_subscriber(scan_repositories_if_enabled, ApplicationCreated) |
|
299 | config.add_subscriber(scan_repositories_if_enabled, ApplicationCreated) | |
|
300 | config.add_subscriber(write_metadata_if_needed, ApplicationCreated) | |||
288 |
|
301 | |||
289 | # Set the authorization policy. |
|
302 | # Set the authorization policy. | |
290 | authz_policy = ACLAuthorizationPolicy() |
|
303 | authz_policy = ACLAuthorizationPolicy() | |
@@ -320,6 +333,13 b' def includeme_first(config):' | |||||
320 | config.add_view(favicon_redirect, route_name='favicon') |
|
333 | config.add_view(favicon_redirect, route_name='favicon') | |
321 | config.add_route('favicon', '/favicon.ico') |
|
334 | config.add_route('favicon', '/favicon.ico') | |
322 |
|
335 | |||
|
336 | def robots_redirect(context, request): | |||
|
337 | return HTTPFound( | |||
|
338 | request.static_path('rhodecode:public/robots.txt')) | |||
|
339 | ||||
|
340 | config.add_view(robots_redirect, route_name='robots') | |||
|
341 | config.add_route('robots', '/robots.txt') | |||
|
342 | ||||
323 | config.add_static_view( |
|
343 | config.add_static_view( | |
324 | '_static/deform', 'deform:static') |
|
344 | '_static/deform', 'deform:static') | |
325 | config.add_static_view( |
|
345 | config.add_static_view( | |
@@ -351,7 +371,6 b' def wrap_app_in_wsgi_middlewares(pyramid' | |||||
351 | pyramid_app = make_gzip_middleware( |
|
371 | pyramid_app = make_gzip_middleware( | |
352 | pyramid_app, settings, compress_level=1) |
|
372 | pyramid_app, settings, compress_level=1) | |
353 |
|
373 | |||
354 |
|
||||
355 | # this should be the outer most middleware in the wsgi stack since |
|
374 | # this should be the outer most middleware in the wsgi stack since | |
356 | # middleware like Routes make database calls |
|
375 | # middleware like Routes make database calls | |
357 | def pyramid_app_with_cleanup(environ, start_response): |
|
376 | def pyramid_app_with_cleanup(environ, start_response): |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2016-201 |
|
3 | # Copyright (C) 2016-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -503,12 +503,6 b' def make_map(config):' | |||||
503 | m.connect('admin_settings_search', '/settings/search', |
|
503 | m.connect('admin_settings_search', '/settings/search', | |
504 | action='settings_search', conditions={'method': ['GET']}) |
|
504 | action='settings_search', conditions={'method': ['GET']}) | |
505 |
|
505 | |||
506 | m.connect('admin_settings_system', '/settings/system', |
|
|||
507 | action='settings_system', conditions={'method': ['GET']}) |
|
|||
508 |
|
||||
509 | m.connect('admin_settings_system_update', '/settings/system/updates', |
|
|||
510 | action='settings_system_update', conditions={'method': ['GET']}) |
|
|||
511 |
|
||||
512 | m.connect('admin_settings_supervisor', '/settings/supervisor', |
|
506 | m.connect('admin_settings_supervisor', '/settings/supervisor', | |
513 | action='settings_supervisor', conditions={'method': ['GET']}) |
|
507 | action='settings_supervisor', conditions={'method': ['GET']}) | |
514 | m.connect('admin_settings_supervisor_log', '/settings/supervisor/{procid}/log', |
|
508 | m.connect('admin_settings_supervisor_log', '/settings/supervisor/{procid}/log', | |
@@ -566,6 +560,10 b' def make_map(config):' | |||||
566 | '/my_account/toggle_visibility', |
|
560 | '/my_account/toggle_visibility', | |
567 | action='my_notifications_toggle_visibility', |
|
561 | action='my_notifications_toggle_visibility', | |
568 | conditions={'method': ['POST']}) |
|
562 | conditions={'method': ['POST']}) | |
|
563 | m.connect('my_account_notifications_test_channelstream', | |||
|
564 | '/my_account/test_channelstream', | |||
|
565 | action='my_account_notifications_test_channelstream', | |||
|
566 | conditions={'method': ['POST']}) | |||
569 |
|
567 | |||
570 | # NOTIFICATION REST ROUTES |
|
568 | # NOTIFICATION REST ROUTES | |
571 | with rmap.submapper(path_prefix=ADMIN_PREFIX, |
|
569 | with rmap.submapper(path_prefix=ADMIN_PREFIX, | |
@@ -624,9 +622,11 b' def make_map(config):' | |||||
624 | 'pull_requests_global_0', '/pull_requests/{pull_request_id:[0-9]+}', |
|
622 | 'pull_requests_global_0', '/pull_requests/{pull_request_id:[0-9]+}', | |
625 | action='pull_requests') |
|
623 | action='pull_requests') | |
626 | m.connect( |
|
624 | m.connect( | |
627 | 'pull_requests_global', '/pull-requests/{pull_request_id:[0-9]+}', |
|
625 | 'pull_requests_global_1', '/pull-requests/{pull_request_id:[0-9]+}', | |
628 | action='pull_requests') |
|
626 | action='pull_requests') | |
629 |
|
627 | m.connect( | ||
|
628 | 'pull_requests_global', '/pull-request/{pull_request_id:[0-9]+}', | |||
|
629 | action='pull_requests') | |||
630 |
|
630 | |||
631 | # USER JOURNAL |
|
631 | # USER JOURNAL | |
632 | rmap.connect('journal', '%s/journal' % (ADMIN_PREFIX,), |
|
632 | rmap.connect('journal', '%s/journal' % (ADMIN_PREFIX,), | |
@@ -694,8 +694,8 b' def make_map(config):' | |||||
694 | requirements=URL_NAME_REQUIREMENTS, jsroute=True) |
|
694 | requirements=URL_NAME_REQUIREMENTS, jsroute=True) | |
695 |
|
695 | |||
696 | rmap.connect('repo_refs_data', '/{repo_name}/refs-data', |
|
696 | rmap.connect('repo_refs_data', '/{repo_name}/refs-data', | |
697 |
controller='summary', action='repo_refs_data', |
|
697 | controller='summary', action='repo_refs_data', | |
698 | requirements=URL_NAME_REQUIREMENTS) |
|
698 | requirements=URL_NAME_REQUIREMENTS, jsroute=True) | |
699 | rmap.connect('repo_refs_changelog_data', '/{repo_name}/refs-data-changelog', |
|
699 | rmap.connect('repo_refs_changelog_data', '/{repo_name}/refs-data-changelog', | |
700 | controller='summary', action='repo_refs_changelog_data', |
|
700 | controller='summary', action='repo_refs_changelog_data', | |
701 | requirements=URL_NAME_REQUIREMENTS, jsroute=True) |
|
701 | requirements=URL_NAME_REQUIREMENTS, jsroute=True) | |
@@ -704,9 +704,9 b' def make_map(config):' | |||||
704 | jsroute=True, requirements=URL_NAME_REQUIREMENTS) |
|
704 | jsroute=True, requirements=URL_NAME_REQUIREMENTS) | |
705 |
|
705 | |||
706 | rmap.connect('changeset_home', '/{repo_name}/changeset/{revision}', |
|
706 | rmap.connect('changeset_home', '/{repo_name}/changeset/{revision}', | |
707 |
controller='changeset', revision='tip', |
|
707 | controller='changeset', revision='tip', | |
708 | conditions={'function': check_repo}, |
|
708 | conditions={'function': check_repo}, | |
709 | requirements=URL_NAME_REQUIREMENTS) |
|
709 | requirements=URL_NAME_REQUIREMENTS, jsroute=True) | |
710 | rmap.connect('changeset_children', '/{repo_name}/changeset_children/{revision}', |
|
710 | rmap.connect('changeset_children', '/{repo_name}/changeset_children/{revision}', | |
711 | controller='changeset', revision='tip', action='changeset_children', |
|
711 | controller='changeset', revision='tip', action='changeset_children', | |
712 | conditions={'function': check_repo}, |
|
712 | conditions={'function': check_repo}, | |
@@ -923,7 +923,7 b' def make_map(config):' | |||||
923 | controller='pullrequests', |
|
923 | controller='pullrequests', | |
924 | action='show', conditions={'function': check_repo, |
|
924 | action='show', conditions={'function': check_repo, | |
925 | 'method': ['GET']}, |
|
925 | 'method': ['GET']}, | |
926 | requirements=URL_NAME_REQUIREMENTS) |
|
926 | requirements=URL_NAME_REQUIREMENTS, jsroute=True) | |
927 |
|
927 | |||
928 | rmap.connect('pullrequest_update', |
|
928 | rmap.connect('pullrequest_update', | |
929 | '/{repo_name}/pull-request/{pull_request_id}', |
|
929 | '/{repo_name}/pull-request/{pull_request_id}', | |
@@ -997,10 +997,10 b' def make_map(config):' | |||||
997 | conditions={'function': check_repo}, |
|
997 | conditions={'function': check_repo}, | |
998 | requirements=URL_NAME_REQUIREMENTS, jsroute=True) |
|
998 | requirements=URL_NAME_REQUIREMENTS, jsroute=True) | |
999 |
|
999 | |||
1000 |
rmap.connect('changelog_ |
|
1000 | rmap.connect('changelog_elements', '/{repo_name}/changelog_details', | |
1001 |
controller='changelog', action='changelog_ |
|
1001 | controller='changelog', action='changelog_elements', | |
1002 | conditions={'function': check_repo}, |
|
1002 | conditions={'function': check_repo}, | |
1003 | requirements=URL_NAME_REQUIREMENTS) |
|
1003 | requirements=URL_NAME_REQUIREMENTS, jsroute=True) | |
1004 |
|
1004 | |||
1005 | rmap.connect('files_home', '/{repo_name}/files/{revision}/{f_path}', |
|
1005 | rmap.connect('files_home', '/{repo_name}/files/{revision}/{f_path}', | |
1006 | controller='files', revision='tip', f_path='', |
|
1006 | controller='files', revision='tip', f_path='', | |
@@ -1064,7 +1064,7 b' def make_map(config):' | |||||
1064 | '/{repo_name}/annotate/{revision}/{f_path}', |
|
1064 | '/{repo_name}/annotate/{revision}/{f_path}', | |
1065 | controller='files', action='index', revision='tip', |
|
1065 | controller='files', action='index', revision='tip', | |
1066 | f_path='', annotate=True, conditions={'function': check_repo}, |
|
1066 | f_path='', annotate=True, conditions={'function': check_repo}, | |
1067 | requirements=URL_NAME_REQUIREMENTS) |
|
1067 | requirements=URL_NAME_REQUIREMENTS, jsroute=True) | |
1068 |
|
1068 | |||
1069 | rmap.connect('files_edit', |
|
1069 | rmap.connect('files_edit', | |
1070 | '/{repo_name}/edit/{revision}/{f_path}', |
|
1070 | '/{repo_name}/edit/{revision}/{f_path}', |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -153,11 +153,11 b' class AdminController(BaseController):' | |||||
153 |
|
153 | |||
154 | c.users_log = Page(users_log, page=p, items_per_page=10, |
|
154 | c.users_log = Page(users_log, page=p, items_per_page=10, | |
155 | url=url_generator) |
|
155 | url=url_generator) | |
156 |
c.log_data = render('admin/admin_log. |
|
156 | c.log_data = render('admin/admin_log.mako') | |
157 |
|
157 | |||
158 | if request.is_xhr: |
|
158 | if request.is_xhr: | |
159 | return c.log_data |
|
159 | return c.log_data | |
160 |
return render('admin/admin. |
|
160 | return render('admin/admin.mako') | |
161 |
|
161 | |||
162 | # global redirect doesn't need permissions |
|
162 | # global redirect doesn't need permissions | |
163 | def pull_requests(self, pull_request_id): |
|
163 | def pull_requests(self, pull_request_id): |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -57,7 +57,7 b' class DefaultsController(BaseController)' | |||||
57 | defaults = SettingsModel().get_default_repo_settings() |
|
57 | defaults = SettingsModel().get_default_repo_settings() | |
58 |
|
58 | |||
59 | return htmlfill.render( |
|
59 | return htmlfill.render( | |
60 |
render('admin/defaults/defaults. |
|
60 | render('admin/defaults/defaults.mako'), | |
61 | defaults=defaults, |
|
61 | defaults=defaults, | |
62 | encoding="UTF-8", |
|
62 | encoding="UTF-8", | |
63 | force_defaults=False |
|
63 | force_defaults=False | |
@@ -88,7 +88,7 b' class DefaultsController(BaseController)' | |||||
88 | defaults = errors.value |
|
88 | defaults = errors.value | |
89 |
|
89 | |||
90 | return htmlfill.render( |
|
90 | return htmlfill.render( | |
91 |
render('admin/defaults/defaults. |
|
91 | render('admin/defaults/defaults.mako'), | |
92 | defaults=defaults, |
|
92 | defaults=defaults, | |
93 | errors=errors.error_dict or {}, |
|
93 | errors=errors.error_dict or {}, | |
94 | prefix_error=False, |
|
94 | prefix_error=False, |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2013-201 |
|
3 | # Copyright (C) 2013-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -114,7 +114,7 b' class GistsController(BaseController):' | |||||
114 | c.active = 'public' |
|
114 | c.active = 'public' | |
115 |
|
115 | |||
116 | from rhodecode.lib.utils import PartialRenderer |
|
116 | from rhodecode.lib.utils import PartialRenderer | |
117 |
_render = PartialRenderer('data_table/_dt_elements. |
|
117 | _render = PartialRenderer('data_table/_dt_elements.mako') | |
118 |
|
118 | |||
119 | data = [] |
|
119 | data = [] | |
120 |
|
120 | |||
@@ -130,7 +130,7 b' class GistsController(BaseController):' | |||||
130 | 'description': _render('gist_description', gist.gist_description) |
|
130 | 'description': _render('gist_description', gist.gist_description) | |
131 | }) |
|
131 | }) | |
132 | c.data = json.dumps(data) |
|
132 | c.data = json.dumps(data) | |
133 |
return render('admin/gists/index. |
|
133 | return render('admin/gists/index.mako') | |
134 |
|
134 | |||
135 | @LoginRequired() |
|
135 | @LoginRequired() | |
136 | @NotAnonymous() |
|
136 | @NotAnonymous() | |
@@ -186,7 +186,7 b' class GistsController(BaseController):' | |||||
186 | del errors['nodes.0.filename'] |
|
186 | del errors['nodes.0.filename'] | |
187 |
|
187 | |||
188 | return formencode.htmlfill.render( |
|
188 | return formencode.htmlfill.render( | |
189 |
render('admin/gists/new. |
|
189 | render('admin/gists/new.mako'), | |
190 | defaults=defaults, |
|
190 | defaults=defaults, | |
191 | errors=errors, |
|
191 | errors=errors, | |
192 | prefix_error=False, |
|
192 | prefix_error=False, | |
@@ -202,11 +202,11 b' class GistsController(BaseController):' | |||||
202 |
|
202 | |||
203 | @LoginRequired() |
|
203 | @LoginRequired() | |
204 | @NotAnonymous() |
|
204 | @NotAnonymous() | |
205 |
def new(self |
|
205 | def new(self): | |
206 | """GET /admin/gists/new: Form to create a new item""" |
|
206 | """GET /admin/gists/new: Form to create a new item""" | |
207 | # url('new_gist') |
|
207 | # url('new_gist') | |
208 | self.__load_defaults() |
|
208 | self.__load_defaults() | |
209 |
return render('admin/gists/new. |
|
209 | return render('admin/gists/new.mako') | |
210 |
|
210 | |||
211 | @LoginRequired() |
|
211 | @LoginRequired() | |
212 | @NotAnonymous() |
|
212 | @NotAnonymous() | |
@@ -266,7 +266,7 b' class GistsController(BaseController):' | |||||
266 | if (f_path is None or f.path == f_path)]) |
|
266 | if (f_path is None or f.path == f_path)]) | |
267 | response.content_type = 'text/plain' |
|
267 | response.content_type = 'text/plain' | |
268 | return content |
|
268 | return content | |
269 |
return render('admin/gists/show. |
|
269 | return render('admin/gists/show.mako') | |
270 |
|
270 | |||
271 | @LoginRequired() |
|
271 | @LoginRequired() | |
272 | @NotAnonymous() |
|
272 | @NotAnonymous() | |
@@ -322,7 +322,9 b' class GistsController(BaseController):' | |||||
322 |
|
322 | |||
323 | @LoginRequired() |
|
323 | @LoginRequired() | |
324 | @NotAnonymous() |
|
324 | @NotAnonymous() | |
325 |
def edit_form(self, gist_id |
|
325 | def edit_form(self, gist_id): | |
|
326 | translate = _ = c.pyramid_request.translate | |||
|
327 | ||||
326 | """GET /admin/gists/gist_id/edit: Form to edit an existing item""" |
|
328 | """GET /admin/gists/gist_id/edit: Form to edit an existing item""" | |
327 | # url('edit_gist', gist_id=ID) |
|
329 | # url('edit_gist', gist_id=ID) | |
328 | self._add_gist_to_context(gist_id) |
|
330 | self._add_gist_to_context(gist_id) | |
@@ -342,9 +344,11 b' class GistsController(BaseController):' | |||||
342 | else: |
|
344 | else: | |
343 | # this cannot use timeago, since it's used in select2 as a value |
|
345 | # this cannot use timeago, since it's used in select2 as a value | |
344 | expiry = h.age(h.time_to_datetime(c.gist.gist_expires)) |
|
346 | expiry = h.age(h.time_to_datetime(c.gist.gist_expires)) | |
|
347 | ||||
|
348 | expiry = translate(expiry) | |||
345 | self.__load_defaults( |
|
349 | self.__load_defaults( | |
346 | extra_values=(0, _('%(expiry)s - current value') % {'expiry': expiry})) |
|
350 | extra_values=(0, _('%(expiry)s - current value') % {'expiry': expiry})) | |
347 |
return render('admin/gists/edit. |
|
351 | return render('admin/gists/edit.mako') | |
348 |
|
352 | |||
349 | @LoginRequired() |
|
353 | @LoginRequired() | |
350 | @NotAnonymous() |
|
354 | @NotAnonymous() |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2013-201 |
|
3 | # Copyright (C) 2013-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -24,13 +24,16 b' my account controller for RhodeCode admi' | |||||
24 | """ |
|
24 | """ | |
25 |
|
25 | |||
26 | import logging |
|
26 | import logging | |
|
27 | import datetime | |||
27 |
|
28 | |||
28 | import formencode |
|
29 | import formencode | |
29 | from formencode import htmlfill |
|
30 | from formencode import htmlfill | |
|
31 | from pyramid.threadlocal import get_current_registry | |||
30 | from pylons import request, tmpl_context as c, url, session |
|
32 | from pylons import request, tmpl_context as c, url, session | |
31 | from pylons.controllers.util import redirect |
|
33 | from pylons.controllers.util import redirect | |
32 | from pylons.i18n.translation import _ |
|
34 | from pylons.i18n.translation import _ | |
33 | from sqlalchemy.orm import joinedload |
|
35 | from sqlalchemy.orm import joinedload | |
|
36 | from webob.exc import HTTPBadGateway | |||
34 |
|
37 | |||
35 | from rhodecode import forms |
|
38 | from rhodecode import forms | |
36 | from rhodecode.lib import helpers as h |
|
39 | from rhodecode.lib import helpers as h | |
@@ -41,6 +44,8 b' from rhodecode.lib.base import BaseContr' | |||||
41 | from rhodecode.lib.utils import jsonify |
|
44 | from rhodecode.lib.utils import jsonify | |
42 | from rhodecode.lib.utils2 import safe_int, md5, str2bool |
|
45 | from rhodecode.lib.utils2 import safe_int, md5, str2bool | |
43 | from rhodecode.lib.ext_json import json |
|
46 | from rhodecode.lib.ext_json import json | |
|
47 | from rhodecode.lib.channelstream import channelstream_request, \ | |||
|
48 | ChannelstreamException | |||
44 |
|
49 | |||
45 | from rhodecode.model.validation_schema.schemas import user_schema |
|
50 | from rhodecode.model.validation_schema.schemas import user_schema | |
46 | from rhodecode.model.db import ( |
|
51 | from rhodecode.model.db import ( | |
@@ -52,7 +57,7 b' from rhodecode.model.repo import RepoMod' | |||||
52 | from rhodecode.model.auth_token import AuthTokenModel |
|
57 | from rhodecode.model.auth_token import AuthTokenModel | |
53 | from rhodecode.model.meta import Session |
|
58 | from rhodecode.model.meta import Session | |
54 | from rhodecode.model.pull_request import PullRequestModel |
|
59 | from rhodecode.model.pull_request import PullRequestModel | |
55 |
from rhodecode.model.comment import |
|
60 | from rhodecode.model.comment import CommentsModel | |
56 |
|
61 | |||
57 | log = logging.getLogger(__name__) |
|
62 | log = logging.getLogger(__name__) | |
58 |
|
63 | |||
@@ -76,6 +81,9 b' class MyAccountController(BaseController' | |||||
76 | " crucial for entire application"), category='warning') |
|
81 | " crucial for entire application"), category='warning') | |
77 | return redirect(url('users')) |
|
82 | return redirect(url('users')) | |
78 |
|
83 | |||
|
84 | c.auth_user = AuthUser( | |||
|
85 | user_id=c.rhodecode_user.user_id, ip_addr=self.ip_addr) | |||
|
86 | ||||
79 | def _load_my_repos_data(self, watched=False): |
|
87 | def _load_my_repos_data(self, watched=False): | |
80 | if watched: |
|
88 | if watched: | |
81 | admin = False |
|
89 | admin = False | |
@@ -104,8 +112,7 b' class MyAccountController(BaseController' | |||||
104 | # url('my_account') |
|
112 | # url('my_account') | |
105 | c.active = 'profile_edit' |
|
113 | c.active = 'profile_edit' | |
106 | self.__load_data() |
|
114 | self.__load_data() | |
107 |
c.perm_user = |
|
115 | c.perm_user = c.auth_user | |
108 | ip_addr=self.ip_addr) |
|
|||
109 | c.extern_type = c.user.extern_type |
|
116 | c.extern_type = c.user.extern_type | |
110 | c.extern_name = c.user.extern_name |
|
117 | c.extern_name = c.user.extern_name | |
111 |
|
118 | |||
@@ -137,7 +144,7 b' class MyAccountController(BaseController' | |||||
137 |
|
144 | |||
138 | except formencode.Invalid as errors: |
|
145 | except formencode.Invalid as errors: | |
139 | return htmlfill.render( |
|
146 | return htmlfill.render( | |
140 |
render('admin/my_account/my_account. |
|
147 | render('admin/my_account/my_account.mako'), | |
141 | defaults=errors.value, |
|
148 | defaults=errors.value, | |
142 | errors=errors.error_dict or {}, |
|
149 | errors=errors.error_dict or {}, | |
143 | prefix_error=False, |
|
150 | prefix_error=False, | |
@@ -152,7 +159,7 b' class MyAccountController(BaseController' | |||||
152 | return redirect('my_account') |
|
159 | return redirect('my_account') | |
153 |
|
160 | |||
154 | return htmlfill.render( |
|
161 | return htmlfill.render( | |
155 |
render('admin/my_account/my_account. |
|
162 | render('admin/my_account/my_account.mako'), | |
156 | defaults=defaults, |
|
163 | defaults=defaults, | |
157 | encoding="UTF-8", |
|
164 | encoding="UTF-8", | |
158 | force_defaults=False |
|
165 | force_defaults=False | |
@@ -168,7 +175,7 b' class MyAccountController(BaseController' | |||||
168 |
|
175 | |||
169 | defaults = c.user.get_dict() |
|
176 | defaults = c.user.get_dict() | |
170 | return htmlfill.render( |
|
177 | return htmlfill.render( | |
171 |
render('admin/my_account/my_account. |
|
178 | render('admin/my_account/my_account.mako'), | |
172 | defaults=defaults, encoding="UTF-8", force_defaults=False) |
|
179 | defaults=defaults, encoding="UTF-8", force_defaults=False) | |
173 |
|
180 | |||
174 | def my_account_edit(self): |
|
181 | def my_account_edit(self): | |
@@ -177,14 +184,13 b' class MyAccountController(BaseController' | |||||
177 | """ |
|
184 | """ | |
178 | c.active = 'profile_edit' |
|
185 | c.active = 'profile_edit' | |
179 | self.__load_data() |
|
186 | self.__load_data() | |
180 |
c.perm_user = |
|
187 | c.perm_user = c.auth_user | |
181 | ip_addr=self.ip_addr) |
|
|||
182 | c.extern_type = c.user.extern_type |
|
188 | c.extern_type = c.user.extern_type | |
183 | c.extern_name = c.user.extern_name |
|
189 | c.extern_name = c.user.extern_name | |
184 |
|
190 | |||
185 | defaults = c.user.get_dict() |
|
191 | defaults = c.user.get_dict() | |
186 | return htmlfill.render( |
|
192 | return htmlfill.render( | |
187 |
render('admin/my_account/my_account. |
|
193 | render('admin/my_account/my_account.mako'), | |
188 | defaults=defaults, |
|
194 | defaults=defaults, | |
189 | encoding="UTF-8", |
|
195 | encoding="UTF-8", | |
190 | force_defaults=False |
|
196 | force_defaults=False | |
@@ -194,6 +200,7 b' class MyAccountController(BaseController' | |||||
194 | def my_account_password(self): |
|
200 | def my_account_password(self): | |
195 | c.active = 'password' |
|
201 | c.active = 'password' | |
196 | self.__load_data() |
|
202 | self.__load_data() | |
|
203 | c.extern_type = c.user.extern_type | |||
197 |
|
204 | |||
198 | schema = user_schema.ChangePasswordSchema().bind( |
|
205 | schema = user_schema.ChangePasswordSchema().bind( | |
199 | username=c.rhodecode_user.username) |
|
206 | username=c.rhodecode_user.username) | |
@@ -201,7 +208,7 b' class MyAccountController(BaseController' | |||||
201 | form = forms.Form(schema, |
|
208 | form = forms.Form(schema, | |
202 | buttons=(forms.buttons.save, forms.buttons.reset)) |
|
209 | buttons=(forms.buttons.save, forms.buttons.reset)) | |
203 |
|
210 | |||
204 | if request.method == 'POST': |
|
211 | if request.method == 'POST' and c.extern_type == 'rhodecode': | |
205 | controls = request.POST.items() |
|
212 | controls = request.POST.items() | |
206 | try: |
|
213 | try: | |
207 | valid_data = form.validate(controls) |
|
214 | valid_data = form.validate(controls) | |
@@ -228,7 +235,7 b' class MyAccountController(BaseController' | |||||
228 | return redirect(url('my_account_password')) |
|
235 | return redirect(url('my_account_password')) | |
229 |
|
236 | |||
230 | c.form = form |
|
237 | c.form = form | |
231 |
return render('admin/my_account/my_account. |
|
238 | return render('admin/my_account/my_account.mako') | |
232 |
|
239 | |||
233 | def my_account_repos(self): |
|
240 | def my_account_repos(self): | |
234 | c.active = 'repos' |
|
241 | c.active = 'repos' | |
@@ -236,7 +243,7 b' class MyAccountController(BaseController' | |||||
236 |
|
243 | |||
237 | # json used to render the grid |
|
244 | # json used to render the grid | |
238 | c.data = self._load_my_repos_data() |
|
245 | c.data = self._load_my_repos_data() | |
239 |
return render('admin/my_account/my_account. |
|
246 | return render('admin/my_account/my_account.mako') | |
240 |
|
247 | |||
241 | def my_account_watched(self): |
|
248 | def my_account_watched(self): | |
242 | c.active = 'watched' |
|
249 | c.active = 'watched' | |
@@ -244,15 +251,14 b' class MyAccountController(BaseController' | |||||
244 |
|
251 | |||
245 | # json used to render the grid |
|
252 | # json used to render the grid | |
246 | c.data = self._load_my_repos_data(watched=True) |
|
253 | c.data = self._load_my_repos_data(watched=True) | |
247 |
return render('admin/my_account/my_account. |
|
254 | return render('admin/my_account/my_account.mako') | |
248 |
|
255 | |||
249 | def my_account_perms(self): |
|
256 | def my_account_perms(self): | |
250 | c.active = 'perms' |
|
257 | c.active = 'perms' | |
251 | self.__load_data() |
|
258 | self.__load_data() | |
252 |
c.perm_user = |
|
259 | c.perm_user = c.auth_user | |
253 | ip_addr=self.ip_addr) |
|
|||
254 |
|
260 | |||
255 |
return render('admin/my_account/my_account. |
|
261 | return render('admin/my_account/my_account.mako') | |
256 |
|
262 | |||
257 | def my_account_emails(self): |
|
263 | def my_account_emails(self): | |
258 | c.active = 'emails' |
|
264 | c.active = 'emails' | |
@@ -260,7 +266,7 b' class MyAccountController(BaseController' | |||||
260 |
|
266 | |||
261 | c.user_email_map = UserEmailMap.query()\ |
|
267 | c.user_email_map = UserEmailMap.query()\ | |
262 | .filter(UserEmailMap.user == c.user).all() |
|
268 | .filter(UserEmailMap.user == c.user).all() | |
263 |
return render('admin/my_account/my_account. |
|
269 | return render('admin/my_account/my_account.mako') | |
264 |
|
270 | |||
265 | @auth.CSRFRequired() |
|
271 | @auth.CSRFRequired() | |
266 | def my_account_emails_add(self): |
|
272 | def my_account_emails_add(self): | |
@@ -312,11 +318,11 b' class MyAccountController(BaseController' | |||||
312 | user_id=c.rhodecode_user.user_id, statuses=statuses) |
|
318 | user_id=c.rhodecode_user.user_id, statuses=statuses) | |
313 |
|
319 | |||
314 | from rhodecode.lib.utils import PartialRenderer |
|
320 | from rhodecode.lib.utils import PartialRenderer | |
315 |
_render = PartialRenderer('data_table/_dt_elements. |
|
321 | _render = PartialRenderer('data_table/_dt_elements.mako') | |
316 | data = [] |
|
322 | data = [] | |
317 | for pr in pull_requests: |
|
323 | for pr in pull_requests: | |
318 | repo_id = pr.target_repo_id |
|
324 | repo_id = pr.target_repo_id | |
319 |
comments = |
|
325 | comments = CommentsModel().get_all_comments( | |
320 | repo_id, pull_request=pr) |
|
326 | repo_id, pull_request=pr) | |
321 | owned = pr.user_id == c.rhodecode_user.user_id |
|
327 | owned = pr.user_id == c.rhodecode_user.user_id | |
322 | status = pr.calculated_review_status() |
|
328 | status = pr.calculated_review_status() | |
@@ -366,7 +372,7 b' class MyAccountController(BaseController' | |||||
366 | if not request.is_xhr: |
|
372 | if not request.is_xhr: | |
367 | c.data_participate = json.dumps(data['data']) |
|
373 | c.data_participate = json.dumps(data['data']) | |
368 | c.records_total_participate = data['recordsTotal'] |
|
374 | c.records_total_participate = data['recordsTotal'] | |
369 |
return render('admin/my_account/my_account. |
|
375 | return render('admin/my_account/my_account.mako') | |
370 | else: |
|
376 | else: | |
371 | return json.dumps(data) |
|
377 | return json.dumps(data) | |
372 |
|
378 | |||
@@ -387,7 +393,7 b' class MyAccountController(BaseController' | |||||
387 | c.role_options = [(c.role_values, _("Role"))] |
|
393 | c.role_options = [(c.role_values, _("Role"))] | |
388 | c.user_auth_tokens = AuthTokenModel().get_auth_tokens( |
|
394 | c.user_auth_tokens = AuthTokenModel().get_auth_tokens( | |
389 | c.rhodecode_user.user_id, show_expired=show_expired) |
|
395 | c.rhodecode_user.user_id, show_expired=show_expired) | |
390 |
return render('admin/my_account/my_account. |
|
396 | return render('admin/my_account/my_account.mako') | |
391 |
|
397 | |||
392 | @auth.CSRFRequired() |
|
398 | @auth.CSRFRequired() | |
393 | def my_account_auth_tokens_add(self): |
|
399 | def my_account_auth_tokens_add(self): | |
@@ -420,7 +426,7 b' class MyAccountController(BaseController' | |||||
420 |
|
426 | |||
421 | def my_notifications(self): |
|
427 | def my_notifications(self): | |
422 | c.active = 'notifications' |
|
428 | c.active = 'notifications' | |
423 |
return render('admin/my_account/my_account. |
|
429 | return render('admin/my_account/my_account.mako') | |
424 |
|
430 | |||
425 | @auth.CSRFRequired() |
|
431 | @auth.CSRFRequired() | |
426 | @jsonify |
|
432 | @jsonify | |
@@ -430,3 +436,33 b' class MyAccountController(BaseController' | |||||
430 | user.update_userdata(notification_status=new_status) |
|
436 | user.update_userdata(notification_status=new_status) | |
431 | Session().commit() |
|
437 | Session().commit() | |
432 | return user.user_data['notification_status'] |
|
438 | return user.user_data['notification_status'] | |
|
439 | ||||
|
440 | @auth.CSRFRequired() | |||
|
441 | @jsonify | |||
|
442 | def my_account_notifications_test_channelstream(self): | |||
|
443 | message = 'Test message sent via Channelstream by user: {}, on {}'.format( | |||
|
444 | c.rhodecode_user.username, datetime.datetime.now()) | |||
|
445 | payload = { | |||
|
446 | 'type': 'message', | |||
|
447 | 'timestamp': datetime.datetime.utcnow(), | |||
|
448 | 'user': 'system', | |||
|
449 | #'channel': 'broadcast', | |||
|
450 | 'pm_users': [c.rhodecode_user.username], | |||
|
451 | 'message': { | |||
|
452 | 'message': message, | |||
|
453 | 'level': 'info', | |||
|
454 | 'topic': '/notifications' | |||
|
455 | } | |||
|
456 | } | |||
|
457 | ||||
|
458 | registry = get_current_registry() | |||
|
459 | rhodecode_plugins = getattr(registry, 'rhodecode_plugins', {}) | |||
|
460 | channelstream_config = rhodecode_plugins.get('channelstream', {}) | |||
|
461 | ||||
|
462 | try: | |||
|
463 | channelstream_request(channelstream_config, [payload], '/message') | |||
|
464 | except ChannelstreamException as e: | |||
|
465 | log.exception('Failed to send channelstream data') | |||
|
466 | return {"response": 'ERROR: {}'.format(e.__class__.__name__)} | |||
|
467 | return {"response": 'Channelstream data sent. ' | |||
|
468 | 'You should see a new live message now.'} |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -82,9 +82,9 b' class NotificationsController(BaseContro' | |||||
82 | c.current_filter = 'comment' |
|
82 | c.current_filter = 'comment' | |
83 |
|
83 | |||
84 | if request.is_xhr: |
|
84 | if request.is_xhr: | |
85 |
return render('admin/notifications/notifications_data. |
|
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 | @auth.CSRFRequired() |
|
90 | @auth.CSRFRequired() | |
@@ -102,7 +102,7 b' class NotificationsController(BaseContro' | |||||
102 | url('notifications'), request.GET) |
|
102 | url('notifications'), request.GET) | |
103 | c.notifications = Page(notif, page=1, items_per_page=10, |
|
103 | c.notifications = Page(notif, page=1, items_per_page=10, | |
104 | url=notifications_url) |
|
104 | url=notifications_url) | |
105 |
return render('admin/notifications/notifications_data. |
|
105 | return render('admin/notifications/notifications_data.mako') | |
106 |
|
106 | |||
107 | def _has_permissions(self, notification): |
|
107 | def _has_permissions(self, notification): | |
108 | def is_owner(): |
|
108 | def is_owner(): | |
@@ -173,6 +173,6 b' class NotificationsController(BaseContro' | |||||
173 | Session().commit() |
|
173 | Session().commit() | |
174 | c.notification = no |
|
174 | c.notification = no | |
175 |
|
175 | |||
176 |
return render('admin/notifications/show_notification. |
|
176 | return render('admin/notifications/show_notification.mako') | |
177 |
|
177 | |||
178 | return abort(403) |
|
178 | return abort(403) |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -80,7 +80,7 b' class PermissionsController(BaseControll' | |||||
80 | defaults.update(c.user.get_default_perms()) |
|
80 | defaults.update(c.user.get_default_perms()) | |
81 |
|
81 | |||
82 | return htmlfill.render( |
|
82 | return htmlfill.render( | |
83 |
render('admin/permissions/permissions. |
|
83 | render('admin/permissions/permissions.mako'), | |
84 | defaults=defaults, |
|
84 | defaults=defaults, | |
85 | encoding="UTF-8", |
|
85 | encoding="UTF-8", | |
86 | force_defaults=False) |
|
86 | force_defaults=False) | |
@@ -116,7 +116,7 b' class PermissionsController(BaseControll' | |||||
116 | defaults = errors.value |
|
116 | defaults = errors.value | |
117 |
|
117 | |||
118 | return htmlfill.render( |
|
118 | return htmlfill.render( | |
119 |
render('admin/permissions/permissions. |
|
119 | render('admin/permissions/permissions.mako'), | |
120 | defaults=defaults, |
|
120 | defaults=defaults, | |
121 | errors=errors.error_dict or {}, |
|
121 | errors=errors.error_dict or {}, | |
122 | prefix_error=False, |
|
122 | prefix_error=False, | |
@@ -137,7 +137,7 b' class PermissionsController(BaseControll' | |||||
137 | defaults = {} |
|
137 | defaults = {} | |
138 | defaults.update(c.user.get_default_perms()) |
|
138 | defaults.update(c.user.get_default_perms()) | |
139 | return htmlfill.render( |
|
139 | return htmlfill.render( | |
140 |
render('admin/permissions/permissions. |
|
140 | render('admin/permissions/permissions.mako'), | |
141 | defaults=defaults, |
|
141 | defaults=defaults, | |
142 | encoding="UTF-8", |
|
142 | encoding="UTF-8", | |
143 | force_defaults=False) |
|
143 | force_defaults=False) | |
@@ -165,7 +165,7 b' class PermissionsController(BaseControll' | |||||
165 | defaults = errors.value |
|
165 | defaults = errors.value | |
166 |
|
166 | |||
167 | return htmlfill.render( |
|
167 | return htmlfill.render( | |
168 |
render('admin/permissions/permissions. |
|
168 | render('admin/permissions/permissions.mako'), | |
169 | defaults=defaults, |
|
169 | defaults=defaults, | |
170 | errors=errors.error_dict or {}, |
|
170 | errors=errors.error_dict or {}, | |
171 | prefix_error=False, |
|
171 | prefix_error=False, | |
@@ -188,7 +188,7 b' class PermissionsController(BaseControll' | |||||
188 | defaults.update(c.user.get_default_perms()) |
|
188 | defaults.update(c.user.get_default_perms()) | |
189 |
|
189 | |||
190 | return htmlfill.render( |
|
190 | return htmlfill.render( | |
191 |
render('admin/permissions/permissions. |
|
191 | render('admin/permissions/permissions.mako'), | |
192 | defaults=defaults, |
|
192 | defaults=defaults, | |
193 | encoding="UTF-8", |
|
193 | encoding="UTF-8", | |
194 | force_defaults=False) |
|
194 | force_defaults=False) | |
@@ -219,7 +219,7 b' class PermissionsController(BaseControll' | |||||
219 | defaults = errors.value |
|
219 | defaults = errors.value | |
220 |
|
220 | |||
221 | return htmlfill.render( |
|
221 | return htmlfill.render( | |
222 |
render('admin/permissions/permissions. |
|
222 | render('admin/permissions/permissions.mako'), | |
223 | defaults=defaults, |
|
223 | defaults=defaults, | |
224 | errors=errors.error_dict or {}, |
|
224 | errors=errors.error_dict or {}, | |
225 | prefix_error=False, |
|
225 | prefix_error=False, | |
@@ -239,11 +239,11 b' class PermissionsController(BaseControll' | |||||
239 | c.user_ip_map = ( |
|
239 | c.user_ip_map = ( | |
240 | UserIpMap.query().filter(UserIpMap.user == c.user).all()) |
|
240 | UserIpMap.query().filter(UserIpMap.user == c.user).all()) | |
241 |
|
241 | |||
242 |
return render('admin/permissions/permissions. |
|
242 | return render('admin/permissions/permissions.mako') | |
243 |
|
243 | |||
244 | @HasPermissionAllDecorator('hg.admin') |
|
244 | @HasPermissionAllDecorator('hg.admin') | |
245 | def permission_perms(self): |
|
245 | def permission_perms(self): | |
246 | c.active = 'perms' |
|
246 | c.active = 'perms' | |
247 | c.user = User.get_default_user() |
|
247 | c.user = User.get_default_user() | |
248 | c.perm_user = c.user.AuthUser |
|
248 | c.perm_user = c.user.AuthUser | |
249 |
return render('admin/permissions/permissions. |
|
249 | return render('admin/permissions/permissions.mako') |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -162,7 +162,7 b' class RepoGroupsController(BaseControlle' | |||||
162 | repo_group_data = RepoGroupModel().get_repo_groups_as_dict( |
|
162 | repo_group_data = RepoGroupModel().get_repo_groups_as_dict( | |
163 | repo_group_list=repo_group_list_acl, admin=True) |
|
163 | repo_group_list=repo_group_list_acl, admin=True) | |
164 | c.data = json.dumps(repo_group_data) |
|
164 | c.data = json.dumps(repo_group_data) | |
165 |
return render('admin/repo_groups/repo_groups. |
|
165 | return render('admin/repo_groups/repo_groups.mako') | |
166 |
|
166 | |||
167 | # perm checks inside |
|
167 | # perm checks inside | |
168 | @NotAnonymous() |
|
168 | @NotAnonymous() | |
@@ -199,7 +199,7 b' class RepoGroupsController(BaseControlle' | |||||
199 | # TODO: in futureaction_logger(, '', '', '', self.sa) |
|
199 | # TODO: in futureaction_logger(, '', '', '', self.sa) | |
200 | except formencode.Invalid as errors: |
|
200 | except formencode.Invalid as errors: | |
201 | return htmlfill.render( |
|
201 | return htmlfill.render( | |
202 |
render('admin/repo_groups/repo_group_add. |
|
202 | render('admin/repo_groups/repo_group_add.mako'), | |
203 | defaults=errors.value, |
|
203 | defaults=errors.value, | |
204 | errors=errors.error_dict or {}, |
|
204 | errors=errors.error_dict or {}, | |
205 | prefix_error=False, |
|
205 | prefix_error=False, | |
@@ -224,7 +224,7 b' class RepoGroupsController(BaseControlle' | |||||
224 | return abort(403) |
|
224 | return abort(403) | |
225 |
|
225 | |||
226 | self.__load_defaults() |
|
226 | self.__load_defaults() | |
227 |
return render('admin/repo_groups/repo_group_add. |
|
227 | return render('admin/repo_groups/repo_group_add.mako') | |
228 |
|
228 | |||
229 | @HasRepoGroupPermissionAnyDecorator('group.admin') |
|
229 | @HasRepoGroupPermissionAnyDecorator('group.admin') | |
230 | @auth.CSRFRequired() |
|
230 | @auth.CSRFRequired() | |
@@ -263,7 +263,7 b' class RepoGroupsController(BaseControlle' | |||||
263 | except formencode.Invalid as errors: |
|
263 | except formencode.Invalid as errors: | |
264 | c.active = 'settings' |
|
264 | c.active = 'settings' | |
265 | return htmlfill.render( |
|
265 | return htmlfill.render( | |
266 |
render('admin/repo_groups/repo_group_edit. |
|
266 | render('admin/repo_groups/repo_group_edit.mako'), | |
267 | defaults=errors.value, |
|
267 | defaults=errors.value, | |
268 | errors=errors.error_dict or {}, |
|
268 | errors=errors.error_dict or {}, | |
269 | prefix_error=False, |
|
269 | prefix_error=False, | |
@@ -338,7 +338,7 b' class RepoGroupsController(BaseControlle' | |||||
338 | defaults = self.__load_data(c.repo_group.group_id) |
|
338 | defaults = self.__load_data(c.repo_group.group_id) | |
339 |
|
339 | |||
340 | return htmlfill.render( |
|
340 | return htmlfill.render( | |
341 |
render('admin/repo_groups/repo_group_edit. |
|
341 | render('admin/repo_groups/repo_group_edit.mako'), | |
342 | defaults=defaults, |
|
342 | defaults=defaults, | |
343 | encoding="UTF-8", |
|
343 | encoding="UTF-8", | |
344 | force_defaults=False |
|
344 | force_defaults=False | |
@@ -351,7 +351,7 b' class RepoGroupsController(BaseControlle' | |||||
351 | c.active = 'advanced' |
|
351 | c.active = 'advanced' | |
352 | c.repo_group = RepoGroupModel()._get_repo_group(group_name) |
|
352 | c.repo_group = RepoGroupModel()._get_repo_group(group_name) | |
353 |
|
353 | |||
354 |
return render('admin/repo_groups/repo_group_edit. |
|
354 | return render('admin/repo_groups/repo_group_edit.mako') | |
355 |
|
355 | |||
356 | @HasRepoGroupPermissionAnyDecorator('group.admin') |
|
356 | @HasRepoGroupPermissionAnyDecorator('group.admin') | |
357 | def edit_repo_group_perms(self, group_name): |
|
357 | def edit_repo_group_perms(self, group_name): | |
@@ -363,7 +363,7 b' class RepoGroupsController(BaseControlle' | |||||
363 | defaults = self.__load_data(c.repo_group.group_id) |
|
363 | defaults = self.__load_data(c.repo_group.group_id) | |
364 |
|
364 | |||
365 | return htmlfill.render( |
|
365 | return htmlfill.render( | |
366 |
render('admin/repo_groups/repo_group_edit. |
|
366 | render('admin/repo_groups/repo_group_edit.mako'), | |
367 | defaults=defaults, |
|
367 | defaults=defaults, | |
368 | encoding="UTF-8", |
|
368 | encoding="UTF-8", | |
369 | force_defaults=False |
|
369 | force_defaults=False |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2013-201 |
|
3 | # Copyright (C) 2013-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -147,7 +147,7 b' class ReposController(BaseRepoController' | |||||
147 | # json used to render the grid |
|
147 | # json used to render the grid | |
148 | c.data = json.dumps(repos_data) |
|
148 | c.data = json.dumps(repos_data) | |
149 |
|
149 | |||
150 |
return render('admin/repos/repos. |
|
150 | return render('admin/repos/repos.mako') | |
151 |
|
151 | |||
152 | # perms check inside |
|
152 | # perms check inside | |
153 | @NotAnonymous() |
|
153 | @NotAnonymous() | |
@@ -175,7 +175,7 b' class ReposController(BaseRepoController' | |||||
175 | task_id = task.task_id |
|
175 | task_id = task.task_id | |
176 | except formencode.Invalid as errors: |
|
176 | except formencode.Invalid as errors: | |
177 | return htmlfill.render( |
|
177 | return htmlfill.render( | |
178 |
render('admin/repos/repo_add. |
|
178 | render('admin/repos/repo_add.mako'), | |
179 | defaults=errors.value, |
|
179 | defaults=errors.value, | |
180 | errors=errors.error_dict or {}, |
|
180 | errors=errors.error_dict or {}, | |
181 | prefix_error=False, |
|
181 | prefix_error=False, | |
@@ -235,7 +235,7 b' class ReposController(BaseRepoController' | |||||
235 | defaults.update({'repo_group': parent_group_choice}) |
|
235 | defaults.update({'repo_group': parent_group_choice}) | |
236 |
|
236 | |||
237 | return htmlfill.render( |
|
237 | return htmlfill.render( | |
238 |
render('admin/repos/repo_add. |
|
238 | render('admin/repos/repo_add.mako'), | |
239 | defaults=defaults, |
|
239 | defaults=defaults, | |
240 | errors={}, |
|
240 | errors={}, | |
241 | prefix_error=False, |
|
241 | prefix_error=False, | |
@@ -249,7 +249,7 b' class ReposController(BaseRepoController' | |||||
249 | c.task_id = request.GET.get('task_id') |
|
249 | c.task_id = request.GET.get('task_id') | |
250 | if not c.repo: |
|
250 | if not c.repo: | |
251 | raise HTTPNotFound() |
|
251 | raise HTTPNotFound() | |
252 |
return render('admin/repos/repo_creating. |
|
252 | return render('admin/repos/repo_creating.mako') | |
253 |
|
253 | |||
254 | @NotAnonymous() |
|
254 | @NotAnonymous() | |
255 | @jsonify |
|
255 | @jsonify | |
@@ -334,7 +334,7 b' class ReposController(BaseRepoController' | |||||
334 | defaults = self.__load_data(repo_name) |
|
334 | defaults = self.__load_data(repo_name) | |
335 | defaults.update(errors.value) |
|
335 | defaults.update(errors.value) | |
336 | return htmlfill.render( |
|
336 | return htmlfill.render( | |
337 |
render('admin/repos/repo_edit. |
|
337 | render('admin/repos/repo_edit.mako'), | |
338 | defaults=defaults, |
|
338 | defaults=defaults, | |
339 | errors=errors.error_dict or {}, |
|
339 | errors=errors.error_dict or {}, | |
340 | prefix_error=False, |
|
340 | prefix_error=False, | |
@@ -410,7 +410,7 b' class ReposController(BaseRepoController' | |||||
410 | c.personal_repo_group = c.rhodecode_user.personal_repo_group |
|
410 | c.personal_repo_group = c.rhodecode_user.personal_repo_group | |
411 | c.active = 'settings' |
|
411 | c.active = 'settings' | |
412 | return htmlfill.render( |
|
412 | return htmlfill.render( | |
413 |
render('admin/repos/repo_edit. |
|
413 | render('admin/repos/repo_edit.mako'), | |
414 | defaults=defaults, |
|
414 | defaults=defaults, | |
415 | encoding="UTF-8", |
|
415 | encoding="UTF-8", | |
416 | force_defaults=False) |
|
416 | force_defaults=False) | |
@@ -424,7 +424,7 b' class ReposController(BaseRepoController' | |||||
424 | defaults = RepoModel()._get_defaults(repo_name) |
|
424 | defaults = RepoModel()._get_defaults(repo_name) | |
425 |
|
425 | |||
426 | return htmlfill.render( |
|
426 | return htmlfill.render( | |
427 |
render('admin/repos/repo_edit. |
|
427 | render('admin/repos/repo_edit.mako'), | |
428 | defaults=defaults, |
|
428 | defaults=defaults, | |
429 | encoding="UTF-8", |
|
429 | encoding="UTF-8", | |
430 | force_defaults=False) |
|
430 | force_defaults=False) | |
@@ -454,7 +454,7 b' class ReposController(BaseRepoController' | |||||
454 | if request.POST: |
|
454 | if request.POST: | |
455 |
|
455 | |||
456 | return redirect(url('repo_edit_fields')) |
|
456 | return redirect(url('repo_edit_fields')) | |
457 |
return render('admin/repos/repo_edit. |
|
457 | return render('admin/repos/repo_edit.mako') | |
458 |
|
458 | |||
459 | @HasRepoPermissionAllDecorator('repository.admin') |
|
459 | @HasRepoPermissionAllDecorator('repository.admin') | |
460 | @auth.CSRFRequired() |
|
460 | @auth.CSRFRequired() | |
@@ -509,7 +509,7 b' class ReposController(BaseRepoController' | |||||
509 |
|
509 | |||
510 | if request.POST: |
|
510 | if request.POST: | |
511 | return redirect(url('repo_edit_advanced')) |
|
511 | return redirect(url('repo_edit_advanced')) | |
512 |
return render('admin/repos/repo_edit. |
|
512 | return render('admin/repos/repo_edit.mako') | |
513 |
|
513 | |||
514 | @HasRepoPermissionAllDecorator('repository.admin') |
|
514 | @HasRepoPermissionAllDecorator('repository.admin') | |
515 | @auth.CSRFRequired() |
|
515 | @auth.CSRFRequired() | |
@@ -642,7 +642,7 b' class ReposController(BaseRepoController' | |||||
642 | c.repo_info = self._load_repo(repo_name) |
|
642 | c.repo_info = self._load_repo(repo_name) | |
643 | c.active = 'caches' |
|
643 | c.active = 'caches' | |
644 |
|
644 | |||
645 |
return render('admin/repos/repo_edit. |
|
645 | return render('admin/repos/repo_edit.mako') | |
646 |
|
646 | |||
647 | @HasRepoPermissionAllDecorator('repository.admin') |
|
647 | @HasRepoPermissionAllDecorator('repository.admin') | |
648 | @auth.CSRFRequired() |
|
648 | @auth.CSRFRequired() | |
@@ -664,7 +664,7 b' class ReposController(BaseRepoController' | |||||
664 | c.repo_info = self._load_repo(repo_name) |
|
664 | c.repo_info = self._load_repo(repo_name) | |
665 | c.active = 'remote' |
|
665 | c.active = 'remote' | |
666 |
|
666 | |||
667 |
return render('admin/repos/repo_edit. |
|
667 | return render('admin/repos/repo_edit.mako') | |
668 |
|
668 | |||
669 | @HasRepoPermissionAllDecorator('repository.admin') |
|
669 | @HasRepoPermissionAllDecorator('repository.admin') | |
670 | @auth.CSRFRequired() |
|
670 | @auth.CSRFRequired() | |
@@ -702,7 +702,7 b' class ReposController(BaseRepoController' | |||||
702 |
|
702 | |||
703 | c.active = 'statistics' |
|
703 | c.active = 'statistics' | |
704 |
|
704 | |||
705 |
return render('admin/repos/repo_edit. |
|
705 | return render('admin/repos/repo_edit.mako') | |
706 |
|
706 | |||
707 | @HasRepoPermissionAllDecorator('repository.admin') |
|
707 | @HasRepoPermissionAllDecorator('repository.admin') | |
708 | @auth.CSRFRequired() |
|
708 | @auth.CSRFRequired() | |
@@ -771,7 +771,7 b' class ReposController(BaseRepoController' | |||||
771 | c.global_patterns = c.settings_model.get_global_settings() |
|
771 | c.global_patterns = c.settings_model.get_global_settings() | |
772 | c.repo_patterns = c.settings_model.get_repo_settings() |
|
772 | c.repo_patterns = c.settings_model.get_repo_settings() | |
773 |
|
773 | |||
774 |
return render('admin/repos/repo_edit. |
|
774 | return render('admin/repos/repo_edit.mako') | |
775 |
|
775 | |||
776 | @HasRepoPermissionAllDecorator('repository.admin') |
|
776 | @HasRepoPermissionAllDecorator('repository.admin') | |
777 | def repo_settings_vcs(self, repo_name): |
|
777 | def repo_settings_vcs(self, repo_name): | |
@@ -791,7 +791,7 b' class ReposController(BaseRepoController' | |||||
791 | rhodecode.CONFIG.get('labs_settings_active', 'true')) |
|
791 | rhodecode.CONFIG.get('labs_settings_active', 'true')) | |
792 |
|
792 | |||
793 | return htmlfill.render( |
|
793 | return htmlfill.render( | |
794 |
render('admin/repos/repo_edit. |
|
794 | render('admin/repos/repo_edit.mako'), | |
795 | defaults=defaults, |
|
795 | defaults=defaults, | |
796 | encoding="UTF-8", |
|
796 | encoding="UTF-8", | |
797 | force_defaults=False) |
|
797 | force_defaults=False) | |
@@ -819,7 +819,7 b' class ReposController(BaseRepoController' | |||||
819 | _("Some form inputs contain invalid data."), |
|
819 | _("Some form inputs contain invalid data."), | |
820 | category='error') |
|
820 | category='error') | |
821 | return htmlfill.render( |
|
821 | return htmlfill.render( | |
822 |
render('admin/repos/repo_edit. |
|
822 | render('admin/repos/repo_edit.mako'), | |
823 | defaults=errors.value, |
|
823 | defaults=errors.value, | |
824 | errors=errors.error_dict or {}, |
|
824 | errors=errors.error_dict or {}, | |
825 | prefix_error=False, |
|
825 | prefix_error=False, | |
@@ -842,7 +842,7 b' class ReposController(BaseRepoController' | |||||
842 | return redirect(url('repo_vcs_settings', repo_name=repo_name)) |
|
842 | return redirect(url('repo_vcs_settings', repo_name=repo_name)) | |
843 |
|
843 | |||
844 | return htmlfill.render( |
|
844 | return htmlfill.render( | |
845 |
render('admin/repos/repo_edit. |
|
845 | render('admin/repos/repo_edit.mako'), | |
846 | defaults=self._vcs_form_defaults(repo_name), |
|
846 | defaults=self._vcs_form_defaults(repo_name), | |
847 | encoding="UTF-8", |
|
847 | encoding="UTF-8", | |
848 | force_defaults=False) |
|
848 | force_defaults=False) |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -25,15 +25,13 b' settings controller for rhodecode admin' | |||||
25 |
|
25 | |||
26 | import collections |
|
26 | import collections | |
27 | import logging |
|
27 | import logging | |
28 | import urllib2 |
|
|||
29 |
|
28 | |||
30 | import datetime |
|
29 | import datetime | |
31 | import formencode |
|
30 | import formencode | |
32 | from formencode import htmlfill |
|
31 | from formencode import htmlfill | |
33 | import packaging.version |
|
|||
34 | from pylons import request, tmpl_context as c, url, config |
|
32 | from pylons import request, tmpl_context as c, url, config | |
35 | from pylons.controllers.util import redirect |
|
33 | from pylons.controllers.util import redirect | |
36 |
from pylons.i18n.translation import _ |
|
34 | from pylons.i18n.translation import _ | |
37 | from pyramid.threadlocal import get_current_registry |
|
35 | from pyramid.threadlocal import get_current_registry | |
38 | from webob.exc import HTTPBadRequest |
|
36 | from webob.exc import HTTPBadRequest | |
39 |
|
37 | |||
@@ -48,7 +46,6 b' from rhodecode.lib.utils import repo2db_' | |||||
48 | from rhodecode.lib.utils2 import ( |
|
46 | from rhodecode.lib.utils2 import ( | |
49 | str2bool, safe_unicode, AttributeDict, safe_int) |
|
47 | str2bool, safe_unicode, AttributeDict, safe_int) | |
50 | from rhodecode.lib.compat import OrderedDict |
|
48 | from rhodecode.lib.compat import OrderedDict | |
51 | from rhodecode.lib.ext_json import json |
|
|||
52 | from rhodecode.lib.utils import jsonify |
|
49 | from rhodecode.lib.utils import jsonify | |
53 |
|
50 | |||
54 | from rhodecode.model.db import RhodeCodeUi, Repository |
|
51 | from rhodecode.model.db import RhodeCodeUi, Repository | |
@@ -150,7 +147,7 b' class SettingsController(BaseController)' | |||||
150 | _("Some form inputs contain invalid data."), |
|
147 | _("Some form inputs contain invalid data."), | |
151 | category='error') |
|
148 | category='error') | |
152 | return htmlfill.render( |
|
149 | return htmlfill.render( | |
153 |
render('admin/settings/settings. |
|
150 | render('admin/settings/settings.mako'), | |
154 | defaults=errors.value, |
|
151 | defaults=errors.value, | |
155 | errors=errors.error_dict or {}, |
|
152 | errors=errors.error_dict or {}, | |
156 | prefix_error=False, |
|
153 | prefix_error=False, | |
@@ -179,7 +176,7 b' class SettingsController(BaseController)' | |||||
179 | return redirect(url('admin_settings_vcs')) |
|
176 | return redirect(url('admin_settings_vcs')) | |
180 |
|
177 | |||
181 | return htmlfill.render( |
|
178 | return htmlfill.render( | |
182 |
render('admin/settings/settings. |
|
179 | render('admin/settings/settings.mako'), | |
183 | defaults=self._form_defaults(), |
|
180 | defaults=self._form_defaults(), | |
184 | encoding="UTF-8", |
|
181 | encoding="UTF-8", | |
185 | force_defaults=False) |
|
182 | force_defaults=False) | |
@@ -198,7 +195,7 b' class SettingsController(BaseController)' | |||||
198 | c.svn_proxy_generate_config = pyramid_settings[generate_config] |
|
195 | c.svn_proxy_generate_config = pyramid_settings[generate_config] | |
199 |
|
196 | |||
200 | return htmlfill.render( |
|
197 | return htmlfill.render( | |
201 |
render('admin/settings/settings. |
|
198 | render('admin/settings/settings.mako'), | |
202 | defaults=self._form_defaults(), |
|
199 | defaults=self._form_defaults(), | |
203 | encoding="UTF-8", |
|
200 | encoding="UTF-8", | |
204 | force_defaults=False) |
|
201 | force_defaults=False) | |
@@ -235,7 +232,7 b' class SettingsController(BaseController)' | |||||
235 | c.active = 'mapping' |
|
232 | c.active = 'mapping' | |
236 |
|
233 | |||
237 | return htmlfill.render( |
|
234 | return htmlfill.render( | |
238 |
render('admin/settings/settings. |
|
235 | render('admin/settings/settings.mako'), | |
239 | defaults=self._form_defaults(), |
|
236 | defaults=self._form_defaults(), | |
240 | encoding="UTF-8", |
|
237 | encoding="UTF-8", | |
241 | force_defaults=False) |
|
238 | force_defaults=False) | |
@@ -253,7 +250,7 b' class SettingsController(BaseController)' | |||||
253 | form_result = application_form.to_python(dict(request.POST)) |
|
250 | form_result = application_form.to_python(dict(request.POST)) | |
254 | except formencode.Invalid as errors: |
|
251 | except formencode.Invalid as errors: | |
255 | return htmlfill.render( |
|
252 | return htmlfill.render( | |
256 |
render('admin/settings/settings. |
|
253 | render('admin/settings/settings.mako'), | |
257 | defaults=errors.value, |
|
254 | defaults=errors.value, | |
258 | errors=errors.error_dict or {}, |
|
255 | errors=errors.error_dict or {}, | |
259 | prefix_error=False, |
|
256 | prefix_error=False, | |
@@ -296,7 +293,7 b' class SettingsController(BaseController)' | |||||
296 | .get_personal_group_name_pattern() |
|
293 | .get_personal_group_name_pattern() | |
297 |
|
294 | |||
298 | return htmlfill.render( |
|
295 | return htmlfill.render( | |
299 |
render('admin/settings/settings. |
|
296 | render('admin/settings/settings.mako'), | |
300 | defaults=self._form_defaults(), |
|
297 | defaults=self._form_defaults(), | |
301 | encoding="UTF-8", |
|
298 | encoding="UTF-8", | |
302 | force_defaults=False) |
|
299 | force_defaults=False) | |
@@ -312,7 +309,7 b' class SettingsController(BaseController)' | |||||
312 | form_result = application_form.to_python(dict(request.POST)) |
|
309 | form_result = application_form.to_python(dict(request.POST)) | |
313 | except formencode.Invalid as errors: |
|
310 | except formencode.Invalid as errors: | |
314 | return htmlfill.render( |
|
311 | return htmlfill.render( | |
315 |
render('admin/settings/settings. |
|
312 | render('admin/settings/settings.mako'), | |
316 | defaults=errors.value, |
|
313 | defaults=errors.value, | |
317 | errors=errors.error_dict or {}, |
|
314 | errors=errors.error_dict or {}, | |
318 | prefix_error=False, |
|
315 | prefix_error=False, | |
@@ -360,7 +357,7 b' class SettingsController(BaseController)' | |||||
360 | c.active = 'visual' |
|
357 | c.active = 'visual' | |
361 |
|
358 | |||
362 | return htmlfill.render( |
|
359 | return htmlfill.render( | |
363 |
render('admin/settings/settings. |
|
360 | render('admin/settings/settings.mako'), | |
364 | defaults=self._form_defaults(), |
|
361 | defaults=self._form_defaults(), | |
365 | encoding="UTF-8", |
|
362 | encoding="UTF-8", | |
366 | force_defaults=False) |
|
363 | force_defaults=False) | |
@@ -406,7 +403,7 b' class SettingsController(BaseController)' | |||||
406 | 'desc': defaults.get('rhodecode_issuetracker_desc_' + uid), |
|
403 | 'desc': defaults.get('rhodecode_issuetracker_desc_' + uid), | |
407 | }) |
|
404 | }) | |
408 |
|
405 | |||
409 |
return render('admin/settings/settings. |
|
406 | return render('admin/settings/settings.mako') | |
410 |
|
407 | |||
411 | @HasPermissionAllDecorator('hg.admin') |
|
408 | @HasPermissionAllDecorator('hg.admin') | |
412 | @auth.CSRFRequired() |
|
409 | @auth.CSRFRequired() | |
@@ -469,7 +466,7 b' class SettingsController(BaseController)' | |||||
469 | c.rhodecode_ini = rhodecode.CONFIG |
|
466 | c.rhodecode_ini = rhodecode.CONFIG | |
470 |
|
467 | |||
471 | return htmlfill.render( |
|
468 | return htmlfill.render( | |
472 |
render('admin/settings/settings. |
|
469 | render('admin/settings/settings.mako'), | |
473 | defaults=self._form_defaults(), |
|
470 | defaults=self._form_defaults(), | |
474 | encoding="UTF-8", |
|
471 | encoding="UTF-8", | |
475 | force_defaults=False) |
|
472 | force_defaults=False) | |
@@ -526,7 +523,7 b' class SettingsController(BaseController)' | |||||
526 | c.custom_hooks = model.get_custom_hooks() |
|
523 | c.custom_hooks = model.get_custom_hooks() | |
527 |
|
524 | |||
528 | return htmlfill.render( |
|
525 | return htmlfill.render( | |
529 |
render('admin/settings/settings. |
|
526 | render('admin/settings/settings.mako'), | |
530 | defaults=self._form_defaults(), |
|
527 | defaults=self._form_defaults(), | |
531 | encoding="UTF-8", |
|
528 | encoding="UTF-8", | |
532 | force_defaults=False) |
|
529 | force_defaults=False) | |
@@ -541,154 +538,7 b' class SettingsController(BaseController)' | |||||
541 | searcher = searcher_from_config(config) |
|
538 | searcher = searcher_from_config(config) | |
542 | c.statistics = searcher.statistics() |
|
539 | c.statistics = searcher.statistics() | |
543 |
|
540 | |||
544 |
return render('admin/settings/settings. |
|
541 | return render('admin/settings/settings.mako') | |
545 |
|
||||
546 | @HasPermissionAllDecorator('hg.admin') |
|
|||
547 | def settings_system(self): |
|
|||
548 | """GET /admin/settings/system: All items in the collection""" |
|
|||
549 | # url('admin_settings_system') |
|
|||
550 | snapshot = str2bool(request.GET.get('snapshot')) |
|
|||
551 | defaults = self._form_defaults() |
|
|||
552 |
|
||||
553 | c.active = 'system' |
|
|||
554 | c.rhodecode_update_url = defaults.get('rhodecode_update_url') |
|
|||
555 | server_info = ScmModel().get_server_info(request.environ) |
|
|||
556 |
|
||||
557 | for key, val in server_info.iteritems(): |
|
|||
558 | setattr(c, key, val) |
|
|||
559 |
|
||||
560 | def val(name, subkey='human_value'): |
|
|||
561 | return server_info[name][subkey] |
|
|||
562 |
|
||||
563 | def state(name): |
|
|||
564 | return server_info[name]['state'] |
|
|||
565 |
|
||||
566 | def val2(name): |
|
|||
567 | val = server_info[name]['human_value'] |
|
|||
568 | state = server_info[name]['state'] |
|
|||
569 | return val, state |
|
|||
570 |
|
||||
571 | c.data_items = [ |
|
|||
572 | # update info |
|
|||
573 | (_('Update info'), h.literal( |
|
|||
574 | '<span class="link" id="check_for_update" >%s.</span>' % ( |
|
|||
575 | _('Check for updates')) + |
|
|||
576 | '<br/> <span >%s.</span>' % (_('Note: please make sure this server can access `%s` for the update link to work') % c.rhodecode_update_url) |
|
|||
577 | ), ''), |
|
|||
578 |
|
||||
579 | # RhodeCode specific |
|
|||
580 | (_('RhodeCode Version'), val('rhodecode_app')['text'], state('rhodecode_app')), |
|
|||
581 | (_('RhodeCode Server IP'), val('server')['server_ip'], state('server')), |
|
|||
582 | (_('RhodeCode Server ID'), val('server')['server_id'], state('server')), |
|
|||
583 | (_('RhodeCode Configuration'), val('rhodecode_config')['path'], state('rhodecode_config')), |
|
|||
584 | ('', '', ''), # spacer |
|
|||
585 |
|
||||
586 | # Database |
|
|||
587 | (_('Database'), val('database')['url'], state('database')), |
|
|||
588 | (_('Database version'), val('database')['version'], state('database')), |
|
|||
589 | ('', '', ''), # spacer |
|
|||
590 |
|
||||
591 | # Platform/Python |
|
|||
592 | (_('Platform'), val('platform')['name'], state('platform')), |
|
|||
593 | (_('Platform UUID'), val('platform')['uuid'], state('platform')), |
|
|||
594 | (_('Python version'), val('python')['version'], state('python')), |
|
|||
595 | (_('Python path'), val('python')['executable'], state('python')), |
|
|||
596 | ('', '', ''), # spacer |
|
|||
597 |
|
||||
598 | # Systems stats |
|
|||
599 | (_('CPU'), val('cpu'), state('cpu')), |
|
|||
600 | (_('Load'), val('load')['text'], state('load')), |
|
|||
601 | (_('Memory'), val('memory')['text'], state('memory')), |
|
|||
602 | (_('Uptime'), val('uptime')['text'], state('uptime')), |
|
|||
603 | ('', '', ''), # spacer |
|
|||
604 |
|
||||
605 | # Repo storage |
|
|||
606 | (_('Storage location'), val('storage')['path'], state('storage')), |
|
|||
607 | (_('Storage info'), val('storage')['text'], state('storage')), |
|
|||
608 | (_('Storage inodes'), val('storage_inodes')['text'], state('storage_inodes')), |
|
|||
609 |
|
||||
610 | (_('Gist storage location'), val('storage_gist')['path'], state('storage_gist')), |
|
|||
611 | (_('Gist storage info'), val('storage_gist')['text'], state('storage_gist')), |
|
|||
612 |
|
||||
613 | (_('Archive cache storage location'), val('storage_archive')['path'], state('storage_archive')), |
|
|||
614 | (_('Archive cache info'), val('storage_archive')['text'], state('storage_archive')), |
|
|||
615 |
|
||||
616 | (_('Temp storage location'), val('storage_temp')['path'], state('storage_temp')), |
|
|||
617 | (_('Temp storage info'), val('storage_temp')['text'], state('storage_temp')), |
|
|||
618 |
|
||||
619 | (_('Search info'), val('search')['text'], state('search')), |
|
|||
620 | (_('Search location'), val('search')['location'], state('search')), |
|
|||
621 | ('', '', ''), # spacer |
|
|||
622 |
|
||||
623 | # VCS specific |
|
|||
624 | (_('VCS Backends'), val('vcs_backends'), state('vcs_backends')), |
|
|||
625 | (_('VCS Server'), val('vcs_server')['text'], state('vcs_server')), |
|
|||
626 | (_('GIT'), val('git'), state('git')), |
|
|||
627 | (_('HG'), val('hg'), state('hg')), |
|
|||
628 | (_('SVN'), val('svn'), state('svn')), |
|
|||
629 |
|
||||
630 | ] |
|
|||
631 |
|
||||
632 | # TODO: marcink, figure out how to allow only selected users to do this |
|
|||
633 | c.allowed_to_snapshot = c.rhodecode_user.admin |
|
|||
634 |
|
||||
635 | if snapshot: |
|
|||
636 | if c.allowed_to_snapshot: |
|
|||
637 | c.data_items.pop(0) # remove server info |
|
|||
638 | return render('admin/settings/settings_system_snapshot.html') |
|
|||
639 | else: |
|
|||
640 | h.flash('You are not allowed to do this', category='warning') |
|
|||
641 |
|
||||
642 | return htmlfill.render( |
|
|||
643 | render('admin/settings/settings.html'), |
|
|||
644 | defaults=defaults, |
|
|||
645 | encoding="UTF-8", |
|
|||
646 | force_defaults=False) |
|
|||
647 |
|
||||
648 | @staticmethod |
|
|||
649 | def get_update_data(update_url): |
|
|||
650 | """Return the JSON update data.""" |
|
|||
651 | ver = rhodecode.__version__ |
|
|||
652 | log.debug('Checking for upgrade on `%s` server', update_url) |
|
|||
653 | opener = urllib2.build_opener() |
|
|||
654 | opener.addheaders = [('User-agent', 'RhodeCode-SCM/%s' % ver)] |
|
|||
655 | response = opener.open(update_url) |
|
|||
656 | response_data = response.read() |
|
|||
657 | data = json.loads(response_data) |
|
|||
658 |
|
||||
659 | return data |
|
|||
660 |
|
||||
661 | @HasPermissionAllDecorator('hg.admin') |
|
|||
662 | def settings_system_update(self): |
|
|||
663 | """GET /admin/settings/system/updates: All items in the collection""" |
|
|||
664 | # url('admin_settings_system_update') |
|
|||
665 | defaults = self._form_defaults() |
|
|||
666 | update_url = defaults.get('rhodecode_update_url', '') |
|
|||
667 |
|
||||
668 | _err = lambda s: '<div style="color:#ff8888; padding:4px 0px">%s</div>' % (s) |
|
|||
669 | try: |
|
|||
670 | data = self.get_update_data(update_url) |
|
|||
671 | except urllib2.URLError as e: |
|
|||
672 | log.exception("Exception contacting upgrade server") |
|
|||
673 | return _err('Failed to contact upgrade server: %r' % e) |
|
|||
674 | except ValueError as e: |
|
|||
675 | log.exception("Bad data sent from update server") |
|
|||
676 | return _err('Bad data sent from update server') |
|
|||
677 |
|
||||
678 | latest = data['versions'][0] |
|
|||
679 |
|
||||
680 | c.update_url = update_url |
|
|||
681 | c.latest_data = latest |
|
|||
682 | c.latest_ver = latest['version'] |
|
|||
683 | c.cur_ver = rhodecode.__version__ |
|
|||
684 | c.should_upgrade = False |
|
|||
685 |
|
||||
686 | if (packaging.version.Version(c.latest_ver) > |
|
|||
687 | packaging.version.Version(c.cur_ver)): |
|
|||
688 | c.should_upgrade = True |
|
|||
689 | c.important_notices = latest['general'] |
|
|||
690 |
|
||||
691 | return render('admin/settings/settings_system_update.html') |
|
|||
692 |
|
542 | |||
693 | @HasPermissionAllDecorator('hg.admin') |
|
543 | @HasPermissionAllDecorator('hg.admin') | |
694 | def settings_supervisor(self): |
|
544 | def settings_supervisor(self): | |
@@ -710,7 +560,7 b' class SettingsController(BaseController)' | |||||
710 | except Exception as e: |
|
560 | except Exception as e: | |
711 | c.connection_error = str(e) |
|
561 | c.connection_error = str(e) | |
712 | log.exception("Exception reading supervisor data") |
|
562 | log.exception("Exception reading supervisor data") | |
713 |
return render('admin/settings/settings. |
|
563 | return render('admin/settings/settings.mako') | |
714 |
|
564 | |||
715 | groupid = c.rhodecode_ini.get('supervisor.group_id') |
|
565 | groupid = c.rhodecode_ini.get('supervisor.group_id') | |
716 |
|
566 | |||
@@ -734,7 +584,7 b' class SettingsController(BaseController)' | |||||
734 | log.exception("Exception reading supervisor data") |
|
584 | log.exception("Exception reading supervisor data") | |
735 | c.supervisor_procs[k] = {'_rhodecode_error': str(e)} |
|
585 | c.supervisor_procs[k] = {'_rhodecode_error': str(e)} | |
736 |
|
586 | |||
737 |
return render('admin/settings/settings. |
|
587 | return render('admin/settings/settings.mako') | |
738 |
|
588 | |||
739 | @HasPermissionAllDecorator('hg.admin') |
|
589 | @HasPermissionAllDecorator('hg.admin') | |
740 | def settings_supervisor_log(self, procid): |
|
590 | def settings_supervisor_log(self, procid): | |
@@ -751,7 +601,7 b' class SettingsController(BaseController)' | |||||
751 | offset = abs(safe_int(request.GET.get('offset', c.log_size))) * -1 |
|
601 | offset = abs(safe_int(request.GET.get('offset', c.log_size))) * -1 | |
752 | c.log = supervisor.read_process_log(_connection, procid, offset, 0) |
|
602 | c.log = supervisor.read_process_log(_connection, procid, offset, 0) | |
753 |
|
603 | |||
754 |
return render('admin/settings/settings. |
|
604 | return render('admin/settings/settings.mako') | |
755 |
|
605 | |||
756 | @HasPermissionAllDecorator('hg.admin') |
|
606 | @HasPermissionAllDecorator('hg.admin') | |
757 | @auth.CSRFRequired() |
|
607 | @auth.CSRFRequired() | |
@@ -768,7 +618,7 b' class SettingsController(BaseController)' | |||||
768 | _('Some form inputs contain invalid data.'), |
|
618 | _('Some form inputs contain invalid data.'), | |
769 | category='error') |
|
619 | category='error') | |
770 | return htmlfill.render( |
|
620 | return htmlfill.render( | |
771 |
render('admin/settings/settings. |
|
621 | render('admin/settings/settings.mako'), | |
772 | defaults=errors.value, |
|
622 | defaults=errors.value, | |
773 | errors=errors.error_dict or {}, |
|
623 | errors=errors.error_dict or {}, | |
774 | prefix_error=False, |
|
624 | prefix_error=False, | |
@@ -795,7 +645,7 b' class SettingsController(BaseController)' | |||||
795 | return redirect(url('admin_settings_labs')) |
|
645 | return redirect(url('admin_settings_labs')) | |
796 |
|
646 | |||
797 | return htmlfill.render( |
|
647 | return htmlfill.render( | |
798 |
render('admin/settings/settings. |
|
648 | render('admin/settings/settings.mako'), | |
799 | defaults=self._form_defaults(), |
|
649 | defaults=self._form_defaults(), | |
800 | encoding='UTF-8', |
|
650 | encoding='UTF-8', | |
801 | force_defaults=False) |
|
651 | force_defaults=False) | |
@@ -811,7 +661,7 b' class SettingsController(BaseController)' | |||||
811 | c.lab_settings = _LAB_SETTINGS |
|
661 | c.lab_settings = _LAB_SETTINGS | |
812 |
|
662 | |||
813 | return htmlfill.render( |
|
663 | return htmlfill.render( | |
814 |
render('admin/settings/settings. |
|
664 | render('admin/settings/settings.mako'), | |
815 | defaults=self._form_defaults(), |
|
665 | defaults=self._form_defaults(), | |
816 | encoding='UTF-8', |
|
666 | encoding='UTF-8', | |
817 | force_defaults=False) |
|
667 | force_defaults=False) |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -109,7 +109,7 b' class UserGroupsController(BaseControlle' | |||||
109 | # url('users_groups') |
|
109 | # url('users_groups') | |
110 |
|
110 | |||
111 | from rhodecode.lib.utils import PartialRenderer |
|
111 | from rhodecode.lib.utils import PartialRenderer | |
112 |
_render = PartialRenderer('data_table/_dt_elements. |
|
112 | _render = PartialRenderer('data_table/_dt_elements.mako') | |
113 |
|
113 | |||
114 | def user_group_name(user_group_id, user_group_name): |
|
114 | def user_group_name(user_group_id, user_group_name): | |
115 | return _render("user_group_name", user_group_id, user_group_name) |
|
115 | return _render("user_group_name", user_group_id, user_group_name) | |
@@ -136,7 +136,7 b' class UserGroupsController(BaseControlle' | |||||
136 | }) |
|
136 | }) | |
137 |
|
137 | |||
138 | c.data = json.dumps(user_groups_data) |
|
138 | c.data = json.dumps(user_groups_data) | |
139 |
return render('admin/user_groups/user_groups. |
|
139 | return render('admin/user_groups/user_groups.mako') | |
140 |
|
140 | |||
141 | @HasPermissionAnyDecorator('hg.admin', 'hg.usergroup.create.true') |
|
141 | @HasPermissionAnyDecorator('hg.admin', 'hg.usergroup.create.true') | |
142 | @auth.CSRFRequired() |
|
142 | @auth.CSRFRequired() | |
@@ -167,7 +167,7 b' class UserGroupsController(BaseControlle' | |||||
167 | Session().commit() |
|
167 | Session().commit() | |
168 | except formencode.Invalid as errors: |
|
168 | except formencode.Invalid as errors: | |
169 | return htmlfill.render( |
|
169 | return htmlfill.render( | |
170 |
render('admin/user_groups/user_group_add. |
|
170 | render('admin/user_groups/user_group_add.mako'), | |
171 | defaults=errors.value, |
|
171 | defaults=errors.value, | |
172 | errors=errors.error_dict or {}, |
|
172 | errors=errors.error_dict or {}, | |
173 | prefix_error=False, |
|
173 | prefix_error=False, | |
@@ -185,7 +185,7 b' class UserGroupsController(BaseControlle' | |||||
185 | def new(self): |
|
185 | def new(self): | |
186 | """GET /user_groups/new: Form to create a new item""" |
|
186 | """GET /user_groups/new: Form to create a new item""" | |
187 | # url('new_users_group') |
|
187 | # url('new_users_group') | |
188 |
return render('admin/user_groups/user_group_add. |
|
188 | return render('admin/user_groups/user_group_add.mako') | |
189 |
|
189 | |||
190 | @HasUserGroupPermissionAnyDecorator('usergroup.admin') |
|
190 | @HasUserGroupPermissionAnyDecorator('usergroup.admin') | |
191 | @auth.CSRFRequired() |
|
191 | @auth.CSRFRequired() | |
@@ -224,7 +224,7 b' class UserGroupsController(BaseControlle' | |||||
224 | e = errors.error_dict or {} |
|
224 | e = errors.error_dict or {} | |
225 |
|
225 | |||
226 | return htmlfill.render( |
|
226 | return htmlfill.render( | |
227 |
render('admin/user_groups/user_group_edit. |
|
227 | render('admin/user_groups/user_group_edit.mako'), | |
228 | defaults=defaults, |
|
228 | defaults=defaults, | |
229 | errors=e, |
|
229 | errors=e, | |
230 | prefix_error=False, |
|
230 | prefix_error=False, | |
@@ -276,7 +276,7 b' class UserGroupsController(BaseControlle' | |||||
276 | defaults = self.__load_defaults(user_group_id) |
|
276 | defaults = self.__load_defaults(user_group_id) | |
277 |
|
277 | |||
278 | return htmlfill.render( |
|
278 | return htmlfill.render( | |
279 |
render('admin/user_groups/user_group_edit. |
|
279 | render('admin/user_groups/user_group_edit.mako'), | |
280 | defaults=defaults, |
|
280 | defaults=defaults, | |
281 | encoding="UTF-8", |
|
281 | encoding="UTF-8", | |
282 | force_defaults=False |
|
282 | force_defaults=False | |
@@ -299,7 +299,7 b' class UserGroupsController(BaseControlle' | |||||
299 | p.permission.permission_name}) |
|
299 | p.permission.permission_name}) | |
300 |
|
300 | |||
301 | return htmlfill.render( |
|
301 | return htmlfill.render( | |
302 |
render('admin/user_groups/user_group_edit. |
|
302 | render('admin/user_groups/user_group_edit.mako'), | |
303 | defaults=defaults, |
|
303 | defaults=defaults, | |
304 | encoding="UTF-8", |
|
304 | encoding="UTF-8", | |
305 | force_defaults=False |
|
305 | force_defaults=False | |
@@ -365,7 +365,7 b' class UserGroupsController(BaseControlle' | |||||
365 | permissions['repositories_groups'][gr.group.group_name] \ |
|
365 | permissions['repositories_groups'][gr.group.group_name] \ | |
366 | = gr.permission.permission_name |
|
366 | = gr.permission.permission_name | |
367 | c.permissions = permissions |
|
367 | c.permissions = permissions | |
368 |
return render('admin/user_groups/user_group_edit. |
|
368 | return render('admin/user_groups/user_group_edit.mako') | |
369 |
|
369 | |||
370 | @HasUserGroupPermissionAnyDecorator('usergroup.admin') |
|
370 | @HasUserGroupPermissionAnyDecorator('usergroup.admin') | |
371 | def edit_global_perms(self, user_group_id): |
|
371 | def edit_global_perms(self, user_group_id): | |
@@ -379,7 +379,7 b' class UserGroupsController(BaseControlle' | |||||
379 | defaults.update(c.user_group.get_default_perms()) |
|
379 | defaults.update(c.user_group.get_default_perms()) | |
380 |
|
380 | |||
381 | return htmlfill.render( |
|
381 | return htmlfill.render( | |
382 |
render('admin/user_groups/user_group_edit. |
|
382 | render('admin/user_groups/user_group_edit.mako'), | |
383 | defaults=defaults, |
|
383 | defaults=defaults, | |
384 | encoding="UTF-8", |
|
384 | encoding="UTF-8", | |
385 | force_defaults=False |
|
385 | force_defaults=False | |
@@ -425,7 +425,7 b' class UserGroupsController(BaseControlle' | |||||
425 | defaults = errors.value |
|
425 | defaults = errors.value | |
426 | c.user_group = user_group |
|
426 | c.user_group = user_group | |
427 | return htmlfill.render( |
|
427 | return htmlfill.render( | |
428 |
render('admin/user_groups/user_group_edit. |
|
428 | render('admin/user_groups/user_group_edit.mako'), | |
429 | defaults=defaults, |
|
429 | defaults=defaults, | |
430 | errors=errors.error_dict or {}, |
|
430 | errors=errors.error_dict or {}, | |
431 | prefix_error=False, |
|
431 | prefix_error=False, | |
@@ -456,7 +456,7 b' class UserGroupsController(BaseControlle' | |||||
456 | (x.group for x in c.user_group.users_group_repo_group_to_perm), |
|
456 | (x.group for x in c.user_group.users_group_repo_group_to_perm), | |
457 | key=lambda u: u.group_name.lower()) |
|
457 | key=lambda u: u.group_name.lower()) | |
458 |
|
458 | |||
459 |
return render('admin/user_groups/user_group_edit. |
|
459 | return render('admin/user_groups/user_group_edit.mako') | |
460 |
|
460 | |||
461 | @HasUserGroupPermissionAnyDecorator('usergroup.admin') |
|
461 | @HasUserGroupPermissionAnyDecorator('usergroup.admin') | |
462 | @XHRRequired() |
|
462 | @XHRRequired() |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -82,7 +82,7 b' class UsersController(BaseController):' | |||||
82 | # url('users') |
|
82 | # url('users') | |
83 |
|
83 | |||
84 | from rhodecode.lib.utils import PartialRenderer |
|
84 | from rhodecode.lib.utils import PartialRenderer | |
85 |
_render = PartialRenderer('data_table/_dt_elements. |
|
85 | _render = PartialRenderer('data_table/_dt_elements.mako') | |
86 |
|
86 | |||
87 | def username(user_id, username): |
|
87 | def username(user_id, username): | |
88 | return _render("user_name", user_id, username) |
|
88 | return _render("user_name", user_id, username) | |
@@ -119,7 +119,7 b' class UsersController(BaseController):' | |||||
119 |
|
119 | |||
120 |
|
120 | |||
121 | c.data = json.dumps(users_data) |
|
121 | c.data = json.dumps(users_data) | |
122 |
return render('admin/users/users. |
|
122 | return render('admin/users/users.mako') | |
123 |
|
123 | |||
124 | def _get_personal_repo_group_template_vars(self): |
|
124 | def _get_personal_repo_group_template_vars(self): | |
125 | DummyUser = AttributeDict({ |
|
125 | DummyUser = AttributeDict({ | |
@@ -156,7 +156,7 b' class UsersController(BaseController):' | |||||
156 | except formencode.Invalid as errors: |
|
156 | except formencode.Invalid as errors: | |
157 | self._get_personal_repo_group_template_vars() |
|
157 | self._get_personal_repo_group_template_vars() | |
158 | return htmlfill.render( |
|
158 | return htmlfill.render( | |
159 |
render('admin/users/user_add. |
|
159 | render('admin/users/user_add.mako'), | |
160 | defaults=errors.value, |
|
160 | defaults=errors.value, | |
161 | errors=errors.error_dict or {}, |
|
161 | errors=errors.error_dict or {}, | |
162 | prefix_error=False, |
|
162 | prefix_error=False, | |
@@ -176,7 +176,7 b' class UsersController(BaseController):' | |||||
176 | # url('new_user') |
|
176 | # url('new_user') | |
177 | c.default_extern_type = auth_rhodecode.RhodeCodeAuthPlugin.name |
|
177 | c.default_extern_type = auth_rhodecode.RhodeCodeAuthPlugin.name | |
178 | self._get_personal_repo_group_template_vars() |
|
178 | self._get_personal_repo_group_template_vars() | |
179 |
return render('admin/users/user_add. |
|
179 | return render('admin/users/user_add.mako') | |
180 |
|
180 | |||
181 | @HasPermissionAllDecorator('hg.admin') |
|
181 | @HasPermissionAllDecorator('hg.admin') | |
182 | @auth.CSRFRequired() |
|
182 | @auth.CSRFRequired() | |
@@ -218,7 +218,7 b' class UsersController(BaseController):' | |||||
218 | e = errors.error_dict or {} |
|
218 | e = errors.error_dict or {} | |
219 |
|
219 | |||
220 | return htmlfill.render( |
|
220 | return htmlfill.render( | |
221 |
render('admin/users/user_edit. |
|
221 | render('admin/users/user_edit.mako'), | |
222 | defaults=defaults, |
|
222 | defaults=defaults, | |
223 | errors=e, |
|
223 | errors=e, | |
224 | prefix_error=False, |
|
224 | prefix_error=False, | |
@@ -414,7 +414,7 b' class UsersController(BaseController):' | |||||
414 | defaults = c.user.get_dict() |
|
414 | defaults = c.user.get_dict() | |
415 | defaults.update({'language': c.user.user_data.get('language')}) |
|
415 | defaults.update({'language': c.user.user_data.get('language')}) | |
416 | return htmlfill.render( |
|
416 | return htmlfill.render( | |
417 |
render('admin/users/user_edit. |
|
417 | render('admin/users/user_edit.mako'), | |
418 | defaults=defaults, |
|
418 | defaults=defaults, | |
419 | encoding="UTF-8", |
|
419 | encoding="UTF-8", | |
420 | force_defaults=False) |
|
420 | force_defaults=False) | |
@@ -446,7 +446,7 b' class UsersController(BaseController):' | |||||
446 | '"inactive" instead of deleting it.') if has_review else '' |
|
446 | '"inactive" instead of deleting it.') if has_review else '' | |
447 |
|
447 | |||
448 | return htmlfill.render( |
|
448 | return htmlfill.render( | |
449 |
render('admin/users/user_edit. |
|
449 | render('admin/users/user_edit.mako'), | |
450 | defaults=defaults, |
|
450 | defaults=defaults, | |
451 | encoding="UTF-8", |
|
451 | encoding="UTF-8", | |
452 | force_defaults=False) |
|
452 | force_defaults=False) | |
@@ -476,7 +476,7 b' class UsersController(BaseController):' | |||||
476 | c.user.user_id, show_expired=show_expired) |
|
476 | c.user.user_id, show_expired=show_expired) | |
477 | defaults = c.user.get_dict() |
|
477 | defaults = c.user.get_dict() | |
478 | return htmlfill.render( |
|
478 | return htmlfill.render( | |
479 |
render('admin/users/user_edit. |
|
479 | render('admin/users/user_edit.mako'), | |
480 | defaults=defaults, |
|
480 | defaults=defaults, | |
481 | encoding="UTF-8", |
|
481 | encoding="UTF-8", | |
482 | force_defaults=False) |
|
482 | force_defaults=False) | |
@@ -539,7 +539,7 b' class UsersController(BaseController):' | |||||
539 | defaults.update(c.user.get_default_perms()) |
|
539 | defaults.update(c.user.get_default_perms()) | |
540 |
|
540 | |||
541 | return htmlfill.render( |
|
541 | return htmlfill.render( | |
542 |
render('admin/users/user_edit. |
|
542 | render('admin/users/user_edit.mako'), | |
543 | defaults=defaults, |
|
543 | defaults=defaults, | |
544 | encoding="UTF-8", |
|
544 | encoding="UTF-8", | |
545 | force_defaults=False) |
|
545 | force_defaults=False) | |
@@ -584,7 +584,7 b' class UsersController(BaseController):' | |||||
584 | defaults = errors.value |
|
584 | defaults = errors.value | |
585 | c.user = user |
|
585 | c.user = user | |
586 | return htmlfill.render( |
|
586 | return htmlfill.render( | |
587 |
render('admin/users/user_edit. |
|
587 | render('admin/users/user_edit.mako'), | |
588 | defaults=defaults, |
|
588 | defaults=defaults, | |
589 | errors=errors.error_dict or {}, |
|
589 | errors=errors.error_dict or {}, | |
590 | prefix_error=False, |
|
590 | prefix_error=False, | |
@@ -607,7 +607,7 b' class UsersController(BaseController):' | |||||
607 | c.active = 'perms_summary' |
|
607 | c.active = 'perms_summary' | |
608 | c.perm_user = AuthUser(user_id=user_id, ip_addr=self.ip_addr) |
|
608 | c.perm_user = AuthUser(user_id=user_id, ip_addr=self.ip_addr) | |
609 |
|
609 | |||
610 |
return render('admin/users/user_edit. |
|
610 | return render('admin/users/user_edit.mako') | |
611 |
|
611 | |||
612 | @HasPermissionAllDecorator('hg.admin') |
|
612 | @HasPermissionAllDecorator('hg.admin') | |
613 | def edit_emails(self, user_id): |
|
613 | def edit_emails(self, user_id): | |
@@ -623,7 +623,7 b' class UsersController(BaseController):' | |||||
623 |
|
623 | |||
624 | defaults = c.user.get_dict() |
|
624 | defaults = c.user.get_dict() | |
625 | return htmlfill.render( |
|
625 | return htmlfill.render( | |
626 |
render('admin/users/user_edit. |
|
626 | render('admin/users/user_edit.mako'), | |
627 | defaults=defaults, |
|
627 | defaults=defaults, | |
628 | encoding="UTF-8", |
|
628 | encoding="UTF-8", | |
629 | force_defaults=False) |
|
629 | force_defaults=False) | |
@@ -685,7 +685,7 b' class UsersController(BaseController):' | |||||
685 |
|
685 | |||
686 | defaults = c.user.get_dict() |
|
686 | defaults = c.user.get_dict() | |
687 | return htmlfill.render( |
|
687 | return htmlfill.render( | |
688 |
render('admin/users/user_edit. |
|
688 | render('admin/users/user_edit.mako'), | |
689 | defaults=defaults, |
|
689 | defaults=defaults, | |
690 | encoding="UTF-8", |
|
690 | encoding="UTF-8", | |
691 | force_defaults=False) |
|
691 | force_defaults=False) |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -34,8 +34,8 b' log = logging.getLogger(__name__)' | |||||
34 |
|
34 | |||
35 | class BookmarksController(BaseReferencesController): |
|
35 | class BookmarksController(BaseReferencesController): | |
36 |
|
36 | |||
37 |
partials_template = 'bookmarks/bookmarks_data. |
|
37 | partials_template = 'bookmarks/bookmarks_data.mako' | |
38 |
template = 'bookmarks/bookmarks. |
|
38 | template = 'bookmarks/bookmarks.mako' | |
39 |
|
39 | |||
40 | def __before__(self): |
|
40 | def __before__(self): | |
41 | super(BookmarksController, self).__before__() |
|
41 | super(BookmarksController, self).__before__() |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -34,8 +34,8 b' log = logging.getLogger(__name__)' | |||||
34 |
|
34 | |||
35 | class BranchesController(BaseReferencesController): |
|
35 | class BranchesController(BaseReferencesController): | |
36 |
|
36 | |||
37 |
partials_template = 'branches/branches_data. |
|
37 | partials_template = 'branches/branches_data.mako' | |
38 |
template = 'branches/branches. |
|
38 | template = 'branches/branches.mako' | |
39 |
|
39 | |||
40 | def __before__(self): |
|
40 | def __before__(self): | |
41 | super(BranchesController, self).__before__() |
|
41 | super(BranchesController, self).__before__() |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -30,7 +30,8 b' from pylons.i18n.translation import _' | |||||
30 | from webob.exc import HTTPNotFound, HTTPBadRequest |
|
30 | from webob.exc import HTTPNotFound, HTTPBadRequest | |
31 |
|
31 | |||
32 | import rhodecode.lib.helpers as h |
|
32 | import rhodecode.lib.helpers as h | |
33 | from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator |
|
33 | from rhodecode.lib.auth import ( | |
|
34 | LoginRequired, HasRepoPermissionAnyDecorator, XHRRequired) | |||
34 | from rhodecode.lib.base import BaseRepoController, render |
|
35 | from rhodecode.lib.base import BaseRepoController, render | |
35 | from rhodecode.lib.ext_json import json |
|
36 | from rhodecode.lib.ext_json import json | |
36 | from rhodecode.lib.graphmod import _colored, _dagwalker |
|
37 | from rhodecode.lib.graphmod import _colored, _dagwalker | |
@@ -98,7 +99,7 b' class ChangelogController(BaseRepoContro' | |||||
98 | redirect(h.url('changelog_home', repo_name=repo.repo_name)) |
|
99 | redirect(h.url('changelog_home', repo_name=repo.repo_name)) | |
99 | raise HTTPBadRequest() |
|
100 | raise HTTPBadRequest() | |
100 |
|
101 | |||
101 | def _graph(self, repo, commits): |
|
102 | def _graph(self, repo, commits, prev_data=None, next_data=None): | |
102 | """ |
|
103 | """ | |
103 | Generates a DAG graph for repo |
|
104 | Generates a DAG graph for repo | |
104 |
|
105 | |||
@@ -106,12 +107,30 b' class ChangelogController(BaseRepoContro' | |||||
106 | :param commits: list of commits |
|
107 | :param commits: list of commits | |
107 | """ |
|
108 | """ | |
108 | if not commits: |
|
109 | if not commits: | |
109 |
|
|
110 | return json.dumps([]) | |
110 | return |
|
111 | ||
|
112 | def serialize(commit, parents=True): | |||
|
113 | data = dict( | |||
|
114 | raw_id=commit.raw_id, | |||
|
115 | idx=commit.idx, | |||
|
116 | branch=commit.branch, | |||
|
117 | ) | |||
|
118 | if parents: | |||
|
119 | data['parents'] = [ | |||
|
120 | serialize(x, parents=False) for x in commit.parents] | |||
|
121 | return data | |||
|
122 | ||||
|
123 | prev_data = prev_data or [] | |||
|
124 | next_data = next_data or [] | |||
|
125 | ||||
|
126 | current = [serialize(x) for x in commits] | |||
|
127 | commits = prev_data + current + next_data | |||
111 |
|
128 | |||
112 | dag = _dagwalker(repo, commits) |
|
129 | dag = _dagwalker(repo, commits) | |
113 | data = [['', vtx, edges] for vtx, edges in _colored(dag)] |
|
130 | ||
114 | c.jsdata = json.dumps(data) |
|
131 | data = [[commit_id, vtx, edges, branch] | |
|
132 | for commit_id, vtx, edges, branch in _colored(dag)] | |||
|
133 | return json.dumps(data), json.dumps(current) | |||
115 |
|
134 | |||
116 | def _check_if_valid_branch(self, branch_name, repo_name, f_path): |
|
135 | def _check_if_valid_branch(self, branch_name, repo_name, f_path): | |
117 | if branch_name not in c.rhodecode_repo.branches_all: |
|
136 | if branch_name not in c.rhodecode_repo.branches_all: | |
@@ -120,26 +139,37 b' class ChangelogController(BaseRepoContro' | |||||
120 | redirect(url('changelog_file_home', repo_name=repo_name, |
|
139 | redirect(url('changelog_file_home', repo_name=repo_name, | |
121 | revision=branch_name, f_path=f_path or '')) |
|
140 | revision=branch_name, f_path=f_path or '')) | |
122 |
|
141 | |||
|
142 | def _load_changelog_data(self, collection, page, chunk_size, branch_name=None, dynamic=False): | |||
|
143 | c.total_cs = len(collection) | |||
|
144 | c.showing_commits = min(chunk_size, c.total_cs) | |||
|
145 | c.pagination = RepoPage(collection, page=page, item_count=c.total_cs, | |||
|
146 | items_per_page=chunk_size, branch=branch_name) | |||
|
147 | ||||
|
148 | c.next_page = c.pagination.next_page | |||
|
149 | c.prev_page = c.pagination.previous_page | |||
|
150 | ||||
|
151 | if dynamic: | |||
|
152 | if request.GET.get('chunk') != 'next': | |||
|
153 | c.next_page = None | |||
|
154 | if request.GET.get('chunk') != 'prev': | |||
|
155 | c.prev_page = None | |||
|
156 | ||||
|
157 | page_commit_ids = [x.raw_id for x in c.pagination] | |||
|
158 | c.comments = c.rhodecode_db_repo.get_comments(page_commit_ids) | |||
|
159 | c.statuses = c.rhodecode_db_repo.statuses(page_commit_ids) | |||
|
160 | ||||
123 | @LoginRequired() |
|
161 | @LoginRequired() | |
124 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', |
|
162 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', | |
125 | 'repository.admin') |
|
163 | 'repository.admin') | |
126 | def index(self, repo_name, revision=None, f_path=None): |
|
164 | def index(self, repo_name, revision=None, f_path=None): | |
127 | commit_id = revision |
|
165 | commit_id = revision | |
128 |
|
|
166 | chunk_size = 20 | |
|
167 | ||||
|
168 | c.branch_name = branch_name = request.GET.get('branch', None) | |||
|
169 | c.book_name = book_name = request.GET.get('bookmark', None) | |||
129 | hist_limit = safe_int(request.GET.get('limit')) or None |
|
170 | hist_limit = safe_int(request.GET.get('limit')) or None | |
130 | if request.GET.get('size'): |
|
|||
131 | c.size = safe_int(request.GET.get('size'), 1) |
|
|||
132 | session['changelog_size'] = c.size |
|
|||
133 | session.save() |
|
|||
134 | else: |
|
|||
135 | c.size = int(session.get('changelog_size', DEFAULT_CHANGELOG_SIZE)) |
|
|||
136 |
|
||||
137 | # min size must be 1 and less than limit |
|
|||
138 | c.size = max(c.size, 1) if c.size <= limit else limit |
|
|||
139 |
|
171 | |||
140 | p = safe_int(request.GET.get('page', 1), 1) |
|
172 | p = safe_int(request.GET.get('page', 1), 1) | |
141 | c.branch_name = branch_name = request.GET.get('branch', None) |
|
|||
142 | c.book_name = book_name = request.GET.get('bookmark', None) |
|
|||
143 |
|
173 | |||
144 | c.selected_name = branch_name or book_name |
|
174 | c.selected_name = branch_name or book_name | |
145 | if not commit_id and branch_name: |
|
175 | if not commit_id and branch_name: | |
@@ -147,6 +177,8 b' class ChangelogController(BaseRepoContro' | |||||
147 |
|
177 | |||
148 | c.changelog_for_path = f_path |
|
178 | c.changelog_for_path = f_path | |
149 | pre_load = ['author', 'branch', 'date', 'message', 'parents'] |
|
179 | pre_load = ['author', 'branch', 'date', 'message', 'parents'] | |
|
180 | commit_ids = [] | |||
|
181 | ||||
150 | try: |
|
182 | try: | |
151 | if f_path: |
|
183 | if f_path: | |
152 | log.debug('generating changelog for path %s', f_path) |
|
184 | log.debug('generating changelog for path %s', f_path) | |
@@ -174,13 +206,9 b' class ChangelogController(BaseRepoContro' | |||||
174 | collection = c.rhodecode_repo.get_commits( |
|
206 | collection = c.rhodecode_repo.get_commits( | |
175 | branch_name=branch_name, pre_load=pre_load) |
|
207 | branch_name=branch_name, pre_load=pre_load) | |
176 |
|
208 | |||
177 | c.total_cs = len(collection) |
|
209 | self._load_changelog_data( | |
178 | c.showing_commits = min(c.size, c.total_cs) |
|
210 | collection, p, chunk_size, c.branch_name, dynamic=f_path) | |
179 | c.pagination = RepoPage(collection, page=p, item_count=c.total_cs, |
|
211 | ||
180 | items_per_page=c.size, branch=branch_name) |
|
|||
181 | page_commit_ids = [x.raw_id for x in c.pagination] |
|
|||
182 | c.comments = c.rhodecode_db_repo.get_comments(page_commit_ids) |
|
|||
183 | c.statuses = c.rhodecode_db_repo.statuses(page_commit_ids) |
|
|||
184 | except EmptyRepositoryError as e: |
|
212 | except EmptyRepositoryError as e: | |
185 | h.flash(safe_str(e), category='warning') |
|
213 | h.flash(safe_str(e), category='warning') | |
186 | return redirect(url('summary_home', repo_name=repo_name)) |
|
214 | return redirect(url('summary_home', repo_name=repo_name)) | |
@@ -193,24 +221,64 b' class ChangelogController(BaseRepoContro' | |||||
193 | if (request.environ.get('HTTP_X_PARTIAL_XHR') |
|
221 | if (request.environ.get('HTTP_X_PARTIAL_XHR') | |
194 | or request.environ.get('HTTP_X_PJAX')): |
|
222 | or request.environ.get('HTTP_X_PJAX')): | |
195 | # loading from ajax, we don't want the first result, it's popped |
|
223 | # loading from ajax, we don't want the first result, it's popped | |
196 |
return render('changelog/changelog_file_history. |
|
224 | return render('changelog/changelog_file_history.mako') | |
|
225 | ||||
|
226 | if not f_path: | |||
|
227 | commit_ids = c.pagination | |||
197 |
|
228 | |||
198 | if f_path: |
|
229 | c.graph_data, c.graph_commits = self._graph( | |
199 | revs = [] |
|
230 | c.rhodecode_repo, commit_ids) | |
200 | else: |
|
|||
201 | revs = c.pagination |
|
|||
202 | self._graph(c.rhodecode_repo, revs) |
|
|||
203 |
|
231 | |||
204 |
return render('changelog/changelog. |
|
232 | return render('changelog/changelog.mako') | |
205 |
|
233 | |||
206 | @LoginRequired() |
|
234 | @LoginRequired() | |
207 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', |
|
235 | @XHRRequired() | |
208 | 'repository.admin') |
|
236 | @HasRepoPermissionAnyDecorator( | |
209 | def changelog_details(self, commit_id): |
|
237 | 'repository.read', 'repository.write', 'repository.admin') | |
210 | if request.environ.get('HTTP_X_PARTIAL_XHR'): |
|
238 | def changelog_elements(self, repo_name): | |
211 | c.commit = c.rhodecode_repo.get_commit(commit_id=commit_id) |
|
239 | commit_id = None | |
212 | return render('changelog/changelog_details.html') |
|
240 | chunk_size = 20 | |
213 | raise HTTPNotFound() |
|
241 | ||
|
242 | def wrap_for_error(err): | |||
|
243 | return '<tr><td colspan="9" class="alert alert-error">ERROR: {}</td></tr>'.format(err) | |||
|
244 | ||||
|
245 | c.branch_name = branch_name = request.GET.get('branch', None) | |||
|
246 | c.book_name = book_name = request.GET.get('bookmark', None) | |||
|
247 | ||||
|
248 | p = safe_int(request.GET.get('page', 1), 1) | |||
|
249 | ||||
|
250 | c.selected_name = branch_name or book_name | |||
|
251 | if not commit_id and branch_name: | |||
|
252 | if branch_name not in c.rhodecode_repo.branches_all: | |||
|
253 | return wrap_for_error( | |||
|
254 | safe_str('Missing branch: {}'.format(branch_name))) | |||
|
255 | ||||
|
256 | pre_load = ['author', 'branch', 'date', 'message', 'parents'] | |||
|
257 | collection = c.rhodecode_repo.get_commits( | |||
|
258 | branch_name=branch_name, pre_load=pre_load) | |||
|
259 | ||||
|
260 | try: | |||
|
261 | self._load_changelog_data(collection, p, chunk_size, dynamic=True) | |||
|
262 | except EmptyRepositoryError as e: | |||
|
263 | return wrap_for_error(safe_str(e)) | |||
|
264 | except (RepositoryError, CommitDoesNotExistError, Exception) as e: | |||
|
265 | log.exception('Failed to fetch commits') | |||
|
266 | return wrap_for_error(safe_str(e)) | |||
|
267 | ||||
|
268 | prev_data = None | |||
|
269 | next_data = None | |||
|
270 | ||||
|
271 | prev_graph = json.loads(request.POST.get('graph', '')) | |||
|
272 | ||||
|
273 | if request.GET.get('chunk') == 'prev': | |||
|
274 | next_data = prev_graph | |||
|
275 | elif request.GET.get('chunk') == 'next': | |||
|
276 | prev_data = prev_graph | |||
|
277 | ||||
|
278 | c.graph_data, c.graph_commits = self._graph( | |||
|
279 | c.rhodecode_repo, c.pagination, | |||
|
280 | prev_data=prev_data, next_data=next_data) | |||
|
281 | return render('changelog/changelog_elements.mako') | |||
214 |
|
282 | |||
215 | @LoginRequired() |
|
283 | @LoginRequired() | |
216 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', |
|
284 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', | |
@@ -218,5 +286,5 b' class ChangelogController(BaseRepoContro' | |||||
218 | def changelog_summary(self, repo_name): |
|
286 | def changelog_summary(self, repo_name): | |
219 | if request.environ.get('HTTP_X_PJAX'): |
|
287 | if request.environ.get('HTTP_X_PJAX'): | |
220 | _load_changelog_summary() |
|
288 | _load_changelog_summary() | |
221 |
return render('changelog/changelog_summary_data. |
|
289 | return render('changelog/changelog_summary_data.mako') | |
222 | raise HTTPNotFound() |
|
290 | raise HTTPNotFound() |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -46,7 +46,7 b' from rhodecode.lib.vcs.exceptions import' | |||||
46 | RepositoryError, CommitDoesNotExistError, NodeDoesNotExistError) |
|
46 | RepositoryError, CommitDoesNotExistError, NodeDoesNotExistError) | |
47 | from rhodecode.model.db import ChangesetComment, ChangesetStatus |
|
47 | from rhodecode.model.db import ChangesetComment, ChangesetStatus | |
48 | from rhodecode.model.changeset_status import ChangesetStatusModel |
|
48 | from rhodecode.model.changeset_status import ChangesetStatusModel | |
49 |
from rhodecode.model.comment import |
|
49 | from rhodecode.model.comment import CommentsModel | |
50 | from rhodecode.model.meta import Session |
|
50 | from rhodecode.model.meta import Session | |
51 | from rhodecode.model.repo import RepoModel |
|
51 | from rhodecode.model.repo import RepoModel | |
52 |
|
52 | |||
@@ -198,15 +198,20 b' class ChangesetController(BaseRepoContro' | |||||
198 | c.lines_added = 0 |
|
198 | c.lines_added = 0 | |
199 | c.lines_deleted = 0 |
|
199 | c.lines_deleted = 0 | |
200 |
|
200 | |||
|
201 | # auto collapse if we have more than limit | |||
|
202 | collapse_limit = diffs.DiffProcessor._collapse_commits_over | |||
|
203 | c.collapse_all_commits = len(c.commit_ranges) > collapse_limit | |||
|
204 | ||||
201 | c.commit_statuses = ChangesetStatus.STATUSES |
|
205 | c.commit_statuses = ChangesetStatus.STATUSES | |
202 | c.inline_comments = [] |
|
206 | c.inline_comments = [] | |
203 | c.files = [] |
|
207 | c.files = [] | |
204 |
|
208 | |||
205 | c.statuses = [] |
|
209 | c.statuses = [] | |
206 | c.comments = [] |
|
210 | c.comments = [] | |
|
211 | c.unresolved_comments = [] | |||
207 | if len(c.commit_ranges) == 1: |
|
212 | if len(c.commit_ranges) == 1: | |
208 | commit = c.commit_ranges[0] |
|
213 | commit = c.commit_ranges[0] | |
209 |
c.comments = |
|
214 | c.comments = CommentsModel().get_comments( | |
210 | c.rhodecode_db_repo.repo_id, |
|
215 | c.rhodecode_db_repo.repo_id, | |
211 | revision=commit.raw_id) |
|
216 | revision=commit.raw_id) | |
212 | c.statuses.append(ChangesetStatusModel().get_status( |
|
217 | c.statuses.append(ChangesetStatusModel().get_status( | |
@@ -222,6 +227,9 b' class ChangesetController(BaseRepoContro' | |||||
222 | for pr in prs: |
|
227 | for pr in prs: | |
223 | c.comments.extend(pr.comments) |
|
228 | c.comments.extend(pr.comments) | |
224 |
|
229 | |||
|
230 | c.unresolved_comments = CommentsModel()\ | |||
|
231 | .get_commit_unresolved_todos(commit.raw_id) | |||
|
232 | ||||
225 | # Iterate over ranges (default commit view is always one commit) |
|
233 | # Iterate over ranges (default commit view is always one commit) | |
226 | for commit in c.commit_ranges: |
|
234 | for commit in c.commit_ranges: | |
227 | c.changes[commit.raw_id] = [] |
|
235 | c.changes[commit.raw_id] = [] | |
@@ -251,9 +259,9 b' class ChangesetController(BaseRepoContro' | |||||
251 | return None |
|
259 | return None | |
252 | return get_node |
|
260 | return get_node | |
253 |
|
261 | |||
254 |
inline_comments = |
|
262 | inline_comments = CommentsModel().get_inline_comments( | |
255 | c.rhodecode_db_repo.repo_id, revision=commit.raw_id) |
|
263 | c.rhodecode_db_repo.repo_id, revision=commit.raw_id) | |
256 |
c.inline_cnt = |
|
264 | c.inline_cnt = CommentsModel().get_inline_comments_count( | |
257 | inline_comments) |
|
265 | inline_comments) | |
258 |
|
266 | |||
259 | diffset = codeblocks.DiffSet( |
|
267 | diffset = codeblocks.DiffSet( | |
@@ -271,7 +279,6 b' class ChangesetController(BaseRepoContro' | |||||
271 | # sort comments by how they were generated |
|
279 | # sort comments by how they were generated | |
272 | c.comments = sorted(c.comments, key=lambda x: x.comment_id) |
|
280 | c.comments = sorted(c.comments, key=lambda x: x.comment_id) | |
273 |
|
281 | |||
274 |
|
||||
275 | if len(c.commit_ranges) == 1: |
|
282 | if len(c.commit_ranges) == 1: | |
276 | c.commit = c.commit_ranges[0] |
|
283 | c.commit = c.commit_ranges[0] | |
277 | c.parent_tmpl = ''.join( |
|
284 | c.parent_tmpl = ''.join( | |
@@ -284,17 +291,17 b' class ChangesetController(BaseRepoContro' | |||||
284 | elif method == 'patch': |
|
291 | elif method == 'patch': | |
285 | response.content_type = 'text/plain' |
|
292 | response.content_type = 'text/plain' | |
286 | c.diff = safe_unicode(diff) |
|
293 | c.diff = safe_unicode(diff) | |
287 |
return render('changeset/patch_changeset. |
|
294 | return render('changeset/patch_changeset.mako') | |
288 | elif method == 'raw': |
|
295 | elif method == 'raw': | |
289 | response.content_type = 'text/plain' |
|
296 | response.content_type = 'text/plain' | |
290 | return diff |
|
297 | return diff | |
291 | elif method == 'show': |
|
298 | elif method == 'show': | |
292 | if len(c.commit_ranges) == 1: |
|
299 | if len(c.commit_ranges) == 1: | |
293 |
return render('changeset/changeset. |
|
300 | return render('changeset/changeset.mako') | |
294 | else: |
|
301 | else: | |
295 | c.ancestor = None |
|
302 | c.ancestor = None | |
296 | c.target_repo = c.rhodecode_db_repo |
|
303 | c.target_repo = c.rhodecode_db_repo | |
297 |
return render('changeset/changeset_range. |
|
304 | return render('changeset/changeset_range.mako') | |
298 |
|
305 | |||
299 | @LoginRequired() |
|
306 | @LoginRequired() | |
300 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', |
|
307 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', | |
@@ -330,29 +337,39 b' class ChangesetController(BaseRepoContro' | |||||
330 | commit_id = revision |
|
337 | commit_id = revision | |
331 | status = request.POST.get('changeset_status', None) |
|
338 | status = request.POST.get('changeset_status', None) | |
332 | text = request.POST.get('text') |
|
339 | text = request.POST.get('text') | |
|
340 | comment_type = request.POST.get('comment_type') | |||
|
341 | resolves_comment_id = request.POST.get('resolves_comment_id', None) | |||
|
342 | ||||
333 | if status: |
|
343 | if status: | |
334 | text = text or (_('Status change %(transition_icon)s %(status)s') |
|
344 | text = text or (_('Status change %(transition_icon)s %(status)s') | |
335 | % {'transition_icon': '>', |
|
345 | % {'transition_icon': '>', | |
336 | 'status': ChangesetStatus.get_status_lbl(status)}) |
|
346 | 'status': ChangesetStatus.get_status_lbl(status)}) | |
337 |
|
347 | |||
338 |
multi_commit_ids = |
|
348 | multi_commit_ids = [] | |
339 | lambda s: s not in ['', None], |
|
349 | for _commit_id in request.POST.get('commit_ids', '').split(','): | |
340 | request.POST.get('commit_ids', '').split(','),) |
|
350 | if _commit_id not in ['', None, EmptyCommit.raw_id]: | |
|
351 | if _commit_id not in multi_commit_ids: | |||
|
352 | multi_commit_ids.append(_commit_id) | |||
341 |
|
353 | |||
342 | commit_ids = multi_commit_ids or [commit_id] |
|
354 | commit_ids = multi_commit_ids or [commit_id] | |
|
355 | ||||
343 | comment = None |
|
356 | comment = None | |
344 | for current_id in filter(None, commit_ids): |
|
357 | for current_id in filter(None, commit_ids): | |
345 |
c.co = comment = |
|
358 | c.co = comment = CommentsModel().create( | |
346 | text=text, |
|
359 | text=text, | |
347 | repo=c.rhodecode_db_repo.repo_id, |
|
360 | repo=c.rhodecode_db_repo.repo_id, | |
348 | user=c.rhodecode_user.user_id, |
|
361 | user=c.rhodecode_user.user_id, | |
349 |
|
|
362 | commit_id=current_id, | |
350 | f_path=request.POST.get('f_path'), |
|
363 | f_path=request.POST.get('f_path'), | |
351 | line_no=request.POST.get('line'), |
|
364 | line_no=request.POST.get('line'), | |
352 | status_change=(ChangesetStatus.get_status_lbl(status) |
|
365 | status_change=(ChangesetStatus.get_status_lbl(status) | |
353 | if status else None), |
|
366 | if status else None), | |
354 | status_change_type=status |
|
367 | status_change_type=status, | |
|
368 | comment_type=comment_type, | |||
|
369 | resolves_comment_id=resolves_comment_id | |||
355 | ) |
|
370 | ) | |
|
371 | c.inline_comment = True if comment.line_no else False | |||
|
372 | ||||
356 | # get status if set ! |
|
373 | # get status if set ! | |
357 | if status: |
|
374 | if status: | |
358 | # if latest status was from pull request and it's closed |
|
375 | # if latest status was from pull request and it's closed | |
@@ -386,7 +403,7 b' class ChangesetController(BaseRepoContro' | |||||
386 | if comment: |
|
403 | if comment: | |
387 | data.update(comment.get_dict()) |
|
404 | data.update(comment.get_dict()) | |
388 | data.update({'rendered_text': |
|
405 | data.update({'rendered_text': | |
389 |
render('changeset/changeset_comment_block. |
|
406 | render('changeset/changeset_comment_block.mako')}) | |
390 |
|
407 | |||
391 | return data |
|
408 | return data | |
392 |
|
409 | |||
@@ -417,10 +434,15 b' class ChangesetController(BaseRepoContro' | |||||
417 | @jsonify |
|
434 | @jsonify | |
418 | def delete_comment(self, repo_name, comment_id): |
|
435 | def delete_comment(self, repo_name, comment_id): | |
419 | comment = ChangesetComment.get(comment_id) |
|
436 | comment = ChangesetComment.get(comment_id) | |
|
437 | if not comment: | |||
|
438 | log.debug('Comment with id:%s not found, skipping', comment_id) | |||
|
439 | # comment already deleted in another call probably | |||
|
440 | return True | |||
|
441 | ||||
420 | owner = (comment.author.user_id == c.rhodecode_user.user_id) |
|
442 | owner = (comment.author.user_id == c.rhodecode_user.user_id) | |
421 | is_repo_admin = h.HasRepoPermissionAny('repository.admin')(c.repo_name) |
|
443 | is_repo_admin = h.HasRepoPermissionAny('repository.admin')(c.repo_name) | |
422 | if h.HasPermissionAny('hg.admin')() or is_repo_admin or owner: |
|
444 | if h.HasPermissionAny('hg.admin')() or is_repo_admin or owner: | |
423 |
|
|
445 | CommentsModel().delete(comment=comment) | |
424 | Session().commit() |
|
446 | Session().commit() | |
425 | return True |
|
447 | return True | |
426 | else: |
|
448 | else: |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2012-201 |
|
3 | # Copyright (C) 2012-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -79,6 +79,7 b' class CompareController(BaseRepoControll' | |||||
79 | def index(self, repo_name): |
|
79 | def index(self, repo_name): | |
80 | c.compare_home = True |
|
80 | c.compare_home = True | |
81 | c.commit_ranges = [] |
|
81 | c.commit_ranges = [] | |
|
82 | c.collapse_all_commits = False | |||
82 | c.diffset = None |
|
83 | c.diffset = None | |
83 | c.limited_diff = False |
|
84 | c.limited_diff = False | |
84 | source_repo = c.rhodecode_db_repo.repo_name |
|
85 | source_repo = c.rhodecode_db_repo.repo_name | |
@@ -90,7 +91,8 b' class CompareController(BaseRepoControll' | |||||
90 | c.target_ref_type = "" |
|
91 | c.target_ref_type = "" | |
91 | c.commit_statuses = ChangesetStatus.STATUSES |
|
92 | c.commit_statuses = ChangesetStatus.STATUSES | |
92 | c.preview_mode = False |
|
93 | c.preview_mode = False | |
93 | return render('compare/compare_diff.html') |
|
94 | c.file_path = None | |
|
95 | return render('compare/compare_diff.mako') | |||
94 |
|
96 | |||
95 | @LoginRequired() |
|
97 | @LoginRequired() | |
96 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', |
|
98 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', | |
@@ -103,8 +105,10 b' class CompareController(BaseRepoControll' | |||||
103 |
|
105 | |||
104 | # target_ref will be evaluated in target_repo |
|
106 | # target_ref will be evaluated in target_repo | |
105 | target_repo_name = request.GET.get('target_repo', source_repo_name) |
|
107 | target_repo_name = request.GET.get('target_repo', source_repo_name) | |
106 |
target_path, target_id = parse_path_ref( |
|
108 | target_path, target_id = parse_path_ref( | |
|
109 | target_ref, default_path=request.GET.get('f_path', '')) | |||
107 |
|
110 | |||
|
111 | c.file_path = target_path | |||
108 | c.commit_statuses = ChangesetStatus.STATUSES |
|
112 | c.commit_statuses = ChangesetStatus.STATUSES | |
109 |
|
113 | |||
110 | # if merge is True |
|
114 | # if merge is True | |
@@ -115,7 +119,6 b' class CompareController(BaseRepoControll' | |||||
115 | # if merge is False |
|
119 | # if merge is False | |
116 | # Show a raw diff of source/target refs even if no ancestor exists |
|
120 | # Show a raw diff of source/target refs even if no ancestor exists | |
117 |
|
121 | |||
118 |
|
||||
119 | # c.fulldiff disables cut_off_limit |
|
122 | # c.fulldiff disables cut_off_limit | |
120 | c.fulldiff = str2bool(request.GET.get('fulldiff')) |
|
123 | c.fulldiff = str2bool(request.GET.get('fulldiff')) | |
121 |
|
124 | |||
@@ -131,7 +134,8 b' class CompareController(BaseRepoControll' | |||||
131 | target_repo=source_repo_name, |
|
134 | target_repo=source_repo_name, | |
132 | target_ref_type=source_ref_type, |
|
135 | target_ref_type=source_ref_type, | |
133 | target_ref=source_ref, |
|
136 | target_ref=source_ref, | |
134 |
merge=merge and '1' or '' |
|
137 | merge=merge and '1' or '', | |
|
138 | f_path=target_path) | |||
135 |
|
139 | |||
136 | source_repo = Repository.get_by_repo_name(source_repo_name) |
|
140 | source_repo = Repository.get_by_repo_name(source_repo_name) | |
137 | target_repo = Repository.get_by_repo_name(target_repo_name) |
|
141 | target_repo = Repository.get_by_repo_name(target_repo_name) | |
@@ -151,8 +155,11 b' class CompareController(BaseRepoControll' | |||||
151 | h.flash(msg, category='error') |
|
155 | h.flash(msg, category='error') | |
152 | return redirect(url('compare_home', repo_name=c.repo_name)) |
|
156 | return redirect(url('compare_home', repo_name=c.repo_name)) | |
153 |
|
157 | |||
154 |
source_ |
|
158 | source_scm = source_repo.scm_instance() | |
155 |
target_ |
|
159 | target_scm = target_repo.scm_instance() | |
|
160 | ||||
|
161 | source_alias = source_scm.alias | |||
|
162 | target_alias = target_scm.alias | |||
156 | if source_alias != target_alias: |
|
163 | if source_alias != target_alias: | |
157 | msg = _('The comparison of two different kinds of remote repos ' |
|
164 | msg = _('The comparison of two different kinds of remote repos ' | |
158 | 'is not available') |
|
165 | 'is not available') | |
@@ -175,11 +182,15 b' class CompareController(BaseRepoControll' | |||||
175 | c.source_ref_type = source_ref_type |
|
182 | c.source_ref_type = source_ref_type | |
176 | c.target_ref_type = target_ref_type |
|
183 | c.target_ref_type = target_ref_type | |
177 |
|
184 | |||
178 | source_scm = source_repo.scm_instance() |
|
|||
179 | target_scm = target_repo.scm_instance() |
|
|||
180 |
|
||||
181 | pre_load = ["author", "branch", "date", "message"] |
|
185 | pre_load = ["author", "branch", "date", "message"] | |
182 | c.ancestor = None |
|
186 | c.ancestor = None | |
|
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: | |||
183 | try: |
|
194 | try: | |
184 | c.commit_ranges = source_scm.compare( |
|
195 | c.commit_ranges = source_scm.compare( | |
185 | source_commit.raw_id, target_commit.raw_id, |
|
196 | source_commit.raw_id, target_commit.raw_id, | |
@@ -199,10 +210,14 b' class CompareController(BaseRepoControll' | |||||
199 | c.statuses = c.rhodecode_db_repo.statuses( |
|
210 | c.statuses = c.rhodecode_db_repo.statuses( | |
200 | [x.raw_id for x in c.commit_ranges]) |
|
211 | [x.raw_id for x in c.commit_ranges]) | |
201 |
|
212 | |||
|
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 | ||||
202 | if partial: # for PR ajax commits loader |
|
217 | if partial: # for PR ajax commits loader | |
203 | if not c.ancestor: |
|
218 | if not c.ancestor: | |
204 | return '' # cannot merge if there is no ancestor |
|
219 | return '' # cannot merge if there is no ancestor | |
205 |
return render('compare/compare_commits. |
|
220 | return render('compare/compare_commits.mako') | |
206 |
|
221 | |||
207 | if c.ancestor: |
|
222 | if c.ancestor: | |
208 | # case we want a simple diff without incoming commits, |
|
223 | # case we want a simple diff without incoming commits, | |
@@ -238,7 +253,8 b' class CompareController(BaseRepoControll' | |||||
238 |
|
253 | |||
239 | txtdiff = source_repo.scm_instance().get_diff( |
|
254 | txtdiff = source_repo.scm_instance().get_diff( | |
240 | commit1=source_commit, commit2=target_commit, |
|
255 | commit1=source_commit, commit2=target_commit, | |
241 |
path1=source_path |
|
256 | path=target_path, path1=source_path) | |
|
257 | ||||
242 | diff_processor = diffs.DiffProcessor( |
|
258 | diff_processor = diffs.DiffProcessor( | |
243 | txtdiff, format='newdiff', diff_limit=diff_limit, |
|
259 | txtdiff, format='newdiff', diff_limit=diff_limit, | |
244 | file_limit=file_limit, show_full_diff=c.fulldiff) |
|
260 | file_limit=file_limit, show_full_diff=c.fulldiff) | |
@@ -260,5 +276,7 b' class CompareController(BaseRepoControll' | |||||
260 | ).render_patchset(_parsed, source_ref, target_ref) |
|
276 | ).render_patchset(_parsed, source_ref, target_ref) | |
261 |
|
277 | |||
262 | c.preview_mode = merge |
|
278 | c.preview_mode = merge | |
|
279 | c.source_commit = source_commit | |||
|
280 | c.target_commit = target_commit | |||
263 |
|
281 | |||
264 |
return render('compare/compare_diff. |
|
282 | return render('compare/compare_diff.mako') |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2014-201 |
|
3 | # Copyright (C) 2014-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -144,7 +144,7 b' class FilesController(BaseRepoController' | |||||
144 | log.debug('Generating cached file tree for %s, %s, %s', |
|
144 | log.debug('Generating cached file tree for %s, %s, %s', | |
145 | repo_name, commit_id, f_path) |
|
145 | repo_name, commit_id, f_path) | |
146 | c.full_load = full_load |
|
146 | c.full_load = full_load | |
147 |
return render('files/files_browser_tree. |
|
147 | return render('files/files_browser_tree.mako') | |
148 |
|
148 | |||
149 | cache_manager = self.__get_tree_cache_manager( |
|
149 | cache_manager = self.__get_tree_cache_manager( | |
150 | repo_name, caches.FILE_TREE) |
|
150 | repo_name, caches.FILE_TREE) | |
@@ -255,9 +255,9 b' class FilesController(BaseRepoController' | |||||
255 | raise HTTPNotFound() |
|
255 | raise HTTPNotFound() | |
256 |
|
256 | |||
257 | if request.environ.get('HTTP_X_PJAX'): |
|
257 | if request.environ.get('HTTP_X_PJAX'): | |
258 |
return render('files/files_pjax. |
|
258 | return render('files/files_pjax.mako') | |
259 |
|
259 | |||
260 |
return render('files/files. |
|
260 | return render('files/files.mako') | |
261 |
|
261 | |||
262 | @LoginRequired() |
|
262 | @LoginRequired() | |
263 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', |
|
263 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', | |
@@ -305,7 +305,7 b' class FilesController(BaseRepoController' | |||||
305 | c.authors.append(( |
|
305 | c.authors.append(( | |
306 | h.email(author), |
|
306 | h.email(author), | |
307 | h.person(author, 'username_or_name_or_email'))) |
|
307 | h.person(author, 'username_or_name_or_email'))) | |
308 |
return render('files/file_authors_box. |
|
308 | return render('files/file_authors_box.mako') | |
309 |
|
309 | |||
310 | @LoginRequired() |
|
310 | @LoginRequired() | |
311 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', |
|
311 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', | |
@@ -465,7 +465,7 b' class FilesController(BaseRepoController' | |||||
465 | 'Deleted file %s via RhodeCode Enterprise') % (f_path) |
|
465 | 'Deleted file %s via RhodeCode Enterprise') % (f_path) | |
466 | c.f_path = f_path |
|
466 | c.f_path = f_path | |
467 |
|
467 | |||
468 |
return render('files/files_delete. |
|
468 | return render('files/files_delete.mako') | |
469 |
|
469 | |||
470 | @CSRFRequired() |
|
470 | @CSRFRequired() | |
471 | @LoginRequired() |
|
471 | @LoginRequired() | |
@@ -574,7 +574,7 b' class FilesController(BaseRepoController' | |||||
574 | 'Edited file %s via RhodeCode Enterprise') % (f_path) |
|
574 | 'Edited file %s via RhodeCode Enterprise') % (f_path) | |
575 | c.f_path = f_path |
|
575 | c.f_path = f_path | |
576 |
|
576 | |||
577 |
return render('files/files_edit. |
|
577 | return render('files/files_edit.mako') | |
578 |
|
578 | |||
579 | def _is_valid_head(self, commit_id, repo): |
|
579 | def _is_valid_head(self, commit_id, repo): | |
580 | # check if commit is a branch identifier- basically we cannot |
|
580 | # check if commit is a branch identifier- basically we cannot | |
@@ -700,7 +700,7 b' class FilesController(BaseRepoController' | |||||
700 | c.default_message = (_('Added file via RhodeCode Enterprise')) |
|
700 | c.default_message = (_('Added file via RhodeCode Enterprise')) | |
701 | c.f_path = f_path |
|
701 | c.f_path = f_path | |
702 |
|
702 | |||
703 |
return render('files/files_add. |
|
703 | return render('files/files_add.mako') | |
704 |
|
704 | |||
705 | @LoginRequired() |
|
705 | @LoginRequired() | |
706 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', |
|
706 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', | |
@@ -799,21 +799,15 b' class FilesController(BaseRepoController' | |||||
799 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', |
|
799 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', | |
800 | 'repository.admin') |
|
800 | 'repository.admin') | |
801 | def diff(self, repo_name, f_path): |
|
801 | def diff(self, repo_name, f_path): | |
802 | ignore_whitespace = request.GET.get('ignorews') == '1' |
|
802 | ||
803 |
|
|
803 | c.action = request.GET.get('diff') | |
804 | diff1 = request.GET.get('diff1', '') |
|
804 | diff1 = request.GET.get('diff1', '') | |
|
805 | diff2 = request.GET.get('diff2', '') | |||
805 |
|
806 | |||
806 | path1, diff1 = parse_path_ref(diff1, default_path=f_path) |
|
807 | path1, diff1 = parse_path_ref(diff1, default_path=f_path) | |
807 |
|
808 | |||
808 | diff2 = request.GET.get('diff2', '') |
|
809 | ignore_whitespace = str2bool(request.GET.get('ignorews')) | |
809 |
|
|
810 | line_context = request.GET.get('context', 3) | |
810 | c.no_changes = diff1 == diff2 |
|
|||
811 | c.f_path = f_path |
|
|||
812 | c.big_diff = False |
|
|||
813 | c.ignorews_url = _ignorews_url |
|
|||
814 | c.context_url = _context_url |
|
|||
815 | c.changes = OrderedDict() |
|
|||
816 | c.changes[diff2] = [] |
|
|||
817 |
|
811 | |||
818 | if not any((diff1, diff2)): |
|
812 | if not any((diff1, diff2)): | |
819 | h.flash( |
|
813 | h.flash( | |
@@ -821,18 +815,16 b' class FilesController(BaseRepoController' | |||||
821 | category='error') |
|
815 | category='error') | |
822 | raise HTTPBadRequest() |
|
816 | raise HTTPBadRequest() | |
823 |
|
817 | |||
824 | # special case if we want a show commit_id only, it's impl here |
|
818 | if c.action not in ['download', 'raw']: | |
825 | # to reduce JS and callbacks |
|
819 | # redirect to new view if we render diff | |
826 |
|
820 | return redirect( | ||
827 | if request.GET.get('show_rev') and diff1: |
|
821 | url('compare_url', repo_name=repo_name, | |
828 | if str2bool(request.GET.get('annotate', 'False')): |
|
822 | source_ref_type='rev', | |
829 | _url = url('files_annotate_home', repo_name=c.repo_name, |
|
823 | source_ref=diff1, | |
830 | revision=diff1, f_path=path1) |
|
824 | target_repo=c.repo_name, | |
831 | else: |
|
825 | target_ref_type='rev', | |
832 | _url = url('files_home', repo_name=c.repo_name, |
|
826 | target_ref=diff2, | |
833 |
|
|
827 | f_path=f_path)) | |
834 |
|
||||
835 | return redirect(_url) |
|
|||
836 |
|
828 | |||
837 | try: |
|
829 | try: | |
838 | node1 = self._get_file_node(diff1, path1) |
|
830 | node1 = self._get_file_node(diff1, path1) | |
@@ -877,98 +869,40 b' class FilesController(BaseRepoController' | |||||
877 | return diff.as_raw() |
|
869 | return diff.as_raw() | |
878 |
|
870 | |||
879 | else: |
|
871 | else: | |
880 | fid = h.FID(diff2, node2.path) |
|
872 | return redirect( | |
881 | line_context_lcl = get_line_ctx(fid, request.GET) |
|
873 | url('compare_url', repo_name=repo_name, | |
882 | ign_whitespace_lcl = get_ignore_ws(fid, request.GET) |
|
874 | source_ref_type='rev', | |
883 |
|
875 | source_ref=diff1, | ||
884 | __, commit1, commit2, diff, st, data = diffs.wrapped_diff( |
|
876 | target_repo=c.repo_name, | |
885 | filenode_old=node1, |
|
877 | target_ref_type='rev', | |
886 | filenode_new=node2, |
|
878 | target_ref=diff2, | |
887 | diff_limit=self.cut_off_limit_diff, |
|
879 | f_path=f_path)) | |
888 | file_limit=self.cut_off_limit_file, |
|
|||
889 | show_full_diff=request.GET.get('fulldiff'), |
|
|||
890 | ignore_whitespace=ign_whitespace_lcl, |
|
|||
891 | line_context=line_context_lcl,) |
|
|||
892 |
|
||||
893 | c.lines_added = data['stats']['added'] if data else 0 |
|
|||
894 | c.lines_deleted = data['stats']['deleted'] if data else 0 |
|
|||
895 | c.files = [data] |
|
|||
896 | c.commit_ranges = [c.commit_1, c.commit_2] |
|
|||
897 | c.ancestor = None |
|
|||
898 | c.statuses = [] |
|
|||
899 | c.target_repo = c.rhodecode_db_repo |
|
|||
900 | c.filename1 = node1.path |
|
|||
901 | c.filename = node2.path |
|
|||
902 | c.binary_file = node1.is_binary or node2.is_binary |
|
|||
903 | operation = data['operation'] if data else '' |
|
|||
904 |
|
||||
905 | commit_changes = { |
|
|||
906 | # TODO: it's passing the old file to the diff to keep the |
|
|||
907 | # standard but this is not being used for this template, |
|
|||
908 | # but might need both files in the future or a more standard |
|
|||
909 | # way to work with that |
|
|||
910 | 'fid': [commit1, commit2, operation, |
|
|||
911 | c.filename, diff, st, data] |
|
|||
912 | } |
|
|||
913 |
|
||||
914 | c.changes = commit_changes |
|
|||
915 |
|
||||
916 | return render('files/file_diff.html') |
|
|||
917 |
|
880 | |||
918 | @LoginRequired() |
|
881 | @LoginRequired() | |
919 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', |
|
882 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', | |
920 | 'repository.admin') |
|
883 | 'repository.admin') | |
921 | def diff_2way(self, repo_name, f_path): |
|
884 | def diff_2way(self, repo_name, f_path): | |
|
885 | """ | |||
|
886 | Kept only to make OLD links work | |||
|
887 | """ | |||
922 | diff1 = request.GET.get('diff1', '') |
|
888 | diff1 = request.GET.get('diff1', '') | |
923 | diff2 = request.GET.get('diff2', '') |
|
889 | diff2 = request.GET.get('diff2', '') | |
924 |
|
890 | |||
925 | nodes = [] |
|
891 | if not any((diff1, diff2)): | |
926 | unknown_commits = [] |
|
892 | h.flash( | |
927 | for commit in [diff1, diff2]: |
|
893 | 'Need query parameter "diff1" or "diff2" to generate a diff.', | |
928 |
|
|
894 | category='error') | |
929 | nodes.append(self._get_file_node(commit, f_path)) |
|
895 | raise HTTPBadRequest() | |
930 | except (RepositoryError, NodeError): |
|
|||
931 | log.exception('%(commit)s does not exist' % {'commit': commit}) |
|
|||
932 | unknown_commits.append(commit) |
|
|||
933 | h.flash(h.literal( |
|
|||
934 | _('Commit %(commit)s does not exist.') % {'commit': commit} |
|
|||
935 | ), category='error') |
|
|||
936 |
|
||||
937 | if unknown_commits: |
|
|||
938 | return redirect(url('files_home', repo_name=c.repo_name, |
|
|||
939 | f_path=f_path)) |
|
|||
940 |
|
||||
941 | if all(isinstance(node.commit, EmptyCommit) for node in nodes): |
|
|||
942 | raise HTTPNotFound |
|
|||
943 |
|
||||
944 | node1, node2 = nodes |
|
|||
945 |
|
896 | |||
946 | f_gitdiff = diffs.get_gitdiff(node1, node2, ignore_whitespace=False) |
|
897 | return redirect( | |
947 | diff_processor = diffs.DiffProcessor(f_gitdiff, format='gitdiff') |
|
898 | url('compare_url', repo_name=repo_name, | |
948 | diff_data = diff_processor.prepare() |
|
899 | source_ref_type='rev', | |
949 |
|
900 | source_ref=diff1, | ||
950 | if not diff_data or diff_data[0]['raw_diff'] == '': |
|
901 | target_repo=c.repo_name, | |
951 | h.flash(h.literal(_('%(file_path)s has not changed ' |
|
902 | target_ref_type='rev', | |
952 | 'between %(commit_1)s and %(commit_2)s.') % { |
|
903 | target_ref=diff2, | |
953 |
|
|
904 | f_path=f_path, | |
954 | 'commit_1': node1.commit.id, |
|
905 | diffmode='sideside')) | |
955 | 'commit_2': node2.commit.id |
|
|||
956 | }), category='error') |
|
|||
957 | return redirect(url('files_home', repo_name=c.repo_name, |
|
|||
958 | f_path=f_path)) |
|
|||
959 |
|
||||
960 | c.diff_data = diff_data[0] |
|
|||
961 | c.FID = h.FID(diff2, node2.path) |
|
|||
962 | # cleanup some unneeded data |
|
|||
963 | del c.diff_data['raw_diff'] |
|
|||
964 | del c.diff_data['chunks'] |
|
|||
965 |
|
||||
966 | c.node1 = node1 |
|
|||
967 | c.commit_1 = node1.commit |
|
|||
968 | c.node2 = node2 |
|
|||
969 | c.commit_2 = node2.commit |
|
|||
970 |
|
||||
971 | return render('files/diff_2way.html') |
|
|||
972 |
|
906 | |||
973 | def _get_file_node(self, commit_id, f_path): |
|
907 | def _get_file_node(self, commit_id, f_path): | |
974 | if commit_id not in ['', None, 'None', '0' * 12, '0' * 40]: |
|
908 | if commit_id not in ['', None, 'None', '0' * 12, '0' * 40]: |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -50,9 +50,9 b' class FollowersController(BaseRepoContro' | |||||
50 | .order_by(UserFollowing.follows_from) |
|
50 | .order_by(UserFollowing.follows_from) | |
51 | c.followers_pager = Page(d, page=p, items_per_page=20) |
|
51 | c.followers_pager = Page(d, page=p, items_per_page=20) | |
52 |
|
52 | |||
53 |
c.followers_data = render('/followers/followers_data. |
|
53 | c.followers_data = render('/followers/followers_data.mako') | |
54 |
|
54 | |||
55 | if request.environ.get('HTTP_X_PJAX'): |
|
55 | if request.environ.get('HTTP_X_PJAX'): | |
56 | return c.followers_data |
|
56 | return c.followers_data | |
57 |
|
57 | |||
58 |
return render('/followers/followers. |
|
58 | return render('/followers/followers.mako') |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2011-201 |
|
3 | # Copyright (C) 2011-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -122,12 +122,12 b' class ForksController(BaseRepoController' | |||||
122 | d.append(r) |
|
122 | d.append(r) | |
123 | c.forks_pager = Page(d, page=p, items_per_page=20) |
|
123 | c.forks_pager = Page(d, page=p, items_per_page=20) | |
124 |
|
124 | |||
125 |
c.forks_data = render('/forks/forks_data. |
|
125 | c.forks_data = render('/forks/forks_data.mako') | |
126 |
|
126 | |||
127 | if request.environ.get('HTTP_X_PJAX'): |
|
127 | if request.environ.get('HTTP_X_PJAX'): | |
128 | return c.forks_data |
|
128 | return c.forks_data | |
129 |
|
129 | |||
130 |
return render('/forks/forks. |
|
130 | return render('/forks/forks.mako') | |
131 |
|
131 | |||
132 | @LoginRequired() |
|
132 | @LoginRequired() | |
133 | @NotAnonymous() |
|
133 | @NotAnonymous() | |
@@ -144,7 +144,7 b' class ForksController(BaseRepoController' | |||||
144 | defaults = self.__load_data(repo_name) |
|
144 | defaults = self.__load_data(repo_name) | |
145 |
|
145 | |||
146 | return htmlfill.render( |
|
146 | return htmlfill.render( | |
147 |
render('forks/fork. |
|
147 | render('forks/fork.mako'), | |
148 | defaults=defaults, |
|
148 | defaults=defaults, | |
149 | encoding="UTF-8", |
|
149 | encoding="UTF-8", | |
150 | force_defaults=False |
|
150 | force_defaults=False | |
@@ -177,7 +177,7 b' class ForksController(BaseRepoController' | |||||
177 | except formencode.Invalid as errors: |
|
177 | except formencode.Invalid as errors: | |
178 | c.new_repo = errors.value['repo_name'] |
|
178 | c.new_repo = errors.value['repo_name'] | |
179 | return htmlfill.render( |
|
179 | return htmlfill.render( | |
180 |
render('forks/fork. |
|
180 | render('forks/fork.mako'), | |
181 | defaults=errors.value, |
|
181 | defaults=errors.value, | |
182 | errors=errors.error_dict or {}, |
|
182 | errors=errors.error_dict or {}, | |
183 | prefix_error=False, |
|
183 | prefix_error=False, |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -97,7 +97,7 b' class HomeController(BaseController):' | |||||
97 | c.repos_data = json.dumps(repo_data) |
|
97 | c.repos_data = json.dumps(repo_data) | |
98 | c.repo_groups_data = json.dumps(repo_group_data) |
|
98 | c.repo_groups_data = json.dumps(repo_group_data) | |
99 |
|
99 | |||
100 |
return render('/index. |
|
100 | return render('/index.mako') | |
101 |
|
101 | |||
102 | @LoginRequired() |
|
102 | @LoginRequired() | |
103 | @HasRepoGroupPermissionAnyDecorator('group.read', 'group.write', |
|
103 | @HasRepoGroupPermissionAnyDecorator('group.read', 'group.write', | |
@@ -112,7 +112,7 b' class HomeController(BaseController):' | |||||
112 | c.repos_data = json.dumps(repo_data) |
|
112 | c.repos_data = json.dumps(repo_data) | |
113 | c.repo_groups_data = json.dumps(repo_group_data) |
|
113 | c.repo_groups_data = json.dumps(repo_group_data) | |
114 |
|
114 | |||
115 |
return render('index_repo_group. |
|
115 | return render('index_repo_group.mako') | |
116 |
|
116 | |||
117 | def _get_repo_list(self, name_contains=None, repo_type=None, limit=20): |
|
117 | def _get_repo_list(self, name_contains=None, repo_type=None, limit=20): | |
118 | query = Repository.query()\ |
|
118 | query = Repository.query()\ |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -205,11 +205,11 b' class JournalController(BaseController):' | |||||
205 | c.journal_pager = Page(journal, page=p, items_per_page=20, url=url_generator) |
|
205 | c.journal_pager = Page(journal, page=p, items_per_page=20, url=url_generator) | |
206 | c.journal_day_aggreagate = self._get_daily_aggregate(c.journal_pager) |
|
206 | c.journal_day_aggreagate = self._get_daily_aggregate(c.journal_pager) | |
207 |
|
207 | |||
208 |
c.journal_data = render('journal/journal_data. |
|
208 | c.journal_data = render('journal/journal_data.mako') | |
209 | if request.is_xhr: |
|
209 | if request.is_xhr: | |
210 | return c.journal_data |
|
210 | return c.journal_data | |
211 |
|
211 | |||
212 |
return render('journal/journal. |
|
212 | return render('journal/journal.mako') | |
213 |
|
213 | |||
214 | @LoginRequired(auth_token_access=True) |
|
214 | @LoginRequired(auth_token_access=True) | |
215 | @NotAnonymous() |
|
215 | @NotAnonymous() | |
@@ -276,10 +276,10 b' class JournalController(BaseController):' | |||||
276 |
|
276 | |||
277 | c.journal_day_aggreagate = self._get_daily_aggregate(c.journal_pager) |
|
277 | c.journal_day_aggreagate = self._get_daily_aggregate(c.journal_pager) | |
278 |
|
278 | |||
279 |
c.journal_data = render('journal/journal_data. |
|
279 | c.journal_data = render('journal/journal_data.mako') | |
280 | if request.is_xhr: |
|
280 | if request.is_xhr: | |
281 | return c.journal_data |
|
281 | return c.journal_data | |
282 |
return render('journal/public_journal. |
|
282 | return render('journal/public_journal.mako') | |
283 |
|
283 | |||
284 | @LoginRequired(auth_token_access=True) |
|
284 | @LoginRequired(auth_token_access=True) | |
285 | def public_journal_atom(self): |
|
285 | def public_journal_atom(self): |
This diff has been collapsed as it changes many lines, (524 lines changed) Show them Hide them | |||||
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2012-201 |
|
3 | # Copyright (C) 2012-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -21,10 +21,12 b'' | |||||
21 | """ |
|
21 | """ | |
22 | pull requests controller for rhodecode for initializing pull requests |
|
22 | pull requests controller for rhodecode for initializing pull requests | |
23 | """ |
|
23 | """ | |
|
24 | import types | |||
24 |
|
25 | |||
25 | import peppercorn |
|
26 | import peppercorn | |
26 | import formencode |
|
27 | import formencode | |
27 | import logging |
|
28 | import logging | |
|
29 | import collections | |||
28 |
|
30 | |||
29 | from webob.exc import HTTPNotFound, HTTPForbidden, HTTPBadRequest |
|
31 | from webob.exc import HTTPNotFound, HTTPForbidden, HTTPBadRequest | |
30 | from pylons import request, tmpl_context as c, url |
|
32 | from pylons import request, tmpl_context as c, url | |
@@ -43,125 +45,31 b' from rhodecode.lib.auth import (' | |||||
43 | LoginRequired, HasRepoPermissionAnyDecorator, NotAnonymous, |
|
45 | LoginRequired, HasRepoPermissionAnyDecorator, NotAnonymous, | |
44 | HasAcceptedRepoType, XHRRequired) |
|
46 | HasAcceptedRepoType, XHRRequired) | |
45 | from rhodecode.lib.channelstream import channelstream_request |
|
47 | from rhodecode.lib.channelstream import channelstream_request | |
46 | from rhodecode.lib.compat import OrderedDict |
|
|||
47 | from rhodecode.lib.utils import jsonify |
|
48 | from rhodecode.lib.utils import jsonify | |
48 |
from rhodecode.lib.utils2 import |
|
49 | from rhodecode.lib.utils2 import ( | |
49 | from rhodecode.lib.vcs.backends.base import EmptyCommit, UpdateFailureReason |
|
50 | safe_int, safe_str, str2bool, safe_unicode) | |
|
51 | from rhodecode.lib.vcs.backends.base import ( | |||
|
52 | EmptyCommit, UpdateFailureReason, EmptyRepository) | |||
50 | from rhodecode.lib.vcs.exceptions import ( |
|
53 | from rhodecode.lib.vcs.exceptions import ( | |
51 | EmptyRepositoryError, CommitDoesNotExistError, RepositoryRequirementError, |
|
54 | EmptyRepositoryError, CommitDoesNotExistError, RepositoryRequirementError, | |
52 | NodeDoesNotExistError) |
|
55 | NodeDoesNotExistError) | |
53 | from rhodecode.lib.diffs import LimitedDiffContainer |
|
56 | ||
54 | from rhodecode.model.changeset_status import ChangesetStatusModel |
|
57 | from rhodecode.model.changeset_status import ChangesetStatusModel | |
55 |
from rhodecode.model.comment import |
|
58 | from rhodecode.model.comment import CommentsModel | |
56 |
from rhodecode.model.db import PullRequest, ChangesetStatus, ChangesetComment, |
|
59 | from rhodecode.model.db import (PullRequest, ChangesetStatus, ChangesetComment, | |
57 | Repository |
|
60 | Repository, PullRequestVersion) | |
58 | from rhodecode.model.forms import PullRequestForm |
|
61 | from rhodecode.model.forms import PullRequestForm | |
59 | from rhodecode.model.meta import Session |
|
62 | from rhodecode.model.meta import Session | |
60 | from rhodecode.model.pull_request import PullRequestModel |
|
63 | from rhodecode.model.pull_request import PullRequestModel, MergeCheck | |
61 |
|
64 | |||
62 | log = logging.getLogger(__name__) |
|
65 | log = logging.getLogger(__name__) | |
63 |
|
66 | |||
64 |
|
67 | |||
65 | class PullrequestsController(BaseRepoController): |
|
68 | class PullrequestsController(BaseRepoController): | |
|
69 | ||||
66 | def __before__(self): |
|
70 | def __before__(self): | |
67 | super(PullrequestsController, self).__before__() |
|
71 | super(PullrequestsController, self).__before__() | |
68 |
|
72 | |||
69 | def _load_compare_data(self, pull_request, inline_comments, enable_comments=True): |
|
|||
70 | """ |
|
|||
71 | Load context data needed for generating compare diff |
|
|||
72 |
|
||||
73 | :param pull_request: object related to the request |
|
|||
74 | :param enable_comments: flag to determine if comments are included |
|
|||
75 | """ |
|
|||
76 | source_repo = pull_request.source_repo |
|
|||
77 | source_ref_id = pull_request.source_ref_parts.commit_id |
|
|||
78 |
|
||||
79 | target_repo = pull_request.target_repo |
|
|||
80 | target_ref_id = pull_request.target_ref_parts.commit_id |
|
|||
81 |
|
||||
82 | # despite opening commits for bookmarks/branches/tags, we always |
|
|||
83 | # convert this to rev to prevent changes after bookmark or branch change |
|
|||
84 | c.source_ref_type = 'rev' |
|
|||
85 | c.source_ref = source_ref_id |
|
|||
86 |
|
||||
87 | c.target_ref_type = 'rev' |
|
|||
88 | c.target_ref = target_ref_id |
|
|||
89 |
|
||||
90 | c.source_repo = source_repo |
|
|||
91 | c.target_repo = target_repo |
|
|||
92 |
|
||||
93 | c.fulldiff = bool(request.GET.get('fulldiff')) |
|
|||
94 |
|
||||
95 | # diff_limit is the old behavior, will cut off the whole diff |
|
|||
96 | # if the limit is applied otherwise will just hide the |
|
|||
97 | # big files from the front-end |
|
|||
98 | diff_limit = self.cut_off_limit_diff |
|
|||
99 | file_limit = self.cut_off_limit_file |
|
|||
100 |
|
||||
101 | pre_load = ["author", "branch", "date", "message"] |
|
|||
102 |
|
||||
103 | c.commit_ranges = [] |
|
|||
104 | source_commit = EmptyCommit() |
|
|||
105 | target_commit = EmptyCommit() |
|
|||
106 | c.missing_requirements = False |
|
|||
107 | try: |
|
|||
108 | c.commit_ranges = [ |
|
|||
109 | source_repo.get_commit(commit_id=rev, pre_load=pre_load) |
|
|||
110 | for rev in pull_request.revisions] |
|
|||
111 |
|
||||
112 | c.statuses = source_repo.statuses( |
|
|||
113 | [x.raw_id for x in c.commit_ranges]) |
|
|||
114 |
|
||||
115 | target_commit = source_repo.get_commit( |
|
|||
116 | commit_id=safe_str(target_ref_id)) |
|
|||
117 | source_commit = source_repo.get_commit( |
|
|||
118 | commit_id=safe_str(source_ref_id)) |
|
|||
119 | except RepositoryRequirementError: |
|
|||
120 | c.missing_requirements = True |
|
|||
121 |
|
||||
122 | c.changes = {} |
|
|||
123 | c.missing_commits = False |
|
|||
124 | if (c.missing_requirements or |
|
|||
125 | isinstance(source_commit, EmptyCommit) or |
|
|||
126 | source_commit == target_commit): |
|
|||
127 | _parsed = [] |
|
|||
128 | c.missing_commits = True |
|
|||
129 | else: |
|
|||
130 | vcs_diff = PullRequestModel().get_diff(pull_request) |
|
|||
131 | diff_processor = diffs.DiffProcessor( |
|
|||
132 | vcs_diff, format='newdiff', diff_limit=diff_limit, |
|
|||
133 | file_limit=file_limit, show_full_diff=c.fulldiff) |
|
|||
134 | _parsed = diff_processor.prepare() |
|
|||
135 |
|
||||
136 | commit_changes = OrderedDict() |
|
|||
137 | _parsed = diff_processor.prepare() |
|
|||
138 | c.limited_diff = isinstance(_parsed, diffs.LimitedDiffContainer) |
|
|||
139 |
|
||||
140 | _parsed = diff_processor.prepare() |
|
|||
141 |
|
||||
142 | def _node_getter(commit): |
|
|||
143 | def get_node(fname): |
|
|||
144 | try: |
|
|||
145 | return commit.get_node(fname) |
|
|||
146 | except NodeDoesNotExistError: |
|
|||
147 | return None |
|
|||
148 | return get_node |
|
|||
149 |
|
||||
150 | c.diffset = codeblocks.DiffSet( |
|
|||
151 | repo_name=c.repo_name, |
|
|||
152 | source_node_getter=_node_getter(target_commit), |
|
|||
153 | target_node_getter=_node_getter(source_commit), |
|
|||
154 | comments=inline_comments |
|
|||
155 | ).render_patchset(_parsed, target_commit.raw_id, source_commit.raw_id) |
|
|||
156 |
|
||||
157 | c.included_files = [] |
|
|||
158 | c.deleted_files = [] |
|
|||
159 |
|
||||
160 | for f in _parsed: |
|
|||
161 | st = f['stats'] |
|
|||
162 | fid = h.FID('', f['filename']) |
|
|||
163 | c.included_files.append(f['filename']) |
|
|||
164 |
|
||||
165 | def _extract_ordering(self, request): |
|
73 | def _extract_ordering(self, request): | |
166 | column_index = safe_int(request.GET.get('order[0][column]')) |
|
74 | column_index = safe_int(request.GET.get('order[0][column]')) | |
167 | order_dir = request.GET.get('order[0][dir]', 'desc') |
|
75 | order_dir = request.GET.get('order[0][dir]', 'desc') | |
@@ -205,7 +113,7 b' class PullrequestsController(BaseRepoCon' | |||||
205 | if not request.is_xhr: |
|
113 | if not request.is_xhr: | |
206 | c.data = json.dumps(data['data']) |
|
114 | c.data = json.dumps(data['data']) | |
207 | c.records_total = data['recordsTotal'] |
|
115 | c.records_total = data['recordsTotal'] | |
208 |
return render('/pullrequests/pullrequests. |
|
116 | return render('/pullrequests/pullrequests.mako') | |
209 | else: |
|
117 | else: | |
210 | return json.dumps(data) |
|
118 | return json.dumps(data) | |
211 |
|
119 | |||
@@ -244,10 +152,10 b' class PullrequestsController(BaseRepoCon' | |||||
244 | opened_by=opened_by) |
|
152 | opened_by=opened_by) | |
245 |
|
153 | |||
246 | from rhodecode.lib.utils import PartialRenderer |
|
154 | from rhodecode.lib.utils import PartialRenderer | |
247 |
_render = PartialRenderer('data_table/_dt_elements. |
|
155 | _render = PartialRenderer('data_table/_dt_elements.mako') | |
248 | data = [] |
|
156 | data = [] | |
249 | for pr in pull_requests: |
|
157 | for pr in pull_requests: | |
250 |
comments = |
|
158 | comments = CommentsModel().get_all_comments( | |
251 | c.rhodecode_db_repo.repo_id, pull_request=pr) |
|
159 | c.rhodecode_db_repo.repo_id, pull_request=pr) | |
252 |
|
160 | |||
253 | data.append({ |
|
161 | data.append({ | |
@@ -336,7 +244,7 b' class PullrequestsController(BaseRepoCon' | |||||
336 | } |
|
244 | } | |
337 | c.default_source_ref = selected_source_ref |
|
245 | c.default_source_ref = selected_source_ref | |
338 |
|
246 | |||
339 |
return render('/pullrequests/pullrequest. |
|
247 | return render('/pullrequests/pullrequest.mako') | |
340 |
|
248 | |||
341 | @LoginRequired() |
|
249 | @LoginRequired() | |
342 | @NotAnonymous() |
|
250 | @NotAnonymous() | |
@@ -586,14 +494,20 b' class PullrequestsController(BaseRepoCon' | |||||
586 |
|
494 | |||
587 | Merge will perform a server-side merge of the specified |
|
495 | Merge will perform a server-side merge of the specified | |
588 | pull request, if the pull request is approved and mergeable. |
|
496 | pull request, if the pull request is approved and mergeable. | |
589 |
After succesfu |
|
497 | After successful merging, the pull request is automatically | |
590 | closed, with a relevant comment. |
|
498 | closed, with a relevant comment. | |
591 | """ |
|
499 | """ | |
592 | pull_request_id = safe_int(pull_request_id) |
|
500 | pull_request_id = safe_int(pull_request_id) | |
593 | pull_request = PullRequest.get_or_404(pull_request_id) |
|
501 | pull_request = PullRequest.get_or_404(pull_request_id) | |
594 | user = c.rhodecode_user |
|
502 | user = c.rhodecode_user | |
595 |
|
503 | |||
596 |
|
|
504 | check = MergeCheck.validate(pull_request, user) | |
|
505 | merge_possible = not check.failed | |||
|
506 | ||||
|
507 | for err_type, error_msg in check.errors: | |||
|
508 | h.flash(error_msg, category=err_type) | |||
|
509 | ||||
|
510 | if merge_possible: | |||
597 | log.debug("Pre-conditions checked, trying to merge.") |
|
511 | log.debug("Pre-conditions checked, trying to merge.") | |
598 | extras = vcs_operation_context( |
|
512 | extras = vcs_operation_context( | |
599 | request.environ, repo_name=pull_request.target_repo.repo_name, |
|
513 | request.environ, repo_name=pull_request.target_repo.repo_name, | |
@@ -606,24 +520,6 b' class PullrequestsController(BaseRepoCon' | |||||
606 | repo_name=pull_request.target_repo.repo_name, |
|
520 | repo_name=pull_request.target_repo.repo_name, | |
607 | pull_request_id=pull_request.pull_request_id)) |
|
521 | pull_request_id=pull_request.pull_request_id)) | |
608 |
|
522 | |||
609 | def _meets_merge_pre_conditions(self, pull_request, user): |
|
|||
610 | if not PullRequestModel().check_user_merge(pull_request, user): |
|
|||
611 | raise HTTPForbidden() |
|
|||
612 |
|
||||
613 | merge_status, msg = PullRequestModel().merge_status(pull_request) |
|
|||
614 | if not merge_status: |
|
|||
615 | log.debug("Cannot merge, not mergeable.") |
|
|||
616 | h.flash(msg, category='error') |
|
|||
617 | return False |
|
|||
618 |
|
||||
619 | if (pull_request.calculated_review_status() |
|
|||
620 | is not ChangesetStatus.STATUS_APPROVED): |
|
|||
621 | log.debug("Cannot merge, approval is pending.") |
|
|||
622 | msg = _('Pull request reviewer approval is pending.') |
|
|||
623 | h.flash(msg, category='error') |
|
|||
624 | return False |
|
|||
625 | return True |
|
|||
626 |
|
||||
627 | def _merge_pull_request(self, pull_request, user, extras): |
|
523 | def _merge_pull_request(self, pull_request, user, extras): | |
628 | merge_resp = PullRequestModel().merge( |
|
524 | merge_resp = PullRequestModel().merge( | |
629 | pull_request, user, extras=extras) |
|
525 | pull_request, user, extras=extras) | |
@@ -675,82 +571,295 b' class PullrequestsController(BaseRepoCon' | |||||
675 | return redirect(url('my_account_pullrequests')) |
|
571 | return redirect(url('my_account_pullrequests')) | |
676 | raise HTTPForbidden() |
|
572 | raise HTTPForbidden() | |
677 |
|
573 | |||
|
574 | def _get_pr_version(self, pull_request_id, version=None): | |||
|
575 | pull_request_id = safe_int(pull_request_id) | |||
|
576 | at_version = None | |||
|
577 | ||||
|
578 | if version and version == 'latest': | |||
|
579 | pull_request_ver = PullRequest.get(pull_request_id) | |||
|
580 | pull_request_obj = pull_request_ver | |||
|
581 | _org_pull_request_obj = pull_request_obj | |||
|
582 | at_version = 'latest' | |||
|
583 | elif version: | |||
|
584 | pull_request_ver = PullRequestVersion.get_or_404(version) | |||
|
585 | pull_request_obj = pull_request_ver | |||
|
586 | _org_pull_request_obj = pull_request_ver.pull_request | |||
|
587 | at_version = pull_request_ver.pull_request_version_id | |||
|
588 | else: | |||
|
589 | _org_pull_request_obj = pull_request_obj = PullRequest.get_or_404(pull_request_id) | |||
|
590 | ||||
|
591 | pull_request_display_obj = PullRequest.get_pr_display_object( | |||
|
592 | pull_request_obj, _org_pull_request_obj) | |||
|
593 | ||||
|
594 | return _org_pull_request_obj, pull_request_obj, \ | |||
|
595 | pull_request_display_obj, at_version | |||
|
596 | ||||
|
597 | def _get_diffset( | |||
|
598 | self, source_repo, source_ref_id, target_ref_id, target_commit, | |||
|
599 | source_commit, diff_limit, file_limit, display_inline_comments): | |||
|
600 | vcs_diff = PullRequestModel().get_diff( | |||
|
601 | source_repo, source_ref_id, target_ref_id) | |||
|
602 | ||||
|
603 | diff_processor = diffs.DiffProcessor( | |||
|
604 | vcs_diff, format='newdiff', diff_limit=diff_limit, | |||
|
605 | file_limit=file_limit, show_full_diff=c.fulldiff) | |||
|
606 | ||||
|
607 | _parsed = diff_processor.prepare() | |||
|
608 | ||||
|
609 | def _node_getter(commit): | |||
|
610 | def get_node(fname): | |||
|
611 | try: | |||
|
612 | return commit.get_node(fname) | |||
|
613 | except NodeDoesNotExistError: | |||
|
614 | return None | |||
|
615 | ||||
|
616 | return get_node | |||
|
617 | ||||
|
618 | diffset = codeblocks.DiffSet( | |||
|
619 | repo_name=c.repo_name, | |||
|
620 | source_repo_name=c.source_repo.repo_name, | |||
|
621 | source_node_getter=_node_getter(target_commit), | |||
|
622 | target_node_getter=_node_getter(source_commit), | |||
|
623 | comments=display_inline_comments | |||
|
624 | ) | |||
|
625 | diffset = diffset.render_patchset( | |||
|
626 | _parsed, target_commit.raw_id, source_commit.raw_id) | |||
|
627 | ||||
|
628 | return diffset | |||
|
629 | ||||
678 | @LoginRequired() |
|
630 | @LoginRequired() | |
679 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', |
|
631 | @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', | |
680 | 'repository.admin') |
|
632 | 'repository.admin') | |
681 | def show(self, repo_name, pull_request_id): |
|
633 | def show(self, repo_name, pull_request_id): | |
682 | pull_request_id = safe_int(pull_request_id) |
|
634 | pull_request_id = safe_int(pull_request_id) | |
683 | c.pull_request = PullRequest.get_or_404(pull_request_id) |
|
635 | version = request.GET.get('version') | |
|
636 | from_version = request.GET.get('from_version') or version | |||
|
637 | merge_checks = request.GET.get('merge_checks') | |||
|
638 | c.fulldiff = str2bool(request.GET.get('fulldiff')) | |||
|
639 | ||||
|
640 | (pull_request_latest, | |||
|
641 | pull_request_at_ver, | |||
|
642 | pull_request_display_obj, | |||
|
643 | at_version) = self._get_pr_version( | |||
|
644 | pull_request_id, version=version) | |||
|
645 | versions = pull_request_display_obj.versions() | |||
684 |
|
646 | |||
685 | c.template_context['pull_request_data']['pull_request_id'] = \ |
|
647 | c.at_version = at_version | |
686 | pull_request_id |
|
648 | c.at_version_num = (at_version | |
|
649 | if at_version and at_version != 'latest' | |||
|
650 | else None) | |||
|
651 | c.at_version_pos = ChangesetComment.get_index_from_version( | |||
|
652 | c.at_version_num, versions) | |||
|
653 | ||||
|
654 | (prev_pull_request_latest, | |||
|
655 | prev_pull_request_at_ver, | |||
|
656 | prev_pull_request_display_obj, | |||
|
657 | prev_at_version) = self._get_pr_version( | |||
|
658 | pull_request_id, version=from_version) | |||
|
659 | ||||
|
660 | c.from_version = prev_at_version | |||
|
661 | c.from_version_num = (prev_at_version | |||
|
662 | if prev_at_version and prev_at_version != 'latest' | |||
|
663 | else None) | |||
|
664 | c.from_version_pos = ChangesetComment.get_index_from_version( | |||
|
665 | c.from_version_num, versions) | |||
|
666 | ||||
|
667 | # define if we're in COMPARE mode or VIEW at version mode | |||
|
668 | compare = at_version != prev_at_version | |||
687 |
|
669 | |||
688 | # pull_requests repo_name we opened it against |
|
670 | # pull_requests repo_name we opened it against | |
689 | # ie. target_repo must match |
|
671 | # ie. target_repo must match | |
690 |
if repo_name != |
|
672 | if repo_name != pull_request_at_ver.target_repo.repo_name: | |
691 | raise HTTPNotFound |
|
673 | raise HTTPNotFound | |
692 |
|
674 | |||
|
675 | c.shadow_clone_url = PullRequestModel().get_shadow_clone_url( | |||
|
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: | |||
693 | c.allowed_to_change_status = PullRequestModel(). \ |
|
690 | c.allowed_to_change_status = PullRequestModel(). \ | |
694 |
check_user_change_status( |
|
691 | check_user_change_status(pull_request_at_ver, c.rhodecode_user) | |
695 | c.allowed_to_update = PullRequestModel().check_user_update( |
|
692 | c.allowed_to_update = PullRequestModel().check_user_update( | |
696 |
|
|
693 | pull_request_latest, c.rhodecode_user) and not pr_closed | |
697 | c.allowed_to_merge = PullRequestModel().check_user_merge( |
|
694 | c.allowed_to_merge = PullRequestModel().check_user_merge( | |
698 |
|
|
695 | pull_request_latest, c.rhodecode_user) and not pr_closed | |
699 | c.shadow_clone_url = PullRequestModel().get_shadow_clone_url( |
|
|||
700 | c.pull_request) |
|
|||
701 | c.allowed_to_delete = PullRequestModel().check_user_delete( |
|
696 | c.allowed_to_delete = PullRequestModel().check_user_delete( | |
702 |
|
|
697 | pull_request_latest, c.rhodecode_user) and not pr_closed | |
|
698 | c.allowed_to_comment = not pr_closed | |||
|
699 | ||||
|
700 | # check merge capabilities | |||
|
701 | _merge_check = MergeCheck.validate( | |||
|
702 | pull_request_latest, user=c.rhodecode_user) | |||
|
703 | c.pr_merge_errors = _merge_check.error_details | |||
|
704 | c.pr_merge_possible = not _merge_check.failed | |||
|
705 | c.pr_merge_message = _merge_check.merge_msg | |||
|
706 | ||||
|
707 | if merge_checks: | |||
|
708 | return render('/pullrequests/pullrequest_merge_checks.mako') | |||
|
709 | ||||
|
710 | comments_model = CommentsModel() | |||
|
711 | ||||
|
712 | # reviewers and statuses | |||
|
713 | c.pull_request_reviewers = pull_request_at_ver.reviewers_statuses() | |||
|
714 | allowed_reviewers = [x[0].user_id for x in c.pull_request_reviewers] | |||
|
715 | c.pull_request_review_status = pull_request_at_ver.calculated_review_status() | |||
703 |
|
716 | |||
704 | cc_model = ChangesetCommentsModel() |
|
717 | # GENERAL COMMENTS with versions # | |
|
718 | q = comments_model._all_general_comments_of_pull_request(pull_request_latest) | |||
|
719 | q = q.order_by(ChangesetComment.comment_id.asc()) | |||
|
720 | general_comments = q.order_by(ChangesetComment.pull_request_version_id.asc()) | |||
|
721 | ||||
|
722 | # pick comments we want to render at current version | |||
|
723 | c.comment_versions = comments_model.aggregate_comments( | |||
|
724 | general_comments, versions, c.at_version_num) | |||
|
725 | c.comments = c.comment_versions[c.at_version_num]['until'] | |||
705 |
|
726 | |||
706 | c.pull_request_reviewers = c.pull_request.reviewers_statuses() |
|
727 | # INLINE COMMENTS with versions # | |
|
728 | q = comments_model._all_inline_comments_of_pull_request(pull_request_latest) | |||
|
729 | q = q.order_by(ChangesetComment.comment_id.asc()) | |||
|
730 | inline_comments = q.order_by(ChangesetComment.pull_request_version_id.asc()) | |||
|
731 | c.inline_versions = comments_model.aggregate_comments( | |||
|
732 | inline_comments, versions, c.at_version_num, inline=True) | |||
|
733 | ||||
|
734 | # inject latest version | |||
|
735 | latest_ver = PullRequest.get_pr_display_object( | |||
|
736 | pull_request_latest, pull_request_latest) | |||
|
737 | ||||
|
738 | c.versions = versions + [latest_ver] | |||
707 |
|
739 | |||
708 | c.pull_request_review_status = c.pull_request.calculated_review_status() |
|
740 | # if we use version, then do not show later comments | |
709 | c.pr_merge_status, c.pr_merge_msg = PullRequestModel().merge_status( |
|
741 | # than current version | |
710 | c.pull_request) |
|
742 | display_inline_comments = collections.defaultdict( | |
711 | c.approval_msg = None |
|
743 | lambda: collections.defaultdict(list)) | |
712 | if c.pull_request_review_status != ChangesetStatus.STATUS_APPROVED: |
|
744 | for co in inline_comments: | |
713 | c.approval_msg = _('Reviewer approval is pending.') |
|
745 | if c.at_version_num: | |
714 | c.pr_merge_status = False |
|
746 | # pick comments that are at least UPTO given version, so we | |
715 | # load compare data into template context |
|
747 | # don't render comments for higher version | |
716 | enable_comments = not c.pull_request.is_closed() |
|
748 | should_render = co.pull_request_version_id and \ | |
|
749 | co.pull_request_version_id <= c.at_version_num | |||
|
750 | else: | |||
|
751 | # showing all, for 'latest' | |||
|
752 | should_render = True | |||
|
753 | ||||
|
754 | if should_render: | |||
|
755 | display_inline_comments[co.f_path][co.line_no].append(co) | |||
|
756 | ||||
|
757 | # load diff data into template context, if we use compare mode then | |||
|
758 | # diff is calculated based on changes between versions of PR | |||
|
759 | ||||
|
760 | source_repo = pull_request_at_ver.source_repo | |||
|
761 | source_ref_id = pull_request_at_ver.source_ref_parts.commit_id | |||
|
762 | ||||
|
763 | target_repo = pull_request_at_ver.target_repo | |||
|
764 | target_ref_id = pull_request_at_ver.target_ref_parts.commit_id | |||
717 |
|
765 | |||
|
766 | if compare: | |||
|
767 | # in compare switch the diff base to latest commit from prev version | |||
|
768 | target_ref_id = prev_pull_request_display_obj.revisions[0] | |||
718 |
|
769 | |||
719 | # inline comments |
|
770 | # despite opening commits for bookmarks/branches/tags, we always | |
720 | c.inline_comments = cc_model.get_inline_comments( |
|
771 | # convert this to rev to prevent changes after bookmark or branch change | |
721 | c.rhodecode_db_repo.repo_id, |
|
772 | c.source_ref_type = 'rev' | |
722 | pull_request=pull_request_id) |
|
773 | c.source_ref = source_ref_id | |
|
774 | ||||
|
775 | c.target_ref_type = 'rev' | |||
|
776 | c.target_ref = target_ref_id | |||
|
777 | ||||
|
778 | c.source_repo = source_repo | |||
|
779 | c.target_repo = target_repo | |||
|
780 | ||||
|
781 | # diff_limit is the old behavior, will cut off the whole diff | |||
|
782 | # if the limit is applied otherwise will just hide the | |||
|
783 | # big files from the front-end | |||
|
784 | diff_limit = self.cut_off_limit_diff | |||
|
785 | file_limit = self.cut_off_limit_file | |||
723 |
|
786 | |||
724 | c.inline_cnt = cc_model.get_inline_comments_count(c.inline_comments) |
|
787 | c.commit_ranges = [] | |
|
788 | source_commit = EmptyCommit() | |||
|
789 | target_commit = EmptyCommit() | |||
|
790 | c.missing_requirements = False | |||
725 |
|
791 | |||
726 | self._load_compare_data( |
|
792 | # try first shadow repo, fallback to regular repo | |
727 | c.pull_request, c.inline_comments, enable_comments=enable_comments) |
|
793 | try: | |
|
794 | commits_source_repo = pull_request_latest.get_shadow_repo() | |||
|
795 | except Exception: | |||
|
796 | log.debug('Failed to get shadow repo', exc_info=True) | |||
|
797 | commits_source_repo = source_repo.scm_instance() | |||
|
798 | ||||
|
799 | c.commits_source_repo = commits_source_repo | |||
|
800 | commit_cache = {} | |||
|
801 | try: | |||
|
802 | pre_load = ["author", "branch", "date", "message"] | |||
|
803 | show_revs = pull_request_at_ver.revisions | |||
|
804 | for rev in show_revs: | |||
|
805 | comm = commits_source_repo.get_commit( | |||
|
806 | commit_id=rev, pre_load=pre_load) | |||
|
807 | c.commit_ranges.append(comm) | |||
|
808 | commit_cache[comm.raw_id] = comm | |||
728 |
|
809 | |||
729 | # outdated comments |
|
810 | target_commit = commits_source_repo.get_commit( | |
730 | c.outdated_comments = {} |
|
811 | commit_id=safe_str(target_ref_id)) | |
731 | c.outdated_cnt = 0 |
|
812 | source_commit = commits_source_repo.get_commit( | |
732 | if ChangesetCommentsModel.use_outdated_comments(c.pull_request): |
|
813 | commit_id=safe_str(source_ref_id)) | |
733 | c.outdated_comments = cc_model.get_outdated_comments( |
|
814 | except CommitDoesNotExistError: | |
734 | c.rhodecode_db_repo.repo_id, |
|
815 | pass | |
735 | pull_request=c.pull_request) |
|
816 | except RepositoryRequirementError: | |
736 | # Count outdated comments and check for deleted files |
|
817 | log.warning( | |
737 | for file_name, lines in c.outdated_comments.iteritems(): |
|
818 | 'Failed to get all required data from repo', exc_info=True) | |
738 | for comments in lines.values(): |
|
819 | c.missing_requirements = True | |
739 | c.outdated_cnt += len(comments) |
|
820 | ||
740 | if file_name not in c.included_files: |
|
821 | c.statuses = source_repo.statuses( | |
741 | c.deleted_files.append(file_name) |
|
822 | [x.raw_id for x in c.commit_ranges]) | |
|
823 | ||||
|
824 | # auto collapse if we have more than limit | |||
|
825 | collapse_limit = diffs.DiffProcessor._collapse_commits_over | |||
|
826 | c.collapse_all_commits = len(c.commit_ranges) > collapse_limit | |||
|
827 | c.compare_mode = compare | |||
|
828 | ||||
|
829 | c.missing_commits = False | |||
|
830 | if (c.missing_requirements or isinstance(source_commit, EmptyCommit) | |||
|
831 | or source_commit == target_commit): | |||
742 |
|
832 | |||
|
833 | c.missing_commits = True | |||
|
834 | else: | |||
|
835 | ||||
|
836 | c.diffset = self._get_diffset( | |||
|
837 | commits_source_repo, source_ref_id, target_ref_id, | |||
|
838 | target_commit, source_commit, | |||
|
839 | diff_limit, file_limit, display_inline_comments) | |||
|
840 | ||||
|
841 | c.limited_diff = c.diffset.limited_diff | |||
|
842 | ||||
|
843 | # calculate removed files that are bound to comments | |||
|
844 | comment_deleted_files = [ | |||
|
845 | fname for fname in display_inline_comments | |||
|
846 | if fname not in c.diffset.file_stats] | |||
|
847 | ||||
|
848 | c.deleted_files_comments = collections.defaultdict(dict) | |||
|
849 | for fname, per_line_comments in display_inline_comments.items(): | |||
|
850 | if fname in comment_deleted_files: | |||
|
851 | c.deleted_files_comments[fname]['stats'] = 0 | |||
|
852 | c.deleted_files_comments[fname]['comments'] = list() | |||
|
853 | for lno, comments in per_line_comments.items(): | |||
|
854 | c.deleted_files_comments[fname]['comments'].extend( | |||
|
855 | comments) | |||
743 |
|
856 | |||
744 | # this is a hack to properly display links, when creating PR, the |
|
857 | # this is a hack to properly display links, when creating PR, the | |
745 | # compare view and others uses different notation, and |
|
858 | # compare view and others uses different notation, and | |
746 |
# compare_commits. |
|
859 | # compare_commits.mako renders links based on the target_repo. | |
747 | # We need to swap that here to generate it properly on the html side |
|
860 | # We need to swap that here to generate it properly on the html side | |
748 | c.target_repo = c.source_repo |
|
861 | c.target_repo = c.source_repo | |
749 |
|
862 | |||
750 | # comments |
|
|||
751 | c.comments = cc_model.get_comments(c.rhodecode_db_repo.repo_id, |
|
|||
752 | pull_request=pull_request_id) |
|
|||
753 |
|
||||
754 | if c.allowed_to_update: |
|
863 | if c.allowed_to_update: | |
755 | force_close = ('forced_closed', _('Close Pull Request')) |
|
864 | force_close = ('forced_closed', _('Close Pull Request')) | |
756 | statuses = ChangesetStatus.STATUSES + [force_close] |
|
865 | statuses = ChangesetStatus.STATUSES + [force_close] | |
@@ -758,14 +867,55 b' class PullrequestsController(BaseRepoCon' | |||||
758 | statuses = ChangesetStatus.STATUSES |
|
867 | statuses = ChangesetStatus.STATUSES | |
759 | c.commit_statuses = statuses |
|
868 | c.commit_statuses = statuses | |
760 |
|
869 | |||
761 | c.ancestor = None # TODO: add ancestor here |
|
870 | c.show_version_changes = not pr_closed | |
|
871 | if c.show_version_changes: | |||
|
872 | cur_obj = pull_request_at_ver | |||
|
873 | prev_obj = prev_pull_request_at_ver | |||
|
874 | ||||
|
875 | old_commit_ids = prev_obj.revisions | |||
|
876 | new_commit_ids = cur_obj.revisions | |||
|
877 | commit_changes = PullRequestModel()._calculate_commit_id_changes( | |||
|
878 | old_commit_ids, new_commit_ids) | |||
|
879 | c.commit_changes_summary = commit_changes | |||
|
880 | ||||
|
881 | # calculate the diff for commits between versions | |||
|
882 | c.commit_changes = [] | |||
|
883 | mark = lambda cs, fw: list( | |||
|
884 | h.itertools.izip_longest([], cs, fillvalue=fw)) | |||
|
885 | for c_type, raw_id in mark(commit_changes.added, 'a') \ | |||
|
886 | + mark(commit_changes.removed, 'r') \ | |||
|
887 | + mark(commit_changes.common, 'c'): | |||
762 |
|
888 | |||
763 | return render('/pullrequests/pullrequest_show.html') |
|
889 | if raw_id in commit_cache: | |
|
890 | commit = commit_cache[raw_id] | |||
|
891 | else: | |||
|
892 | try: | |||
|
893 | commit = commits_source_repo.get_commit(raw_id) | |||
|
894 | except CommitDoesNotExistError: | |||
|
895 | # in case we fail extracting still use "dummy" commit | |||
|
896 | # for display in commit diff | |||
|
897 | commit = h.AttributeDict( | |||
|
898 | {'raw_id': raw_id, | |||
|
899 | 'message': 'EMPTY or MISSING COMMIT'}) | |||
|
900 | c.commit_changes.append([c_type, commit]) | |||
|
901 | ||||
|
902 | # current user review statuses for each version | |||
|
903 | c.review_versions = {} | |||
|
904 | if c.rhodecode_user.user_id in allowed_reviewers: | |||
|
905 | for co in general_comments: | |||
|
906 | if co.author.user_id == c.rhodecode_user.user_id: | |||
|
907 | # each comment has a status change | |||
|
908 | status = co.status_change | |||
|
909 | if status: | |||
|
910 | _ver_pr = status[0].comment.pull_request_version_id | |||
|
911 | c.review_versions[_ver_pr] = status[0] | |||
|
912 | ||||
|
913 | return render('/pullrequests/pullrequest_show.mako') | |||
764 |
|
914 | |||
765 | @LoginRequired() |
|
915 | @LoginRequired() | |
766 | @NotAnonymous() |
|
916 | @NotAnonymous() | |
767 |
@HasRepoPermissionAnyDecorator( |
|
917 | @HasRepoPermissionAnyDecorator( | |
768 | 'repository.admin') |
|
918 | 'repository.read', 'repository.write', 'repository.admin') | |
769 | @auth.CSRFRequired() |
|
919 | @auth.CSRFRequired() | |
770 | @jsonify |
|
920 | @jsonify | |
771 | def comment(self, repo_name, pull_request_id): |
|
921 | def comment(self, repo_name, pull_request_id): | |
@@ -778,6 +928,9 b' class PullrequestsController(BaseRepoCon' | |||||
778 | # as a changeset status, still we want to send it in one value. |
|
928 | # as a changeset status, still we want to send it in one value. | |
779 | status = request.POST.get('changeset_status', None) |
|
929 | status = request.POST.get('changeset_status', None) | |
780 | text = request.POST.get('text') |
|
930 | text = request.POST.get('text') | |
|
931 | comment_type = request.POST.get('comment_type') | |||
|
932 | resolves_comment_id = request.POST.get('resolves_comment_id', None) | |||
|
933 | ||||
781 | if status and '_closed' in status: |
|
934 | if status and '_closed' in status: | |
782 | close_pr = True |
|
935 | close_pr = True | |
783 | status = status.replace('_closed', '') |
|
936 | status = status.replace('_closed', '') | |
@@ -798,7 +951,7 b' class PullrequestsController(BaseRepoCon' | |||||
798 | if close_pr: |
|
951 | if close_pr: | |
799 | message = _('Closing with') + ' ' + message |
|
952 | message = _('Closing with') + ' ' + message | |
800 | text = text or message |
|
953 | text = text or message | |
801 |
comm = |
|
954 | comm = CommentsModel().create( | |
802 | text=text, |
|
955 | text=text, | |
803 | repo=c.rhodecode_db_repo.repo_id, |
|
956 | repo=c.rhodecode_db_repo.repo_id, | |
804 | user=c.rhodecode_user.user_id, |
|
957 | user=c.rhodecode_user.user_id, | |
@@ -809,11 +962,11 b' class PullrequestsController(BaseRepoCon' | |||||
809 | if status and allowed_to_change_status else None), |
|
962 | if status and allowed_to_change_status else None), | |
810 | status_change_type=(status |
|
963 | status_change_type=(status | |
811 | if status and allowed_to_change_status else None), |
|
964 | if status and allowed_to_change_status else None), | |
812 | closing_pr=close_pr |
|
965 | closing_pr=close_pr, | |
|
966 | comment_type=comment_type, | |||
|
967 | resolves_comment_id=resolves_comment_id | |||
813 | ) |
|
968 | ) | |
814 |
|
969 | |||
815 |
|
||||
816 |
|
||||
817 | if allowed_to_change_status: |
|
970 | if allowed_to_change_status: | |
818 | old_calculated_status = pull_request.calculated_review_status() |
|
971 | old_calculated_status = pull_request.calculated_review_status() | |
819 | # get status if set ! |
|
972 | # get status if set ! | |
@@ -863,9 +1016,10 b' class PullrequestsController(BaseRepoCon' | |||||
863 | } |
|
1016 | } | |
864 | if comm: |
|
1017 | if comm: | |
865 | c.co = comm |
|
1018 | c.co = comm | |
|
1019 | c.inline_comment = True if comm.line_no else False | |||
866 | data.update(comm.get_dict()) |
|
1020 | data.update(comm.get_dict()) | |
867 | data.update({'rendered_text': |
|
1021 | data.update({'rendered_text': | |
868 |
render('changeset/changeset_comment_block. |
|
1022 | render('changeset/changeset_comment_block.mako')}) | |
869 |
|
1023 | |||
870 | return data |
|
1024 | return data | |
871 |
|
1025 | |||
@@ -889,7 +1043,7 b' class PullrequestsController(BaseRepoCon' | |||||
889 | is_repo_admin = h.HasRepoPermissionAny('repository.admin')(c.repo_name) |
|
1043 | is_repo_admin = h.HasRepoPermissionAny('repository.admin')(c.repo_name) | |
890 | if h.HasPermissionAny('hg.admin')() or is_repo_admin or is_owner: |
|
1044 | if h.HasPermissionAny('hg.admin')() or is_repo_admin or is_owner: | |
891 | old_calculated_status = co.pull_request.calculated_review_status() |
|
1045 | old_calculated_status = co.pull_request.calculated_review_status() | |
892 |
|
|
1046 | CommentsModel().delete(comment=co) | |
893 | Session().commit() |
|
1047 | Session().commit() | |
894 | calculated_status = co.pull_request.calculated_review_status() |
|
1048 | calculated_status = co.pull_request.calculated_review_status() | |
895 | if old_calculated_status != calculated_status: |
|
1049 | if old_calculated_status != calculated_status: |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -108,4 +108,4 b' class SearchController(BaseRepoControlle' | |||||
108 | c.cur_query = search_query |
|
108 | c.cur_query = search_query | |
109 | c.search_type = search_type |
|
109 | c.search_type = search_type | |
110 | # Return a rendered template |
|
110 | # Return a rendered template | |
111 |
return render('/search/search. |
|
111 | return render('/search/search.mako') |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -165,7 +165,7 b' class SummaryController(BaseRepoControll' | |||||
165 | c.repo_name, c.rhodecode_user.user_id) |
|
165 | c.repo_name, c.rhodecode_user.user_id) | |
166 |
|
166 | |||
167 | if c.repository_requirements_missing: |
|
167 | if c.repository_requirements_missing: | |
168 |
return render('summary/missing_requirements. |
|
168 | return render('summary/missing_requirements.mako') | |
169 |
|
169 | |||
170 | c.readme_data, c.readme_file = \ |
|
170 | c.readme_data, c.readme_file = \ | |
171 | self.__get_readme_data(c.rhodecode_db_repo) |
|
171 | self.__get_readme_data(c.rhodecode_db_repo) | |
@@ -173,9 +173,9 b' class SummaryController(BaseRepoControll' | |||||
173 | _load_changelog_summary() |
|
173 | _load_changelog_summary() | |
174 |
|
174 | |||
175 | if request.is_xhr: |
|
175 | if request.is_xhr: | |
176 |
return render('changelog/changelog_summary_data. |
|
176 | return render('changelog/changelog_summary_data.mako') | |
177 |
|
177 | |||
178 |
return render('summary/summary. |
|
178 | return render('summary/summary.mako') | |
179 |
|
179 | |||
180 | @LoginRequired() |
|
180 | @LoginRequired() | |
181 | @XHRRequired() |
|
181 | @XHRRequired() |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -31,8 +31,8 b' log = logging.getLogger(__name__)' | |||||
31 |
|
31 | |||
32 | class TagsController(BaseReferencesController): |
|
32 | class TagsController(BaseReferencesController): | |
33 |
|
33 | |||
34 |
partials_template = 'tags/tags_data. |
|
34 | partials_template = 'tags/tags_data.mako' | |
35 |
template = 'tags/tags. |
|
35 | template = 'tags/tags.mako' | |
36 |
|
36 | |||
37 | def _get_reference_items(self, repo): |
|
37 | def _get_reference_items(self, repo): | |
38 | return repo.tags.items() |
|
38 | return repo.tags.items() |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -40,4 +40,4 b' class UsersController(BaseController):' | |||||
40 | raise HTTPNotFound() |
|
40 | raise HTTPNotFound() | |
41 |
|
41 | |||
42 | c.active = 'user_profile' |
|
42 | c.active = 'user_profile' | |
43 |
return render('users/user. |
|
43 | return render('users/user.mako') |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -27,6 +27,7 b' Should only contain utilities to be shar' | |||||
27 | from rhodecode.lib import helpers as h |
|
27 | from rhodecode.lib import helpers as h | |
28 | from rhodecode.lib.vcs.exceptions import RepositoryError |
|
28 | from rhodecode.lib.vcs.exceptions import RepositoryError | |
29 |
|
29 | |||
|
30 | ||||
30 | def parse_path_ref(ref, default_path=None): |
|
31 | def parse_path_ref(ref, default_path=None): | |
31 | """ |
|
32 | """ | |
32 | Parse out a path and reference combination and return both parts of it. |
|
33 | Parse out a path and reference combination and return both parts of it. |
@@ -1,4 +1,4 b'' | |||||
1 |
# Copyright (C) 2016-201 |
|
1 | # Copyright (C) 2016-2017 RhodeCode GmbH | |
2 | # |
|
2 | # | |
3 | # This program is free software: you can redistribute it and/or modify |
|
3 | # This program is free software: you can redistribute it and/or modify | |
4 | # it under the terms of the GNU Affero General Public License, version 3 |
|
4 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,4 +1,4 b'' | |||||
1 |
# Copyright (C) 2016-201 |
|
1 | # Copyright (C) 2016-2017 RhodeCode GmbH | |
2 | # |
|
2 | # | |
3 | # This program is free software: you can redistribute it and/or modify |
|
3 | # This program is free software: you can redistribute it and/or modify | |
4 | # it under the terms of the GNU Affero General Public License, version 3 |
|
4 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,4 +1,4 b'' | |||||
1 |
# Copyright (C) 2016-201 |
|
1 | # Copyright (C) 2016-2017 RhodeCode GmbH | |
2 | # |
|
2 | # | |
3 | # This program is free software: you can redistribute it and/or modify |
|
3 | # This program is free software: you can redistribute it and/or modify | |
4 | # it under the terms of the GNU Affero General Public License, version 3 |
|
4 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,4 +1,4 b'' | |||||
1 |
# Copyright (C) 2016-201 |
|
1 | # Copyright (C) 2016-2017 RhodeCode GmbH | |
2 | # |
|
2 | # | |
3 | # This program is free software: you can redistribute it and/or modify |
|
3 | # This program is free software: you can redistribute it and/or modify | |
4 | # it under the terms of the GNU Affero General Public License, version 3 |
|
4 | # it under the terms of the GNU Affero General Public License, version 3 | |
@@ -114,7 +114,7 b' class PullRequestCommentEvent(PullReques' | |||||
114 | self.comment = comment |
|
114 | self.comment = comment | |
115 |
|
115 | |||
116 | def as_dict(self): |
|
116 | def as_dict(self): | |
117 |
from rhodecode.model.comment import |
|
117 | from rhodecode.model.comment import CommentsModel | |
118 | data = super(PullRequestCommentEvent, self).as_dict() |
|
118 | data = super(PullRequestCommentEvent, self).as_dict() | |
119 |
|
119 | |||
120 | status = None |
|
120 | status = None | |
@@ -125,7 +125,7 b' class PullRequestCommentEvent(PullReques' | |||||
125 | 'comment': { |
|
125 | 'comment': { | |
126 | 'status': status, |
|
126 | 'status': status, | |
127 | 'text': self.comment.text, |
|
127 | 'text': self.comment.text, | |
128 |
'url': |
|
128 | 'url': CommentsModel().get_url(self.comment) | |
129 | } |
|
129 | } | |
130 | }) |
|
130 | }) | |
131 | return data |
|
131 | return data |
@@ -1,4 +1,4 b'' | |||||
1 |
# Copyright (C) 2016-201 |
|
1 | # Copyright (C) 2016-2017 RhodeCode GmbH | |
2 | # |
|
2 | # | |
3 | # This program is free software: you can redistribute it and/or modify |
|
3 | # This program is free software: you can redistribute it and/or modify | |
4 | # it under the terms of the GNU Affero General Public License, version 3 |
|
4 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,4 +1,4 b'' | |||||
1 |
# Copyright (C) 2016-201 |
|
1 | # Copyright (C) 2016-2017 RhodeCode GmbH | |
2 | # |
|
2 | # | |
3 | # This program is free software: you can redistribute it and/or modify |
|
3 | # This program is free software: you can redistribute it and/or modify | |
4 | # it under the terms of the GNU Affero General Public License, version 3 |
|
4 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,4 +1,4 b'' | |||||
1 |
# Copyright (C) 2016-201 |
|
1 | # Copyright (C) 2016-2017 RhodeCode GmbH | |
2 | # |
|
2 | # | |
3 | # This program is free software: you can redistribute it and/or modify |
|
3 | # This program is free software: you can redistribute it and/or modify | |
4 | # it under the terms of the GNU Affero General Public License, version 3 |
|
4 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,6 +1,6 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 |
# Copyright (C) 2010-201 |
|
3 | # Copyright (C) 2010-2017 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 |
@@ -1,5 +1,5 b'' | |||||
1 | # Translations template for rhodecode-enterprise-ce. |
|
1 | # Translations template for rhodecode-enterprise-ce. | |
2 |
# Copyright (C) 201 |
|
2 | # Copyright (C) 2017 RhodeCode GmbH | |
3 | # This file is distributed under the same license as the rhodecode-enterprise-ce project. |
|
3 | # This file is distributed under the same license as the rhodecode-enterprise-ce project. | |
4 | # |
|
4 | # | |
5 | # Translators: |
|
5 | # Translators: |
@@ -1,5 +1,5 b'' | |||||
1 | # Translations template for rhodecode-enterprise-ce. |
|
1 | # Translations template for rhodecode-enterprise-ce. | |
2 |
# Copyright (C) 201 |
|
2 | # Copyright (C) 2017 RhodeCode GmbH | |
3 | # This file is distributed under the same license as the rhodecode-enterprise-ce project. |
|
3 | # This file is distributed under the same license as the rhodecode-enterprise-ce project. | |
4 | # |
|
4 | # | |
5 | # Translators: |
|
5 | # Translators: |
@@ -1,5 +1,5 b'' | |||||
1 | # Translations template for rhodecode-enterprise-ce. |
|
1 | # Translations template for rhodecode-enterprise-ce. | |
2 |
# Copyright (C) 201 |
|
2 | # Copyright (C) 2017 RhodeCode GmbH | |
3 | # This file is distributed under the same license as the rhodecode-enterprise-ce project. |
|
3 | # This file is distributed under the same license as the rhodecode-enterprise-ce project. | |
4 | # |
|
4 | # | |
5 | # Translators: |
|
5 | # Translators: |
@@ -1,5 +1,5 b'' | |||||
1 | # Translations template for rhodecode-enterprise-ce. |
|
1 | # Translations template for rhodecode-enterprise-ce. | |
2 |
# Copyright (C) 201 |
|
2 | # Copyright (C) 2017 RhodeCode GmbH | |
3 | # This file is distributed under the same license as the rhodecode-enterprise-ce project. |
|
3 | # This file is distributed under the same license as the rhodecode-enterprise-ce project. | |
4 | # |
|
4 | # | |
5 | # Translators: |
|
5 | # Translators: |
@@ -1,5 +1,5 b'' | |||||
1 | # Translations template for rhodecode-enterprise-ce. |
|
1 | # Translations template for rhodecode-enterprise-ce. | |
2 |
# Copyright (C) 201 |
|
2 | # Copyright (C) 2017 RhodeCode GmbH | |
3 | # This file is distributed under the same license as the rhodecode-enterprise-ce project. |
|
3 | # This file is distributed under the same license as the rhodecode-enterprise-ce project. | |
4 | # |
|
4 | # | |
5 | # Translators: |
|
5 | # Translators: |
@@ -1,9 +1,9 b'' | |||||
1 | # Translations template for rhodecode-enterprise-ce. |
|
1 | # Translations template for rhodecode-enterprise-ce. | |
2 |
# Copyright (C) 201 |
|
2 | # Copyright (C) 2017 RhodeCode GmbH | |
3 | # This file is distributed under the same license as the rhodecode-enterprise-ce project. |
|
3 | # This file is distributed under the same license as the rhodecode-enterprise-ce project. | |
4 | # |
|
4 | # | |
5 | # Translators: |
|
5 | # Translators: | |
6 |
# Alessandro sauzher Ceglie, 2014-201 |
|
6 | # Alessandro sauzher Ceglie, 2014-2017 | |
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, 2014 |
|
7 | # FIRST AUTHOR <EMAIL@ADDRESS>, 2014 | |
8 | msgid "" |
|
8 | msgid "" | |
9 | msgstr "" |
|
9 | msgstr "" |
@@ -1,5 +1,5 b'' | |||||
1 | # Translations template for rhodecode-enterprise-ce. |
|
1 | # Translations template for rhodecode-enterprise-ce. | |
2 |
# Copyright (C) 201 |
|
2 | # Copyright (C) 2017 RhodeCode GmbH | |
3 | # This file is distributed under the same license as the rhodecode-enterprise-ce project. |
|
3 | # This file is distributed under the same license as the rhodecode-enterprise-ce project. | |
4 | # |
|
4 | # | |
5 | # Translators: |
|
5 | # Translators: |
@@ -1,5 +1,5 b'' | |||||
1 | # Translations template for rhodecode-enterprise-ce. |
|
1 | # Translations template for rhodecode-enterprise-ce. | |
2 |
# Copyright (C) 201 |
|
2 | # Copyright (C) 2017 RhodeCode GmbH | |
3 | # This file is distributed under the same license as the rhodecode-enterprise-ce project. |
|
3 | # This file is distributed under the same license as the rhodecode-enterprise-ce project. | |
4 | # |
|
4 | # | |
5 | # Translators: |
|
5 | # Translators: |
@@ -1,5 +1,5 b'' | |||||
1 | # Translations template for rhodecode-enterprise-ce. |
|
1 | # Translations template for rhodecode-enterprise-ce. | |
2 |
# Copyright (C) 201 |
|
2 | # Copyright (C) 2017 RhodeCode GmbH | |
3 | # This file is distributed under the same license as the rhodecode-enterprise-ce project. |
|
3 | # This file is distributed under the same license as the rhodecode-enterprise-ce project. | |
4 | # |
|
4 | # | |
5 | # Translators: |
|
5 | # Translators: |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/admin.html to rhodecode/templates/admin/admin.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/admin.html to rhodecode/templates/admin/admin.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/admin_log.html to rhodecode/templates/admin/admin_log.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/admin_log.html to rhodecode/templates/admin/admin_log.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/auth/auth_settings.html to rhodecode/templates/admin/auth/auth_settings.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/auth/auth_settings.html to rhodecode/templates/admin/auth/auth_settings.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/auth/plugin_settings.html to rhodecode/templates/admin/auth/plugin_settings.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/auth/plugin_settings.html to rhodecode/templates/admin/auth/plugin_settings.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/defaults/defaults.html to rhodecode/templates/admin/defaults/defaults.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/defaults/defaults.html to rhodecode/templates/admin/defaults/defaults.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/defaults/defaults_repositories.html to rhodecode/templates/admin/defaults/defaults_repositories.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/defaults/defaults_repositories.html to rhodecode/templates/admin/defaults/defaults_repositories.mako |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/gists/edit.html to rhodecode/templates/admin/gists/edit.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/gists/edit.html to rhodecode/templates/admin/gists/edit.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/gists/index.html to rhodecode/templates/admin/gists/index.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/gists/index.html to rhodecode/templates/admin/gists/index.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/gists/new.html to rhodecode/templates/admin/gists/new.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/gists/new.html to rhodecode/templates/admin/gists/new.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/gists/show.html to rhodecode/templates/admin/gists/show.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/gists/show.html to rhodecode/templates/admin/gists/show.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/integrations/base.html to rhodecode/templates/admin/integrations/base.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/integrations/base.html to rhodecode/templates/admin/integrations/base.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/integrations/form.html to rhodecode/templates/admin/integrations/form.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/integrations/form.html to rhodecode/templates/admin/integrations/form.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/integrations/list.html to rhodecode/templates/admin/integrations/list.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/integrations/list.html to rhodecode/templates/admin/integrations/list.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/integrations/new.html to rhodecode/templates/admin/integrations/new.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/integrations/new.html to rhodecode/templates/admin/integrations/new.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account.html to rhodecode/templates/admin/my_account/my_account.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account.html to rhodecode/templates/admin/my_account/my_account.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account_auth_tokens.html to rhodecode/templates/admin/my_account/my_account_auth_tokens.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account_auth_tokens.html to rhodecode/templates/admin/my_account/my_account_auth_tokens.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account_emails.html to rhodecode/templates/admin/my_account/my_account_emails.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account_emails.html to rhodecode/templates/admin/my_account/my_account_emails.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account_notifications.html to rhodecode/templates/admin/my_account/my_account_notifications.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account_notifications.html to rhodecode/templates/admin/my_account/my_account_notifications.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account_password.html to rhodecode/templates/admin/my_account/my_account_password.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account_password.html to rhodecode/templates/admin/my_account/my_account_password.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account_perms.html to rhodecode/templates/admin/my_account/my_account_perms.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account_perms.html to rhodecode/templates/admin/my_account/my_account_perms.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account_profile.html to rhodecode/templates/admin/my_account/my_account_profile.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account_profile.html to rhodecode/templates/admin/my_account/my_account_profile.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account_profile_edit.html to rhodecode/templates/admin/my_account/my_account_profile_edit.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account_profile_edit.html to rhodecode/templates/admin/my_account/my_account_profile_edit.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account_pullrequests.html to rhodecode/templates/admin/my_account/my_account_pullrequests.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account_pullrequests.html to rhodecode/templates/admin/my_account/my_account_pullrequests.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account_repos.html to rhodecode/templates/admin/my_account/my_account_repos.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account_repos.html to rhodecode/templates/admin/my_account/my_account_repos.mako |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account_watched.html to rhodecode/templates/admin/my_account/my_account_watched.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/my_account/my_account_watched.html to rhodecode/templates/admin/my_account/my_account_watched.mako |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/notifications/notifications.html to rhodecode/templates/admin/notifications/notifications.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/notifications/notifications.html to rhodecode/templates/admin/notifications/notifications.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/notifications/notifications_data.html to rhodecode/templates/admin/notifications/notifications_data.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/notifications/notifications_data.html to rhodecode/templates/admin/notifications/notifications_data.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/notifications/show_notification.html to rhodecode/templates/admin/notifications/show_notification.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/notifications/show_notification.html to rhodecode/templates/admin/notifications/show_notification.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/permissions/permissions.html to rhodecode/templates/admin/permissions/permissions.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/permissions/permissions.html to rhodecode/templates/admin/permissions/permissions.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/permissions/permissions_application.html to rhodecode/templates/admin/permissions/permissions_application.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/permissions/permissions_application.html to rhodecode/templates/admin/permissions/permissions_application.mako |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/permissions/permissions_global.html to rhodecode/templates/admin/permissions/permissions_global.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/permissions/permissions_global.html to rhodecode/templates/admin/permissions/permissions_global.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/permissions/permissions_ips.html to rhodecode/templates/admin/permissions/permissions_ips.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/permissions/permissions_ips.html to rhodecode/templates/admin/permissions/permissions_ips.mako |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/permissions/permissions_objects.html to rhodecode/templates/admin/permissions/permissions_objects.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/permissions/permissions_objects.html to rhodecode/templates/admin/permissions/permissions_objects.mako |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/permissions/permissions_perms.html to rhodecode/templates/admin/permissions/permissions_perms.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/permissions/permissions_perms.html to rhodecode/templates/admin/permissions/permissions_perms.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/repo_groups/repo_group_add.html to rhodecode/templates/admin/repo_groups/repo_group_add.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/repo_groups/repo_group_add.html to rhodecode/templates/admin/repo_groups/repo_group_add.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/repo_groups/repo_group_edit.html to rhodecode/templates/admin/repo_groups/repo_group_edit.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/repo_groups/repo_group_edit.html to rhodecode/templates/admin/repo_groups/repo_group_edit.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/repo_groups/repo_group_edit_advanced.html to rhodecode/templates/admin/repo_groups/repo_group_edit_advanced.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/repo_groups/repo_group_edit_advanced.html to rhodecode/templates/admin/repo_groups/repo_group_edit_advanced.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/repo_groups/repo_group_edit_perms.html to rhodecode/templates/admin/repo_groups/repo_group_edit_perms.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/repo_groups/repo_group_edit_perms.html to rhodecode/templates/admin/repo_groups/repo_group_edit_perms.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/repo_groups/repo_group_edit_settings.html to rhodecode/templates/admin/repo_groups/repo_group_edit_settings.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/repo_groups/repo_group_edit_settings.html to rhodecode/templates/admin/repo_groups/repo_group_edit_settings.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/repo_groups/repo_groups.html to rhodecode/templates/admin/repo_groups/repo_groups.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/repo_groups/repo_groups.html to rhodecode/templates/admin/repo_groups/repo_groups.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_add.html to rhodecode/templates/admin/repos/repo_add.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_add.html to rhodecode/templates/admin/repos/repo_add.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_add_base.html to rhodecode/templates/admin/repos/repo_add_base.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_add_base.html to rhodecode/templates/admin/repos/repo_add_base.mako |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_creating.html to rhodecode/templates/admin/repos/repo_creating.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_creating.html to rhodecode/templates/admin/repos/repo_creating.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit.html to rhodecode/templates/admin/repos/repo_edit.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit.html to rhodecode/templates/admin/repos/repo_edit.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit_advanced.html to rhodecode/templates/admin/repos/repo_edit_advanced.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit_advanced.html to rhodecode/templates/admin/repos/repo_edit_advanced.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit_caches.html to rhodecode/templates/admin/repos/repo_edit_caches.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit_caches.html to rhodecode/templates/admin/repos/repo_edit_caches.mako |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit_fields.html to rhodecode/templates/admin/repos/repo_edit_fields.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit_fields.html to rhodecode/templates/admin/repos/repo_edit_fields.mako |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit_fork.html to rhodecode/templates/admin/repos/repo_edit_fork.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit_fork.html to rhodecode/templates/admin/repos/repo_edit_fork.mako |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit_issuetracker.html to rhodecode/templates/admin/repos/repo_edit_issuetracker.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit_issuetracker.html to rhodecode/templates/admin/repos/repo_edit_issuetracker.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit_permissions.html to rhodecode/templates/admin/repos/repo_edit_permissions.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit_permissions.html to rhodecode/templates/admin/repos/repo_edit_permissions.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit_remote.html to rhodecode/templates/admin/repos/repo_edit_remote.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit_remote.html to rhodecode/templates/admin/repos/repo_edit_remote.mako |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit_settings.html to rhodecode/templates/admin/repos/repo_edit_settings.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit_settings.html to rhodecode/templates/admin/repos/repo_edit_settings.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit_statistics.html to rhodecode/templates/admin/repos/repo_edit_statistics.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit_statistics.html to rhodecode/templates/admin/repos/repo_edit_statistics.mako |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit_vcs.html to rhodecode/templates/admin/repos/repo_edit_vcs.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/repos/repo_edit_vcs.html to rhodecode/templates/admin/repos/repo_edit_vcs.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/repos/repos.html to rhodecode/templates/admin/repos/repos.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/repos/repos.html to rhodecode/templates/admin/repos/repos.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings.html to rhodecode/templates/admin/settings/settings.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings.html to rhodecode/templates/admin/settings/settings.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_email.html to rhodecode/templates/admin/settings/settings_email.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_email.html to rhodecode/templates/admin/settings/settings_email.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_global.html to rhodecode/templates/admin/settings/settings_global.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_global.html to rhodecode/templates/admin/settings/settings_global.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_hooks.html to rhodecode/templates/admin/settings/settings_hooks.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_hooks.html to rhodecode/templates/admin/settings/settings_hooks.mako |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_issuetracker.html to rhodecode/templates/admin/settings/settings_issuetracker.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_issuetracker.html to rhodecode/templates/admin/settings/settings_issuetracker.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_labs.html to rhodecode/templates/admin/settings/settings_labs.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_labs.html to rhodecode/templates/admin/settings/settings_labs.mako |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_mapping.html to rhodecode/templates/admin/settings/settings_mapping.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_mapping.html to rhodecode/templates/admin/settings/settings_mapping.mako |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_open_source.html to rhodecode/templates/admin/settings/settings_open_source.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_open_source.html to rhodecode/templates/admin/settings/settings_open_source.mako |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_search.html to rhodecode/templates/admin/settings/settings_search.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_search.html to rhodecode/templates/admin/settings/settings_search.mako |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_supervisor.html to rhodecode/templates/admin/settings/settings_supervisor.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_supervisor.html to rhodecode/templates/admin/settings/settings_supervisor.mako |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_supervisor_tail.html to rhodecode/templates/admin/settings/settings_supervisor_tail.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_supervisor_tail.html to rhodecode/templates/admin/settings/settings_supervisor_tail.mako |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_system.html to rhodecode/templates/admin/settings/settings_system.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_system.html to rhodecode/templates/admin/settings/settings_system.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_system_snapshot.html to rhodecode/templates/admin/settings/settings_system_snapshot.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_system_snapshot.html to rhodecode/templates/admin/settings/settings_system_snapshot.mako |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_system_update.html to rhodecode/templates/admin/settings/settings_system_update.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_system_update.html to rhodecode/templates/admin/settings/settings_system_update.mako |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_vcs.html to rhodecode/templates/admin/settings/settings_vcs.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_vcs.html to rhodecode/templates/admin/settings/settings_vcs.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_visual.html to rhodecode/templates/admin/settings/settings_visual.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/settings/settings_visual.html to rhodecode/templates/admin/settings/settings_visual.mako |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/user_groups/user_group_add.html to rhodecode/templates/admin/user_groups/user_group_add.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/user_groups/user_group_add.html to rhodecode/templates/admin/user_groups/user_group_add.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/user_groups/user_group_edit.html to rhodecode/templates/admin/user_groups/user_group_edit.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/user_groups/user_group_edit.html to rhodecode/templates/admin/user_groups/user_group_edit.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/user_groups/user_group_edit_advanced.html to rhodecode/templates/admin/user_groups/user_group_edit_advanced.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/user_groups/user_group_edit_advanced.html to rhodecode/templates/admin/user_groups/user_group_edit_advanced.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/user_groups/user_group_edit_global_perms.html to rhodecode/templates/admin/user_groups/user_group_edit_global_perms.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/user_groups/user_group_edit_global_perms.html to rhodecode/templates/admin/user_groups/user_group_edit_global_perms.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/user_groups/user_group_edit_perms.html to rhodecode/templates/admin/user_groups/user_group_edit_perms.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/user_groups/user_group_edit_perms.html to rhodecode/templates/admin/user_groups/user_group_edit_perms.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/user_groups/user_group_edit_perms_summary.html to rhodecode/templates/admin/user_groups/user_group_edit_perms_summary.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/user_groups/user_group_edit_perms_summary.html to rhodecode/templates/admin/user_groups/user_group_edit_perms_summary.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/user_groups/user_group_edit_settings.html to rhodecode/templates/admin/user_groups/user_group_edit_settings.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/user_groups/user_group_edit_settings.html to rhodecode/templates/admin/user_groups/user_group_edit_settings.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/user_groups/user_groups.html to rhodecode/templates/admin/user_groups/user_groups.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/user_groups/user_groups.html to rhodecode/templates/admin/user_groups/user_groups.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/users/user_add.html to rhodecode/templates/admin/users/user_add.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/users/user_add.html to rhodecode/templates/admin/users/user_add.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/users/user_edit.html to rhodecode/templates/admin/users/user_edit.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/users/user_edit.html to rhodecode/templates/admin/users/user_edit.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/users/user_edit_advanced.html to rhodecode/templates/admin/users/user_edit_advanced.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/users/user_edit_advanced.html to rhodecode/templates/admin/users/user_edit_advanced.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/users/user_edit_auth_tokens.html to rhodecode/templates/admin/users/user_edit_auth_tokens.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/users/user_edit_auth_tokens.html to rhodecode/templates/admin/users/user_edit_auth_tokens.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/users/user_edit_emails.html to rhodecode/templates/admin/users/user_edit_emails.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/users/user_edit_emails.html to rhodecode/templates/admin/users/user_edit_emails.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/users/user_edit_global_perms.html to rhodecode/templates/admin/users/user_edit_global_perms.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/users/user_edit_global_perms.html to rhodecode/templates/admin/users/user_edit_global_perms.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/users/user_edit_ips.html to rhodecode/templates/admin/users/user_edit_ips.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/users/user_edit_ips.html to rhodecode/templates/admin/users/user_edit_ips.mako |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/users/user_edit_perms_summary.html to rhodecode/templates/admin/users/user_edit_perms_summary.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/users/user_edit_perms_summary.html to rhodecode/templates/admin/users/user_edit_perms_summary.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/users/user_edit_profile.html to rhodecode/templates/admin/users/user_edit_profile.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/users/user_edit_profile.html to rhodecode/templates/admin/users/user_edit_profile.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/admin/users/users.html to rhodecode/templates/admin/users/users.mako |
|
NO CONTENT: file renamed from rhodecode/templates/admin/users/users.html to rhodecode/templates/admin/users/users.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/base/base.html to rhodecode/templates/base/base.mako |
|
NO CONTENT: file renamed from rhodecode/templates/base/base.html to rhodecode/templates/base/base.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/base/default_perms_box.html to rhodecode/templates/base/default_perms_box.mako |
|
NO CONTENT: file renamed from rhodecode/templates/base/default_perms_box.html to rhodecode/templates/base/default_perms_box.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/base/issue_tracker_settings.html to rhodecode/templates/base/issue_tracker_settings.mako |
|
NO CONTENT: file renamed from rhodecode/templates/base/issue_tracker_settings.html to rhodecode/templates/base/issue_tracker_settings.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/base/perms_summary.html to rhodecode/templates/base/perms_summary.mako |
|
NO CONTENT: file renamed from rhodecode/templates/base/perms_summary.html to rhodecode/templates/base/perms_summary.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/base/plugins_base.html to rhodecode/templates/base/plugins_base.mako |
|
NO CONTENT: file renamed from rhodecode/templates/base/plugins_base.html to rhodecode/templates/base/plugins_base.mako |
1 | NO CONTENT: file renamed from rhodecode/templates/base/root.html to rhodecode/templates/base/root.mako |
|
NO CONTENT: file renamed from rhodecode/templates/base/root.html to rhodecode/templates/base/root.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/base/vcs_settings.html to rhodecode/templates/base/vcs_settings.mako |
|
NO CONTENT: file renamed from rhodecode/templates/base/vcs_settings.html to rhodecode/templates/base/vcs_settings.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/bookmarks/bookmarks.html to rhodecode/templates/bookmarks/bookmarks.mako |
|
NO CONTENT: file renamed from rhodecode/templates/bookmarks/bookmarks.html to rhodecode/templates/bookmarks/bookmarks.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/bookmarks/bookmarks_data.html to rhodecode/templates/bookmarks/bookmarks_data.mako |
|
NO CONTENT: file renamed from rhodecode/templates/bookmarks/bookmarks_data.html to rhodecode/templates/bookmarks/bookmarks_data.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/branches/branches.html to rhodecode/templates/branches/branches.mako |
|
NO CONTENT: file renamed from rhodecode/templates/branches/branches.html to rhodecode/templates/branches/branches.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/branches/branches_data.html to rhodecode/templates/branches/branches_data.mako |
|
NO CONTENT: file renamed from rhodecode/templates/branches/branches_data.html to rhodecode/templates/branches/branches_data.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/changelog/changelog.html to rhodecode/templates/changelog/changelog.mako |
|
NO CONTENT: file renamed from rhodecode/templates/changelog/changelog.html to rhodecode/templates/changelog/changelog.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/changelog/changelog_details.html to rhodecode/templates/changelog/changelog_elements.mako |
|
NO CONTENT: file renamed from rhodecode/templates/changelog/changelog_details.html to rhodecode/templates/changelog/changelog_elements.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/changelog/changelog_file_history.html to rhodecode/templates/changelog/changelog_file_history.mako |
|
NO CONTENT: file renamed from rhodecode/templates/changelog/changelog_file_history.html to rhodecode/templates/changelog/changelog_file_history.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/changelog/changelog_summary_data.html to rhodecode/templates/changelog/changelog_summary_data.mako |
|
NO CONTENT: file renamed from rhodecode/templates/changelog/changelog_summary_data.html to rhodecode/templates/changelog/changelog_summary_data.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/changeset/changeset.html to rhodecode/templates/changeset/changeset.mako |
|
NO CONTENT: file renamed from rhodecode/templates/changeset/changeset.html to rhodecode/templates/changeset/changeset.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/changeset/changeset_comment_block.html to rhodecode/templates/changeset/changeset_comment_block.mako |
|
NO CONTENT: file renamed from rhodecode/templates/changeset/changeset_comment_block.html to rhodecode/templates/changeset/changeset_comment_block.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/changeset/changeset_file_comment.html to rhodecode/templates/changeset/changeset_file_comment.mako |
|
NO CONTENT: file renamed from rhodecode/templates/changeset/changeset_file_comment.html to rhodecode/templates/changeset/changeset_file_comment.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/changeset/changeset_range.html to rhodecode/templates/changeset/changeset_range.mako |
|
NO CONTENT: file renamed from rhodecode/templates/changeset/changeset_range.html to rhodecode/templates/changeset/changeset_range.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/changeset/diff_block.html to rhodecode/templates/changeset/diff_block.mako |
|
NO CONTENT: file renamed from rhodecode/templates/changeset/diff_block.html to rhodecode/templates/changeset/diff_block.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/changeset/patch_changeset.html to rhodecode/templates/changeset/patch_changeset.mako |
|
NO CONTENT: file renamed from rhodecode/templates/changeset/patch_changeset.html to rhodecode/templates/changeset/patch_changeset.mako |
1 | NO CONTENT: file renamed from rhodecode/templates/channelstream/plugin_init.html to rhodecode/templates/channelstream/plugin_init.mako |
|
NO CONTENT: file renamed from rhodecode/templates/channelstream/plugin_init.html to rhodecode/templates/channelstream/plugin_init.mako |
1 | NO CONTENT: file renamed from rhodecode/templates/codeblocks/diffs.html to rhodecode/templates/codeblocks/diffs.mako |
|
NO CONTENT: file renamed from rhodecode/templates/codeblocks/diffs.html to rhodecode/templates/codeblocks/diffs.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/codeblocks/source.html to rhodecode/templates/codeblocks/source.mako |
|
NO CONTENT: file renamed from rhodecode/templates/codeblocks/source.html to rhodecode/templates/codeblocks/source.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/compare/compare_commits.html to rhodecode/templates/compare/compare_commits.mako |
|
NO CONTENT: file renamed from rhodecode/templates/compare/compare_commits.html to rhodecode/templates/compare/compare_commits.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/compare/compare_diff.html to rhodecode/templates/compare/compare_diff.mako |
|
NO CONTENT: file renamed from rhodecode/templates/compare/compare_diff.html to rhodecode/templates/compare/compare_diff.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/data_table/_dt_elements.html to rhodecode/templates/data_table/_dt_elements.mako |
|
NO CONTENT: file renamed from rhodecode/templates/data_table/_dt_elements.html to rhodecode/templates/data_table/_dt_elements.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/errors/error_document.html to rhodecode/templates/errors/error_document.mako |
|
NO CONTENT: file renamed from rhodecode/templates/errors/error_document.html to rhodecode/templates/errors/error_document.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/files/base.html to rhodecode/templates/files/base.mako |
|
NO CONTENT: file renamed from rhodecode/templates/files/base.html to rhodecode/templates/files/base.mako |
1 | NO CONTENT: file renamed from rhodecode/templates/files/file_authors_box.html to rhodecode/templates/files/file_authors_box.mako |
|
NO CONTENT: file renamed from rhodecode/templates/files/file_authors_box.html to rhodecode/templates/files/file_authors_box.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/files/file_tree_author_box.html to rhodecode/templates/files/file_tree_author_box.mako |
|
NO CONTENT: file renamed from rhodecode/templates/files/file_tree_author_box.html to rhodecode/templates/files/file_tree_author_box.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/files/file_tree_detail.html to rhodecode/templates/files/file_tree_detail.mako |
|
NO CONTENT: file renamed from rhodecode/templates/files/file_tree_detail.html to rhodecode/templates/files/file_tree_detail.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/files/files.html to rhodecode/templates/files/files.mako |
|
NO CONTENT: file renamed from rhodecode/templates/files/files.html to rhodecode/templates/files/files.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/files/files_add.html to rhodecode/templates/files/files_add.mako |
|
NO CONTENT: file renamed from rhodecode/templates/files/files_add.html to rhodecode/templates/files/files_add.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/files/files_browser.html to rhodecode/templates/files/files_browser.mako |
|
NO CONTENT: file renamed from rhodecode/templates/files/files_browser.html to rhodecode/templates/files/files_browser.mako |
1 | NO CONTENT: file renamed from rhodecode/templates/files/files_browser_tree.html to rhodecode/templates/files/files_browser_tree.mako |
|
NO CONTENT: file renamed from rhodecode/templates/files/files_browser_tree.html to rhodecode/templates/files/files_browser_tree.mako |
1 | NO CONTENT: file renamed from rhodecode/templates/files/files_delete.html to rhodecode/templates/files/files_delete.mako |
|
NO CONTENT: file renamed from rhodecode/templates/files/files_delete.html to rhodecode/templates/files/files_delete.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/files/files_detail.html to rhodecode/templates/files/files_detail.mako |
|
NO CONTENT: file renamed from rhodecode/templates/files/files_detail.html to rhodecode/templates/files/files_detail.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/files/files_edit.html to rhodecode/templates/files/files_edit.mako |
|
NO CONTENT: file renamed from rhodecode/templates/files/files_edit.html to rhodecode/templates/files/files_edit.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/files/files_pjax.html to rhodecode/templates/files/files_pjax.mako |
|
NO CONTENT: file renamed from rhodecode/templates/files/files_pjax.html to rhodecode/templates/files/files_pjax.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/files/files_source.html to rhodecode/templates/files/files_source.mako |
|
NO CONTENT: file renamed from rhodecode/templates/files/files_source.html to rhodecode/templates/files/files_source.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/followers/followers.html to rhodecode/templates/followers/followers.mako |
|
NO CONTENT: file renamed from rhodecode/templates/followers/followers.html to rhodecode/templates/followers/followers.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/followers/followers_data.html to rhodecode/templates/followers/followers_data.mako |
|
NO CONTENT: file renamed from rhodecode/templates/followers/followers_data.html to rhodecode/templates/followers/followers_data.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/forks/fork.html to rhodecode/templates/forks/fork.mako |
|
NO CONTENT: file renamed from rhodecode/templates/forks/fork.html to rhodecode/templates/forks/fork.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/forks/forks.html to rhodecode/templates/forks/forks.mako |
|
NO CONTENT: file renamed from rhodecode/templates/forks/forks.html to rhodecode/templates/forks/forks.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/forks/forks_data.html to rhodecode/templates/forks/forks_data.mako |
|
NO CONTENT: file renamed from rhodecode/templates/forks/forks_data.html to rhodecode/templates/forks/forks_data.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/index.html to rhodecode/templates/index.mako |
|
NO CONTENT: file renamed from rhodecode/templates/index.html to rhodecode/templates/index.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/index_base.html to rhodecode/templates/index_base.mako |
|
NO CONTENT: file renamed from rhodecode/templates/index_base.html to rhodecode/templates/index_base.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/index_repo_group.html to rhodecode/templates/index_repo_group.mako |
|
NO CONTENT: file renamed from rhodecode/templates/index_repo_group.html to rhodecode/templates/index_repo_group.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/journal/journal.html to rhodecode/templates/journal/journal.mako |
|
NO CONTENT: file renamed from rhodecode/templates/journal/journal.html to rhodecode/templates/journal/journal.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/journal/journal_data.html to rhodecode/templates/journal/journal_data.mako |
|
NO CONTENT: file renamed from rhodecode/templates/journal/journal_data.html to rhodecode/templates/journal/journal_data.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/journal/public_journal.html to rhodecode/templates/journal/public_journal.mako |
|
NO CONTENT: file renamed from rhodecode/templates/journal/public_journal.html to rhodecode/templates/journal/public_journal.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/login.html to rhodecode/templates/login.mako |
|
NO CONTENT: file renamed from rhodecode/templates/login.html to rhodecode/templates/login.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/password_reset.html to rhodecode/templates/password_reset.mako |
|
NO CONTENT: file renamed from rhodecode/templates/password_reset.html to rhodecode/templates/password_reset.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/pullrequests/pullrequest.html to rhodecode/templates/pullrequests/pullrequest.mako |
|
NO CONTENT: file renamed from rhodecode/templates/pullrequests/pullrequest.html to rhodecode/templates/pullrequests/pullrequest.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/pullrequests/pullrequest_show.html to rhodecode/templates/pullrequests/pullrequest_show.mako |
|
NO CONTENT: file renamed from rhodecode/templates/pullrequests/pullrequest_show.html to rhodecode/templates/pullrequests/pullrequest_show.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/pullrequests/pullrequests.html to rhodecode/templates/pullrequests/pullrequests.mako |
|
NO CONTENT: file renamed from rhodecode/templates/pullrequests/pullrequests.html to rhodecode/templates/pullrequests/pullrequests.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/register.html to rhodecode/templates/register.mako |
|
NO CONTENT: file renamed from rhodecode/templates/register.html to rhodecode/templates/register.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/search/search.html to rhodecode/templates/search/search.mako |
|
NO CONTENT: file renamed from rhodecode/templates/search/search.html to rhodecode/templates/search/search.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/search/search_commit.html to rhodecode/templates/search/search_commit.mako |
|
NO CONTENT: file renamed from rhodecode/templates/search/search_commit.html to rhodecode/templates/search/search_commit.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/search/search_content.html to rhodecode/templates/search/search_content.mako |
|
NO CONTENT: file renamed from rhodecode/templates/search/search_content.html to rhodecode/templates/search/search_content.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/search/search_path.html to rhodecode/templates/search/search_path.mako |
|
NO CONTENT: file renamed from rhodecode/templates/search/search_path.html to rhodecode/templates/search/search_path.mako |
1 | NO CONTENT: file renamed from rhodecode/templates/search/search_repository.html to rhodecode/templates/search/search_repository.mako |
|
NO CONTENT: file renamed from rhodecode/templates/search/search_repository.html to rhodecode/templates/search/search_repository.mako |
1 | NO CONTENT: file renamed from rhodecode/templates/summary/base.html to rhodecode/templates/summary/base.mako |
|
NO CONTENT: file renamed from rhodecode/templates/summary/base.html to rhodecode/templates/summary/base.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/summary/components.html to rhodecode/templates/summary/components.mako |
|
NO CONTENT: file renamed from rhodecode/templates/summary/components.html to rhodecode/templates/summary/components.mako |
1 | NO CONTENT: file renamed from rhodecode/templates/summary/missing_requirements.html to rhodecode/templates/summary/missing_requirements.mako |
|
NO CONTENT: file renamed from rhodecode/templates/summary/missing_requirements.html to rhodecode/templates/summary/missing_requirements.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/summary/summary.html to rhodecode/templates/summary/summary.mako |
|
NO CONTENT: file renamed from rhodecode/templates/summary/summary.html to rhodecode/templates/summary/summary.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/tags/tags.html to rhodecode/templates/tags/tags.mako |
|
NO CONTENT: file renamed from rhodecode/templates/tags/tags.html to rhodecode/templates/tags/tags.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/tags/tags_data.html to rhodecode/templates/tags/tags_data.mako |
|
NO CONTENT: file renamed from rhodecode/templates/tags/tags_data.html to rhodecode/templates/tags/tags_data.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/users/user.html to rhodecode/templates/users/user.mako |
|
NO CONTENT: file renamed from rhodecode/templates/users/user.html to rhodecode/templates/users/user.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/users/user_profile.html to rhodecode/templates/users/user_profile.mako |
|
NO CONTENT: file renamed from rhodecode/templates/users/user_profile.html to rhodecode/templates/users/user_profile.mako | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file renamed from rhodecode/templates/widgets.html to rhodecode/templates/widgets.mako |
|
NO CONTENT: file renamed from rhodecode/templates/widgets.html to rhodecode/templates/widgets.mako |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: modified file |
|
NO CONTENT: modified file | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed | ||
The requested commit or file is too big and content was truncated. Show full diff |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed | ||
The requested commit or file is too big and content was truncated. Show full diff |
General Comments 0
You need to be logged in to leave comments.
Login now