Show More
@@ -0,0 +1,17 b'' | |||||
|
1 | |RCE| 4.0.1 |RNS| | |||
|
2 | ----------------- | |||
|
3 | ||||
|
4 | Release Date | |||
|
5 | ^^^^^^^^^^^^ | |||
|
6 | ||||
|
7 | - 2016-05-25 | |||
|
8 | ||||
|
9 | Fixes | |||
|
10 | ^^^^^ | |||
|
11 | ||||
|
12 | - fixed default session to be file based instead of memory which causes | |||
|
13 | problems in multi-worker setup | |||
|
14 | - ui: fixing forks table #3959 | |||
|
15 | - ui: fixed gravatars misalignment issues | |||
|
16 | - logging: fixed excesive formatting on auth logging | |||
|
17 | - pull requests: better ref selection when opening PRs from changelog |
@@ -1,5 +1,6 b'' | |||||
1 | [bumpversion] |
|
1 | [bumpversion] | |
2 |
current_version = 4.0. |
|
2 | current_version = 4.0.1 | |
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] | |
|
6 |
@@ -1,39 +1,47 b'' | |||||
1 |
|
1 | |||
2 | WEBPACK=./node_modules/webpack/bin/webpack.js |
|
2 | WEBPACK=./node_modules/webpack/bin/webpack.js | |
3 | GRUNT=grunt |
|
3 | GRUNT=grunt | |
4 | NODE_PATH=./node_modules |
|
4 | NODE_PATH=./node_modules | |
5 | FLAKE8=flake8 setup.py pytest_pylons/ rhodecode/ --select=E124 --ignore=E711,E712,E510,E121,E122,E126,E127,E128,E501,F401 --max-line-length=100 --exclude=*rhodecode/lib/dbmigrate/*,*rhodecode/tests/*,*rhodecode/lib/vcs/utils/* |
|
5 | FLAKE8=flake8 setup.py pytest_pylons/ rhodecode/ --select=E124 --ignore=E711,E712,E510,E121,E122,E126,E127,E128,E501,F401 --max-line-length=100 --exclude=*rhodecode/lib/dbmigrate/*,*rhodecode/tests/*,*rhodecode/lib/vcs/utils/* | |
6 | CI_PREFIX=enterprise |
|
6 | CI_PREFIX=enterprise | |
7 |
|
7 | |||
8 |
.PHONY: |
|
8 | .PHONY: docs docs-clean ci-docs clean test test-clean test-lint test-only | |
|
9 | ||||
|
10 | ||||
|
11 | docs: | |||
|
12 | (cd docs; nix-build default.nix -o result; make clean html) | |||
9 |
|
|
13 | ||
10 | help: |
|
14 | docs-clean: | |
11 | @echo "TODO: describe Makefile" |
|
15 | (cd docs; make clean) | |
|
16 | ||||
|
17 | ci-docs: docs; | |||
|
18 | ||||
12 |
|
19 | |||
13 | clean: test-clean |
|
20 | clean: test-clean | |
14 | find . -type f \( -iname '*.c' -o -iname '*.pyc' -o -iname '*.so' \) -exec rm '{}' ';' |
|
21 | find . -type f \( -iname '*.c' -o -iname '*.pyc' -o -iname '*.so' \) -exec rm '{}' ';' | |
15 |
|
22 | |||
16 | test: test-clean test-lint test-only |
|
23 | test: test-clean test-lint test-only | |
17 |
|
24 | |||
18 | test-clean: |
|
25 | test-clean: | |
19 | rm -rf coverage.xml htmlcov junit.xml pylint.log result |
|
26 | rm -rf coverage.xml htmlcov junit.xml pylint.log result | |
20 |
|
27 | |||
21 | test-lint: |
|
28 | test-lint: | |
22 | if [ "$$IN_NIX_SHELL" = "1" ]; then \ |
|
29 | if [ "$$IN_NIX_SHELL" = "1" ]; then \ | |
23 | $(FLAKE8); \ |
|
30 | $(FLAKE8); \ | |
24 | else \ |
|
31 | else \ | |
25 | $(FLAKE8) --format=pylint --exit-zero > pylint.log; \ |
|
32 | $(FLAKE8) --format=pylint --exit-zero > pylint.log; \ | |
26 | fi |
|
33 | fi | |
27 |
|
34 | |||
28 | test-only: |
|
35 | test-only: | |
29 | PYTHONHASHSEED=random py.test -vv -r xw --cov=rhodecode --cov-report=term-missing --cov-report=html rhodecode/tests/ |
|
36 | PYTHONHASHSEED=random py.test -vv -r xw --cov=rhodecode --cov-report=term-missing --cov-report=html rhodecode/tests/ | |
30 |
|
37 | |||
31 | web-build: |
|
38 | web-build: | |
32 | NODE_PATH=$(NODE_PATH) $(GRUNT) |
|
39 | NODE_PATH=$(NODE_PATH) $(GRUNT) | |
33 |
|
40 | |||
34 | web-test: |
|
41 | web-test: | |
35 | @echo "no test for our javascript, yet!" |
|
42 | @echo "no test for our javascript, yet!" | |
36 |
|
43 | |||
37 | docs-bootstrap: |
|
44 | docs-bootstrap: | |
38 | (cd docs; nix-build default.nix -o result) |
|
45 | (cd docs; nix-build default.nix -o result) | |
39 | @echo "Please go to docs folder and run make html" |
|
46 | @echo "Please go to docs folder and run make html" | |
|
47 |
@@ -1,575 +1,577 b'' | |||||
1 | ################################################################################ |
|
1 | ################################################################################ | |
2 | ################################################################################ |
|
2 | ################################################################################ | |
3 | # RhodeCode Enterprise - configuration file # |
|
3 | # RhodeCode Enterprise - configuration file # | |
4 | # Built-in functions and variables # |
|
4 | # Built-in functions and variables # | |
5 | # The %(here)s variable will be replaced with the parent directory of this file# |
|
5 | # The %(here)s variable will be replaced with the parent directory of this file# | |
6 | # # |
|
6 | # # | |
7 | ################################################################################ |
|
7 | ################################################################################ | |
8 |
|
8 | |||
9 | [DEFAULT] |
|
9 | [DEFAULT] | |
10 | debug = true |
|
10 | debug = true | |
11 | pdebug = false |
|
11 | pdebug = false | |
12 | ################################################################################ |
|
12 | ################################################################################ | |
13 | ## Uncomment and replace with the email address which should receive ## |
|
13 | ## Uncomment and replace with the email address which should receive ## | |
14 | ## any error reports after an application crash ## |
|
14 | ## any error reports after an application crash ## | |
15 | ## Additionally these settings will be used by the RhodeCode mailing system ## |
|
15 | ## Additionally these settings will be used by the RhodeCode mailing system ## | |
16 | ################################################################################ |
|
16 | ################################################################################ | |
17 | #email_to = admin@localhost |
|
17 | #email_to = admin@localhost | |
18 | #error_email_from = paste_error@localhost |
|
18 | #error_email_from = paste_error@localhost | |
19 | #app_email_from = rhodecode-noreply@localhost |
|
19 | #app_email_from = rhodecode-noreply@localhost | |
20 | #error_message = |
|
20 | #error_message = | |
21 | #email_prefix = [RhodeCode] |
|
21 | #email_prefix = [RhodeCode] | |
22 |
|
22 | |||
23 | #smtp_server = mail.server.com |
|
23 | #smtp_server = mail.server.com | |
24 | #smtp_username = |
|
24 | #smtp_username = | |
25 | #smtp_password = |
|
25 | #smtp_password = | |
26 | #smtp_port = |
|
26 | #smtp_port = | |
27 | #smtp_use_tls = false |
|
27 | #smtp_use_tls = false | |
28 | #smtp_use_ssl = true |
|
28 | #smtp_use_ssl = true | |
29 | ## Specify available auth parameters here (e.g. LOGIN PLAIN CRAM-MD5, etc.) |
|
29 | ## Specify available auth parameters here (e.g. LOGIN PLAIN CRAM-MD5, etc.) | |
30 | #smtp_auth = |
|
30 | #smtp_auth = | |
31 |
|
31 | |||
32 | [server:main] |
|
32 | [server:main] | |
33 | ## COMMON ## |
|
33 | ## COMMON ## | |
34 | host = 127.0.0.1 |
|
34 | host = 127.0.0.1 | |
35 | port = 5000 |
|
35 | port = 5000 | |
36 |
|
36 | |||
37 | ########################## |
|
37 | ########################## | |
38 | ## WAITRESS WSGI SERVER ## |
|
38 | ## WAITRESS WSGI SERVER ## | |
39 | ########################## |
|
39 | ########################## | |
40 | use = egg:waitress#main |
|
40 | use = egg:waitress#main | |
41 | ## number of worker threads |
|
41 | ## number of worker threads | |
42 | threads = 5 |
|
42 | threads = 5 | |
43 | ## MAX BODY SIZE 100GB |
|
43 | ## MAX BODY SIZE 100GB | |
44 | max_request_body_size = 107374182400 |
|
44 | max_request_body_size = 107374182400 | |
45 | ## Use poll instead of select, fixes file descriptors limits problems. |
|
45 | ## Use poll instead of select, fixes file descriptors limits problems. | |
46 | ## May not work on old windows systems. |
|
46 | ## May not work on old windows systems. | |
47 | asyncore_use_poll = true |
|
47 | asyncore_use_poll = true | |
48 |
|
48 | |||
49 |
|
49 | |||
50 | ########################## |
|
50 | ########################## | |
51 | ## GUNICORN WSGI SERVER ## |
|
51 | ## GUNICORN WSGI SERVER ## | |
52 | ########################## |
|
52 | ########################## | |
53 | ## run with gunicorn --log-config <inifile.ini> --paste <inifile.ini> |
|
53 | ## run with gunicorn --log-config <inifile.ini> --paste <inifile.ini> | |
54 | #use = egg:gunicorn#main |
|
54 | #use = egg:gunicorn#main | |
55 | ## Sets the number of process workers. You must set `instance_id = *` |
|
55 | ## Sets the number of process workers. You must set `instance_id = *` | |
56 | ## when this option is set to more than one worker, recommended |
|
56 | ## when this option is set to more than one worker, recommended | |
57 | ## value is (2 * NUMBER_OF_CPUS + 1), eg 2CPU = 5 workers |
|
57 | ## value is (2 * NUMBER_OF_CPUS + 1), eg 2CPU = 5 workers | |
58 | ## The `instance_id = *` must be set in the [app:main] section below |
|
58 | ## The `instance_id = *` must be set in the [app:main] section below | |
59 | #workers = 1 |
|
59 | #workers = 1 | |
60 | ## number of threads for each of the worker, must be set to 1 for gevent |
|
60 | ## number of threads for each of the worker, must be set to 1 for gevent | |
61 | ## generally recommened to be at 1 |
|
61 | ## generally recommened to be at 1 | |
62 | #threads = 1 |
|
62 | #threads = 1 | |
63 | ## process name |
|
63 | ## process name | |
64 | #proc_name = rhodecode |
|
64 | #proc_name = rhodecode | |
65 | ## type of worker class, one of sync, gevent |
|
65 | ## type of worker class, one of sync, gevent | |
66 | ## recommended for bigger setup is using of of other than sync one |
|
66 | ## recommended for bigger setup is using of of other than sync one | |
67 | #worker_class = sync |
|
67 | #worker_class = sync | |
|
68 | ## The maximum number of simultaneous clients. Valid only for Gevent | |||
|
69 | #worker_connections = 10 | |||
68 | ## max number of requests that worker will handle before being gracefully |
|
70 | ## max number of requests that worker will handle before being gracefully | |
69 | ## restarted, could prevent memory leaks |
|
71 | ## restarted, could prevent memory leaks | |
70 | #max_requests = 1000 |
|
72 | #max_requests = 1000 | |
71 | #max_requests_jitter = 30 |
|
73 | #max_requests_jitter = 30 | |
72 | ## ammount of time a worker can spend with handling a request before it |
|
74 | ## ammount of time a worker can spend with handling a request before it | |
73 | ## gets killed and restarted. Set to 6hrs |
|
75 | ## gets killed and restarted. Set to 6hrs | |
74 | #timeout = 21600 |
|
76 | #timeout = 21600 | |
75 |
|
77 | |||
76 |
|
78 | |||
77 | ## prefix middleware for RhodeCode, disables force_https flag. |
|
79 | ## prefix middleware for RhodeCode, disables force_https flag. | |
78 | ## allows to set RhodeCode under a prefix in server. |
|
80 | ## allows to set RhodeCode under a prefix in server. | |
79 | ## eg https://server.com/<prefix>. Enable `filter-with =` option below as well. |
|
81 | ## eg https://server.com/<prefix>. Enable `filter-with =` option below as well. | |
80 | #[filter:proxy-prefix] |
|
82 | #[filter:proxy-prefix] | |
81 | #use = egg:PasteDeploy#prefix |
|
83 | #use = egg:PasteDeploy#prefix | |
82 | #prefix = /<your-prefix> |
|
84 | #prefix = /<your-prefix> | |
83 |
|
85 | |||
84 | [app:main] |
|
86 | [app:main] | |
85 | use = egg:rhodecode-enterprise-ce |
|
87 | use = egg:rhodecode-enterprise-ce | |
86 | ## enable proxy prefix middleware, defined below |
|
88 | ## enable proxy prefix middleware, defined below | |
87 | #filter-with = proxy-prefix |
|
89 | #filter-with = proxy-prefix | |
88 |
|
90 | |||
89 | # During development the we want to have the debug toolbar enabled |
|
91 | # During development the we want to have the debug toolbar enabled | |
90 | pyramid.includes = |
|
92 | pyramid.includes = | |
91 | pyramid_debugtoolbar |
|
93 | pyramid_debugtoolbar | |
92 | rhodecode.utils.debugtoolbar |
|
94 | rhodecode.utils.debugtoolbar | |
93 | rhodecode.lib.middleware.request_wrapper |
|
95 | rhodecode.lib.middleware.request_wrapper | |
94 |
|
96 | |||
95 | pyramid.reload_templates = true |
|
97 | pyramid.reload_templates = true | |
96 |
|
98 | |||
97 | debugtoolbar.hosts = 0.0.0.0/0 |
|
99 | debugtoolbar.hosts = 0.0.0.0/0 | |
98 | debugtoolbar.exclude_prefixes = |
|
100 | debugtoolbar.exclude_prefixes = | |
99 | /css |
|
101 | /css | |
100 | /fonts |
|
102 | /fonts | |
101 | /images |
|
103 | /images | |
102 | /js |
|
104 | /js | |
103 |
|
105 | |||
104 | ## RHODECODE PLUGINS ## |
|
106 | ## RHODECODE PLUGINS ## | |
105 | rhodecode.includes = |
|
107 | rhodecode.includes = | |
106 | rhodecode.api |
|
108 | rhodecode.api | |
107 |
|
109 | |||
108 |
|
110 | |||
109 | # api prefix url |
|
111 | # api prefix url | |
110 | rhodecode.api.url = /_admin/api |
|
112 | rhodecode.api.url = /_admin/api | |
111 |
|
113 | |||
112 |
|
114 | |||
113 | ## END RHODECODE PLUGINS ## |
|
115 | ## END RHODECODE PLUGINS ## | |
114 |
|
116 | |||
115 | full_stack = true |
|
117 | full_stack = true | |
116 |
|
118 | |||
117 | ## Serve static files via RhodeCode, disable to serve them via HTTP server |
|
119 | ## Serve static files via RhodeCode, disable to serve them via HTTP server | |
118 | static_files = true |
|
120 | static_files = true | |
119 |
|
121 | |||
120 | ## Optional Languages |
|
122 | ## Optional Languages | |
121 | ## en(default), be, de, es, fr, it, ja, pl, pt, ru, zh |
|
123 | ## en(default), be, de, es, fr, it, ja, pl, pt, ru, zh | |
122 | lang = en |
|
124 | lang = en | |
123 |
|
125 | |||
124 | ## perform a full repository scan on each server start, this should be |
|
126 | ## perform a full repository scan on each server start, this should be | |
125 | ## set to false after first startup, to allow faster server restarts. |
|
127 | ## set to false after first startup, to allow faster server restarts. | |
126 | startup.import_repos = false |
|
128 | startup.import_repos = false | |
127 |
|
129 | |||
128 | ## Uncomment and set this path to use archive download cache. |
|
130 | ## Uncomment and set this path to use archive download cache. | |
129 | ## Once enabled, generated archives will be cached at this location |
|
131 | ## Once enabled, generated archives will be cached at this location | |
130 | ## and served from the cache during subsequent requests for the same archive of |
|
132 | ## and served from the cache during subsequent requests for the same archive of | |
131 | ## the repository. |
|
133 | ## the repository. | |
132 | #archive_cache_dir = /tmp/tarballcache |
|
134 | #archive_cache_dir = /tmp/tarballcache | |
133 |
|
135 | |||
134 | ## change this to unique ID for security |
|
136 | ## change this to unique ID for security | |
135 | app_instance_uuid = rc-production |
|
137 | app_instance_uuid = rc-production | |
136 |
|
138 | |||
137 | ## cut off limit for large diffs (size in bytes) |
|
139 | ## cut off limit for large diffs (size in bytes) | |
138 | cut_off_limit_diff = 1024000 |
|
140 | cut_off_limit_diff = 1024000 | |
139 | cut_off_limit_file = 256000 |
|
141 | cut_off_limit_file = 256000 | |
140 |
|
142 | |||
141 | ## use cache version of scm repo everywhere |
|
143 | ## use cache version of scm repo everywhere | |
142 | vcs_full_cache = true |
|
144 | vcs_full_cache = true | |
143 |
|
145 | |||
144 | ## force https in RhodeCode, fixes https redirects, assumes it's always https |
|
146 | ## force https in RhodeCode, fixes https redirects, assumes it's always https | |
145 | ## Normally this is controlled by proper http flags sent from http server |
|
147 | ## Normally this is controlled by proper http flags sent from http server | |
146 | force_https = false |
|
148 | force_https = false | |
147 |
|
149 | |||
148 | ## use Strict-Transport-Security headers |
|
150 | ## use Strict-Transport-Security headers | |
149 | use_htsts = false |
|
151 | use_htsts = false | |
150 |
|
152 | |||
151 | ## number of commits stats will parse on each iteration |
|
153 | ## number of commits stats will parse on each iteration | |
152 | commit_parse_limit = 25 |
|
154 | commit_parse_limit = 25 | |
153 |
|
155 | |||
154 | ## git rev filter option, --all is the default filter, if you need to |
|
156 | ## git rev filter option, --all is the default filter, if you need to | |
155 | ## hide all refs in changelog switch this to --branches --tags |
|
157 | ## hide all refs in changelog switch this to --branches --tags | |
156 | git_rev_filter = --branches --tags |
|
158 | git_rev_filter = --branches --tags | |
157 |
|
159 | |||
158 | # Set to true if your repos are exposed using the dumb protocol |
|
160 | # Set to true if your repos are exposed using the dumb protocol | |
159 | git_update_server_info = false |
|
161 | git_update_server_info = false | |
160 |
|
162 | |||
161 | ## RSS/ATOM feed options |
|
163 | ## RSS/ATOM feed options | |
162 | rss_cut_off_limit = 256000 |
|
164 | rss_cut_off_limit = 256000 | |
163 | rss_items_per_page = 10 |
|
165 | rss_items_per_page = 10 | |
164 | rss_include_diff = false |
|
166 | rss_include_diff = false | |
165 |
|
167 | |||
166 | ## gist URL alias, used to create nicer urls for gist. This should be an |
|
168 | ## gist URL alias, used to create nicer urls for gist. This should be an | |
167 | ## url that does rewrites to _admin/gists/<gistid>. |
|
169 | ## url that does rewrites to _admin/gists/<gistid>. | |
168 | ## example: http://gist.rhodecode.org/{gistid}. Empty means use the internal |
|
170 | ## example: http://gist.rhodecode.org/{gistid}. Empty means use the internal | |
169 | ## RhodeCode url, ie. http[s]://rhodecode.server/_admin/gists/<gistid> |
|
171 | ## RhodeCode url, ie. http[s]://rhodecode.server/_admin/gists/<gistid> | |
170 | gist_alias_url = |
|
172 | gist_alias_url = | |
171 |
|
173 | |||
172 | ## List of controllers (using glob pattern syntax) that AUTH TOKENS could be |
|
174 | ## List of controllers (using glob pattern syntax) that AUTH TOKENS could be | |
173 | ## used for access. |
|
175 | ## used for access. | |
174 | ## Adding ?auth_token = <token> to the url authenticates this request as if it |
|
176 | ## Adding ?auth_token = <token> to the url authenticates this request as if it | |
175 | ## came from the the logged in user who own this authentication token. |
|
177 | ## came from the the logged in user who own this authentication token. | |
176 | ## |
|
178 | ## | |
177 | ## Syntax is <ControllerClass>:<function_pattern>. |
|
179 | ## Syntax is <ControllerClass>:<function_pattern>. | |
178 | ## To enable access to raw_files put `FilesController:raw`. |
|
180 | ## To enable access to raw_files put `FilesController:raw`. | |
179 | ## To enable access to patches add `ChangesetController:changeset_patch`. |
|
181 | ## To enable access to patches add `ChangesetController:changeset_patch`. | |
180 | ## The list should be "," separated and on a single line. |
|
182 | ## The list should be "," separated and on a single line. | |
181 | ## |
|
183 | ## | |
182 | ## Recommended controllers to enable: |
|
184 | ## Recommended controllers to enable: | |
183 | # ChangesetController:changeset_patch, |
|
185 | # ChangesetController:changeset_patch, | |
184 | # ChangesetController:changeset_raw, |
|
186 | # ChangesetController:changeset_raw, | |
185 | # FilesController:raw, |
|
187 | # FilesController:raw, | |
186 | # FilesController:archivefile, |
|
188 | # FilesController:archivefile, | |
187 | # GistsController:*, |
|
189 | # GistsController:*, | |
188 | api_access_controllers_whitelist = |
|
190 | api_access_controllers_whitelist = | |
189 |
|
191 | |||
190 | ## default encoding used to convert from and to unicode |
|
192 | ## default encoding used to convert from and to unicode | |
191 | ## can be also a comma separated list of encoding in case of mixed encodings |
|
193 | ## can be also a comma separated list of encoding in case of mixed encodings | |
192 | default_encoding = UTF-8 |
|
194 | default_encoding = UTF-8 | |
193 |
|
195 | |||
194 | ## instance-id prefix |
|
196 | ## instance-id prefix | |
195 | ## a prefix key for this instance used for cache invalidation when running |
|
197 | ## a prefix key for this instance used for cache invalidation when running | |
196 | ## multiple instances of rhodecode, make sure it's globally unique for |
|
198 | ## multiple instances of rhodecode, make sure it's globally unique for | |
197 | ## all running rhodecode instances. Leave empty if you don't use it |
|
199 | ## all running rhodecode instances. Leave empty if you don't use it | |
198 | instance_id = |
|
200 | instance_id = | |
199 |
|
201 | |||
200 | ## alternative return HTTP header for failed authentication. Default HTTP |
|
202 | ## alternative return HTTP header for failed authentication. Default HTTP | |
201 | ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with |
|
203 | ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with | |
202 | ## handling that causing a series of failed authentication calls. |
|
204 | ## handling that causing a series of failed authentication calls. | |
203 | ## Set this variable to 403 to return HTTPForbidden, or any other HTTP code |
|
205 | ## Set this variable to 403 to return HTTPForbidden, or any other HTTP code | |
204 | ## This will be served instead of default 401 on bad authnetication |
|
206 | ## This will be served instead of default 401 on bad authnetication | |
205 | auth_ret_code = |
|
207 | auth_ret_code = | |
206 |
|
208 | |||
207 | ## use special detection method when serving auth_ret_code, instead of serving |
|
209 | ## use special detection method when serving auth_ret_code, instead of serving | |
208 | ## ret_code directly, use 401 initially (Which triggers credentials prompt) |
|
210 | ## ret_code directly, use 401 initially (Which triggers credentials prompt) | |
209 | ## and then serve auth_ret_code to clients |
|
211 | ## and then serve auth_ret_code to clients | |
210 | auth_ret_code_detection = false |
|
212 | auth_ret_code_detection = false | |
211 |
|
213 | |||
212 | ## locking return code. When repository is locked return this HTTP code. 2XX |
|
214 | ## locking return code. When repository is locked return this HTTP code. 2XX | |
213 | ## codes don't break the transactions while 4XX codes do |
|
215 | ## codes don't break the transactions while 4XX codes do | |
214 | lock_ret_code = 423 |
|
216 | lock_ret_code = 423 | |
215 |
|
217 | |||
216 | ## allows to change the repository location in settings page |
|
218 | ## allows to change the repository location in settings page | |
217 | allow_repo_location_change = true |
|
219 | allow_repo_location_change = true | |
218 |
|
220 | |||
219 | ## allows to setup custom hooks in settings page |
|
221 | ## allows to setup custom hooks in settings page | |
220 | allow_custom_hooks_settings = true |
|
222 | allow_custom_hooks_settings = true | |
221 |
|
223 | |||
222 | ## generated license token, goto license page in RhodeCode settings to obtain |
|
224 | ## generated license token, goto license page in RhodeCode settings to obtain | |
223 | ## new token |
|
225 | ## new token | |
224 | license_token = |
|
226 | license_token = | |
225 |
|
227 | |||
226 | ## supervisor connection uri, for managing supervisor and logs. |
|
228 | ## supervisor connection uri, for managing supervisor and logs. | |
227 | supervisor.uri = |
|
229 | supervisor.uri = | |
228 | ## supervisord group name/id we only want this RC instance to handle |
|
230 | ## supervisord group name/id we only want this RC instance to handle | |
229 | supervisor.group_id = dev |
|
231 | supervisor.group_id = dev | |
230 |
|
232 | |||
231 | ## Display extended labs settings |
|
233 | ## Display extended labs settings | |
232 | labs_settings_active = true |
|
234 | labs_settings_active = true | |
233 |
|
235 | |||
234 | #################################### |
|
236 | #################################### | |
235 | ### CELERY CONFIG #### |
|
237 | ### CELERY CONFIG #### | |
236 | #################################### |
|
238 | #################################### | |
237 | use_celery = false |
|
239 | use_celery = false | |
238 | broker.host = localhost |
|
240 | broker.host = localhost | |
239 | broker.vhost = rabbitmqhost |
|
241 | broker.vhost = rabbitmqhost | |
240 | broker.port = 5672 |
|
242 | broker.port = 5672 | |
241 | broker.user = rabbitmq |
|
243 | broker.user = rabbitmq | |
242 | broker.password = qweqwe |
|
244 | broker.password = qweqwe | |
243 |
|
245 | |||
244 | celery.imports = rhodecode.lib.celerylib.tasks |
|
246 | celery.imports = rhodecode.lib.celerylib.tasks | |
245 |
|
247 | |||
246 | celery.result.backend = amqp |
|
248 | celery.result.backend = amqp | |
247 | celery.result.dburi = amqp:// |
|
249 | celery.result.dburi = amqp:// | |
248 | celery.result.serialier = json |
|
250 | celery.result.serialier = json | |
249 |
|
251 | |||
250 | #celery.send.task.error.emails = true |
|
252 | #celery.send.task.error.emails = true | |
251 | #celery.amqp.task.result.expires = 18000 |
|
253 | #celery.amqp.task.result.expires = 18000 | |
252 |
|
254 | |||
253 | celeryd.concurrency = 2 |
|
255 | celeryd.concurrency = 2 | |
254 | #celeryd.log.file = celeryd.log |
|
256 | #celeryd.log.file = celeryd.log | |
255 | celeryd.log.level = debug |
|
257 | celeryd.log.level = debug | |
256 | celeryd.max.tasks.per.child = 1 |
|
258 | celeryd.max.tasks.per.child = 1 | |
257 |
|
259 | |||
258 | ## tasks will never be sent to the queue, but executed locally instead. |
|
260 | ## tasks will never be sent to the queue, but executed locally instead. | |
259 | celery.always.eager = false |
|
261 | celery.always.eager = false | |
260 |
|
262 | |||
261 | #################################### |
|
263 | #################################### | |
262 | ### BEAKER CACHE #### |
|
264 | ### BEAKER CACHE #### | |
263 | #################################### |
|
265 | #################################### | |
264 | # default cache dir for templates. Putting this into a ramdisk |
|
266 | # default cache dir for templates. Putting this into a ramdisk | |
265 | ## can boost performance, eg. %(here)s/data_ramdisk |
|
267 | ## can boost performance, eg. %(here)s/data_ramdisk | |
266 | cache_dir = %(here)s/data |
|
268 | cache_dir = %(here)s/data | |
267 |
|
269 | |||
268 | ## locking and default file storage for Beaker. Putting this into a ramdisk |
|
270 | ## locking and default file storage for Beaker. Putting this into a ramdisk | |
269 | ## can boost performance, eg. %(here)s/data_ramdisk/cache/beaker_data |
|
271 | ## can boost performance, eg. %(here)s/data_ramdisk/cache/beaker_data | |
270 | beaker.cache.data_dir = %(here)s/data/cache/beaker_data |
|
272 | beaker.cache.data_dir = %(here)s/data/cache/beaker_data | |
271 | beaker.cache.lock_dir = %(here)s/data/cache/beaker_lock |
|
273 | beaker.cache.lock_dir = %(here)s/data/cache/beaker_lock | |
272 |
|
274 | |||
273 | beaker.cache.regions = super_short_term, short_term, long_term, sql_cache_short, auth_plugins, repo_cache_long |
|
275 | beaker.cache.regions = super_short_term, short_term, long_term, sql_cache_short, auth_plugins, repo_cache_long | |
274 |
|
276 | |||
275 | beaker.cache.super_short_term.type = memory |
|
277 | beaker.cache.super_short_term.type = memory | |
276 | beaker.cache.super_short_term.expire = 10 |
|
278 | beaker.cache.super_short_term.expire = 10 | |
277 | beaker.cache.super_short_term.key_length = 256 |
|
279 | beaker.cache.super_short_term.key_length = 256 | |
278 |
|
280 | |||
279 | beaker.cache.short_term.type = memory |
|
281 | beaker.cache.short_term.type = memory | |
280 | beaker.cache.short_term.expire = 60 |
|
282 | beaker.cache.short_term.expire = 60 | |
281 | beaker.cache.short_term.key_length = 256 |
|
283 | beaker.cache.short_term.key_length = 256 | |
282 |
|
284 | |||
283 | beaker.cache.long_term.type = memory |
|
285 | beaker.cache.long_term.type = memory | |
284 | beaker.cache.long_term.expire = 36000 |
|
286 | beaker.cache.long_term.expire = 36000 | |
285 | beaker.cache.long_term.key_length = 256 |
|
287 | beaker.cache.long_term.key_length = 256 | |
286 |
|
288 | |||
287 | beaker.cache.sql_cache_short.type = memory |
|
289 | beaker.cache.sql_cache_short.type = memory | |
288 | beaker.cache.sql_cache_short.expire = 10 |
|
290 | beaker.cache.sql_cache_short.expire = 10 | |
289 | beaker.cache.sql_cache_short.key_length = 256 |
|
291 | beaker.cache.sql_cache_short.key_length = 256 | |
290 |
|
292 | |||
291 | # default is memory cache, configure only if required |
|
293 | # default is memory cache, configure only if required | |
292 | # using multi-node or multi-worker setup |
|
294 | # using multi-node or multi-worker setup | |
293 | #beaker.cache.auth_plugins.type = ext:database |
|
295 | #beaker.cache.auth_plugins.type = ext:database | |
294 | #beaker.cache.auth_plugins.lock_dir = %(here)s/data/cache/auth_plugin_lock |
|
296 | #beaker.cache.auth_plugins.lock_dir = %(here)s/data/cache/auth_plugin_lock | |
295 | #beaker.cache.auth_plugins.url = postgresql://postgres:secret@localhost/rhodecode |
|
297 | #beaker.cache.auth_plugins.url = postgresql://postgres:secret@localhost/rhodecode | |
296 | #beaker.cache.auth_plugins.url = mysql://root:secret@127.0.0.1/rhodecode |
|
298 | #beaker.cache.auth_plugins.url = mysql://root:secret@127.0.0.1/rhodecode | |
297 | #beaker.cache.auth_plugins.sa.pool_recycle = 3600 |
|
299 | #beaker.cache.auth_plugins.sa.pool_recycle = 3600 | |
298 | #beaker.cache.auth_plugins.sa.pool_size = 10 |
|
300 | #beaker.cache.auth_plugins.sa.pool_size = 10 | |
299 | #beaker.cache.auth_plugins.sa.max_overflow = 0 |
|
301 | #beaker.cache.auth_plugins.sa.max_overflow = 0 | |
300 |
|
302 | |||
301 | beaker.cache.repo_cache_long.type = memorylru_base |
|
303 | beaker.cache.repo_cache_long.type = memorylru_base | |
302 | beaker.cache.repo_cache_long.max_items = 4096 |
|
304 | beaker.cache.repo_cache_long.max_items = 4096 | |
303 | beaker.cache.repo_cache_long.expire = 2592000 |
|
305 | beaker.cache.repo_cache_long.expire = 2592000 | |
304 |
|
306 | |||
305 | # default is memorylru_base cache, configure only if required |
|
307 | # default is memorylru_base cache, configure only if required | |
306 | # using multi-node or multi-worker setup |
|
308 | # using multi-node or multi-worker setup | |
307 | #beaker.cache.repo_cache_long.type = ext:memcached |
|
309 | #beaker.cache.repo_cache_long.type = ext:memcached | |
308 | #beaker.cache.repo_cache_long.url = localhost:11211 |
|
310 | #beaker.cache.repo_cache_long.url = localhost:11211 | |
309 | #beaker.cache.repo_cache_long.expire = 1209600 |
|
311 | #beaker.cache.repo_cache_long.expire = 1209600 | |
310 | #beaker.cache.repo_cache_long.key_length = 256 |
|
312 | #beaker.cache.repo_cache_long.key_length = 256 | |
311 |
|
313 | |||
312 | #################################### |
|
314 | #################################### | |
313 | ### BEAKER SESSION #### |
|
315 | ### BEAKER SESSION #### | |
314 | #################################### |
|
316 | #################################### | |
315 |
|
317 | |||
316 | ## .session.type is type of storage options for the session, current allowed |
|
318 | ## .session.type is type of storage options for the session, current allowed | |
317 | ## types are file, ext:memcached, ext:database, and memory(default). |
|
319 | ## types are file, ext:memcached, ext:database, and memory(default). | |
318 | beaker.session.type = file |
|
320 | beaker.session.type = file | |
319 | beaker.session.data_dir = %(here)s/data/sessions/data |
|
321 | beaker.session.data_dir = %(here)s/data/sessions/data | |
320 |
|
322 | |||
321 | ## db based session, fast, and allows easy management over logged in users ## |
|
323 | ## db based session, fast, and allows easy management over logged in users ## | |
322 | #beaker.session.type = ext:database |
|
324 | #beaker.session.type = ext:database | |
323 | #beaker.session.table_name = db_session |
|
325 | #beaker.session.table_name = db_session | |
324 | #beaker.session.sa.url = postgresql://postgres:secret@localhost/rhodecode |
|
326 | #beaker.session.sa.url = postgresql://postgres:secret@localhost/rhodecode | |
325 | #beaker.session.sa.url = mysql://root:secret@127.0.0.1/rhodecode |
|
327 | #beaker.session.sa.url = mysql://root:secret@127.0.0.1/rhodecode | |
326 | #beaker.session.sa.pool_recycle = 3600 |
|
328 | #beaker.session.sa.pool_recycle = 3600 | |
327 | #beaker.session.sa.echo = false |
|
329 | #beaker.session.sa.echo = false | |
328 |
|
330 | |||
329 | beaker.session.key = rhodecode |
|
331 | beaker.session.key = rhodecode | |
330 | beaker.session.secret = develop-rc-uytcxaz |
|
332 | beaker.session.secret = develop-rc-uytcxaz | |
331 | beaker.session.lock_dir = %(here)s/data/sessions/lock |
|
333 | beaker.session.lock_dir = %(here)s/data/sessions/lock | |
332 |
|
334 | |||
333 | ## Secure encrypted cookie. Requires AES and AES python libraries |
|
335 | ## Secure encrypted cookie. Requires AES and AES python libraries | |
334 | ## you must disable beaker.session.secret to use this |
|
336 | ## you must disable beaker.session.secret to use this | |
335 | #beaker.session.encrypt_key = <key_for_encryption> |
|
337 | #beaker.session.encrypt_key = <key_for_encryption> | |
336 | #beaker.session.validate_key = <validation_key> |
|
338 | #beaker.session.validate_key = <validation_key> | |
337 |
|
339 | |||
338 | ## sets session as invalid(also logging out user) if it haven not been |
|
340 | ## sets session as invalid(also logging out user) if it haven not been | |
339 | ## accessed for given amount of time in seconds |
|
341 | ## accessed for given amount of time in seconds | |
340 | beaker.session.timeout = 2592000 |
|
342 | beaker.session.timeout = 2592000 | |
341 | beaker.session.httponly = true |
|
343 | beaker.session.httponly = true | |
342 | #beaker.session.cookie_path = /<your-prefix> |
|
344 | #beaker.session.cookie_path = /<your-prefix> | |
343 |
|
345 | |||
344 | ## uncomment for https secure cookie |
|
346 | ## uncomment for https secure cookie | |
345 | beaker.session.secure = false |
|
347 | beaker.session.secure = false | |
346 |
|
348 | |||
347 | ## auto save the session to not to use .save() |
|
349 | ## auto save the session to not to use .save() | |
348 | beaker.session.auto = false |
|
350 | beaker.session.auto = false | |
349 |
|
351 | |||
350 | ## default cookie expiration time in seconds, set to `true` to set expire |
|
352 | ## default cookie expiration time in seconds, set to `true` to set expire | |
351 | ## at browser close |
|
353 | ## at browser close | |
352 | #beaker.session.cookie_expires = 3600 |
|
354 | #beaker.session.cookie_expires = 3600 | |
353 |
|
355 | |||
354 | ################################### |
|
356 | ################################### | |
355 | ## SEARCH INDEXING CONFIGURATION ## |
|
357 | ## SEARCH INDEXING CONFIGURATION ## | |
356 | ################################### |
|
358 | ################################### | |
357 |
|
359 | |||
358 | search.module = rhodecode.lib.index.whoosh |
|
360 | search.module = rhodecode.lib.index.whoosh | |
359 | search.location = %(here)s/data/index |
|
361 | search.location = %(here)s/data/index | |
360 |
|
362 | |||
361 | ################################### |
|
363 | ################################### | |
362 | ## ERROR AND LOG HANDLING SYSTEM ## |
|
364 | ## ERROR AND LOG HANDLING SYSTEM ## | |
363 | ################################### |
|
365 | ################################### | |
364 |
|
366 | |||
365 | ## Appenlight is tailored to work with RhodeCode, see |
|
367 | ## Appenlight is tailored to work with RhodeCode, see | |
366 | ## http://appenlight.com for details how to obtain an account |
|
368 | ## http://appenlight.com for details how to obtain an account | |
367 |
|
369 | |||
368 | ## appenlight integration enabled |
|
370 | ## appenlight integration enabled | |
369 | appenlight = false |
|
371 | appenlight = false | |
370 |
|
372 | |||
371 | appenlight.server_url = https://api.appenlight.com |
|
373 | appenlight.server_url = https://api.appenlight.com | |
372 | appenlight.api_key = YOUR_API_KEY |
|
374 | appenlight.api_key = YOUR_API_KEY | |
373 | ;appenlight.transport_config = https://api.appenlight.com?threaded=1&timeout=5 |
|
375 | ;appenlight.transport_config = https://api.appenlight.com?threaded=1&timeout=5 | |
374 |
|
376 | |||
375 | # used for JS client |
|
377 | # used for JS client | |
376 | appenlight.api_public_key = YOUR_API_PUBLIC_KEY |
|
378 | appenlight.api_public_key = YOUR_API_PUBLIC_KEY | |
377 |
|
379 | |||
378 | ## TWEAK AMOUNT OF INFO SENT HERE |
|
380 | ## TWEAK AMOUNT OF INFO SENT HERE | |
379 |
|
381 | |||
380 | ## enables 404 error logging (default False) |
|
382 | ## enables 404 error logging (default False) | |
381 | appenlight.report_404 = false |
|
383 | appenlight.report_404 = false | |
382 |
|
384 | |||
383 | ## time in seconds after request is considered being slow (default 1) |
|
385 | ## time in seconds after request is considered being slow (default 1) | |
384 | appenlight.slow_request_time = 1 |
|
386 | appenlight.slow_request_time = 1 | |
385 |
|
387 | |||
386 | ## record slow requests in application |
|
388 | ## record slow requests in application | |
387 | ## (needs to be enabled for slow datastore recording and time tracking) |
|
389 | ## (needs to be enabled for slow datastore recording and time tracking) | |
388 | appenlight.slow_requests = true |
|
390 | appenlight.slow_requests = true | |
389 |
|
391 | |||
390 | ## enable hooking to application loggers |
|
392 | ## enable hooking to application loggers | |
391 | appenlight.logging = true |
|
393 | appenlight.logging = true | |
392 |
|
394 | |||
393 | ## minimum log level for log capture |
|
395 | ## minimum log level for log capture | |
394 | appenlight.logging.level = WARNING |
|
396 | appenlight.logging.level = WARNING | |
395 |
|
397 | |||
396 | ## send logs only from erroneous/slow requests |
|
398 | ## send logs only from erroneous/slow requests | |
397 | ## (saves API quota for intensive logging) |
|
399 | ## (saves API quota for intensive logging) | |
398 | appenlight.logging_on_error = false |
|
400 | appenlight.logging_on_error = false | |
399 |
|
401 | |||
400 | ## list of additonal keywords that should be grabbed from environ object |
|
402 | ## list of additonal keywords that should be grabbed from environ object | |
401 | ## can be string with comma separated list of words in lowercase |
|
403 | ## can be string with comma separated list of words in lowercase | |
402 | ## (by default client will always send following info: |
|
404 | ## (by default client will always send following info: | |
403 | ## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that |
|
405 | ## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that | |
404 | ## start with HTTP* this list be extended with additional keywords here |
|
406 | ## start with HTTP* this list be extended with additional keywords here | |
405 | appenlight.environ_keys_whitelist = |
|
407 | appenlight.environ_keys_whitelist = | |
406 |
|
408 | |||
407 | ## list of keywords that should be blanked from request object |
|
409 | ## list of keywords that should be blanked from request object | |
408 | ## can be string with comma separated list of words in lowercase |
|
410 | ## can be string with comma separated list of words in lowercase | |
409 | ## (by default client will always blank keys that contain following words |
|
411 | ## (by default client will always blank keys that contain following words | |
410 | ## 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf' |
|
412 | ## 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf' | |
411 | ## this list be extended with additional keywords set here |
|
413 | ## this list be extended with additional keywords set here | |
412 | appenlight.request_keys_blacklist = |
|
414 | appenlight.request_keys_blacklist = | |
413 |
|
415 | |||
414 | ## list of namespaces that should be ignores when gathering log entries |
|
416 | ## list of namespaces that should be ignores when gathering log entries | |
415 | ## can be string with comma separated list of namespaces |
|
417 | ## can be string with comma separated list of namespaces | |
416 | ## (by default the client ignores own entries: appenlight_client.client) |
|
418 | ## (by default the client ignores own entries: appenlight_client.client) | |
417 | appenlight.log_namespace_blacklist = |
|
419 | appenlight.log_namespace_blacklist = | |
418 |
|
420 | |||
419 |
|
421 | |||
420 | ################################################################################ |
|
422 | ################################################################################ | |
421 | ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ## |
|
423 | ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ## | |
422 | ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ## |
|
424 | ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ## | |
423 | ## execute malicious code after an exception is raised. ## |
|
425 | ## execute malicious code after an exception is raised. ## | |
424 | ################################################################################ |
|
426 | ################################################################################ | |
425 | #set debug = false |
|
427 | #set debug = false | |
426 |
|
428 | |||
427 |
|
429 | |||
428 | ############## |
|
430 | ############## | |
429 | ## STYLING ## |
|
431 | ## STYLING ## | |
430 | ############## |
|
432 | ############## | |
431 | debug_style = true |
|
433 | debug_style = true | |
432 |
|
434 | |||
433 | ######################################################### |
|
435 | ######################################################### | |
434 | ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ### |
|
436 | ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ### | |
435 | ######################################################### |
|
437 | ######################################################### | |
436 | sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db?timeout=30 |
|
438 | sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db?timeout=30 | |
437 | #sqlalchemy.db1.url = postgresql://postgres:qweqwe@localhost/rhodecode |
|
439 | #sqlalchemy.db1.url = postgresql://postgres:qweqwe@localhost/rhodecode | |
438 | #sqlalchemy.db1.url = mysql://root:qweqwe@localhost/rhodecode |
|
440 | #sqlalchemy.db1.url = mysql://root:qweqwe@localhost/rhodecode | |
439 |
|
441 | |||
440 | # see sqlalchemy docs for other advanced settings |
|
442 | # see sqlalchemy docs for other advanced settings | |
441 |
|
443 | |||
442 | ## print the sql statements to output |
|
444 | ## print the sql statements to output | |
443 | sqlalchemy.db1.echo = false |
|
445 | sqlalchemy.db1.echo = false | |
444 | ## recycle the connections after this ammount of seconds |
|
446 | ## recycle the connections after this ammount of seconds | |
445 | sqlalchemy.db1.pool_recycle = 3600 |
|
447 | sqlalchemy.db1.pool_recycle = 3600 | |
446 | sqlalchemy.db1.convert_unicode = true |
|
448 | sqlalchemy.db1.convert_unicode = true | |
447 |
|
449 | |||
448 | ## the number of connections to keep open inside the connection pool. |
|
450 | ## the number of connections to keep open inside the connection pool. | |
449 | ## 0 indicates no limit |
|
451 | ## 0 indicates no limit | |
450 | #sqlalchemy.db1.pool_size = 5 |
|
452 | #sqlalchemy.db1.pool_size = 5 | |
451 |
|
453 | |||
452 | ## the number of connections to allow in connection pool "overflow", that is |
|
454 | ## the number of connections to allow in connection pool "overflow", that is | |
453 | ## connections that can be opened above and beyond the pool_size setting, |
|
455 | ## connections that can be opened above and beyond the pool_size setting, | |
454 | ## which defaults to five. |
|
456 | ## which defaults to five. | |
455 | #sqlalchemy.db1.max_overflow = 10 |
|
457 | #sqlalchemy.db1.max_overflow = 10 | |
456 |
|
458 | |||
457 |
|
459 | |||
458 | ################## |
|
460 | ################## | |
459 | ### VCS CONFIG ### |
|
461 | ### VCS CONFIG ### | |
460 | ################## |
|
462 | ################## | |
461 | vcs.server.enable = true |
|
463 | vcs.server.enable = true | |
462 | vcs.server = localhost:9900 |
|
464 | vcs.server = localhost:9900 | |
463 | # Available protocols: pyro4, http |
|
465 | # Available protocols: pyro4, http | |
464 | vcs.server.protocol = pyro4 |
|
466 | vcs.server.protocol = pyro4 | |
465 |
|
467 | |||
466 | # available impl: |
|
468 | # available impl: | |
467 | # vcsserver.scm_app (EE only, for testing), |
|
469 | # vcsserver.scm_app (EE only, for testing), | |
468 | # rhodecode.lib.middleware.utils.scm_app_http |
|
470 | # rhodecode.lib.middleware.utils.scm_app_http | |
469 | # pyro4 |
|
471 | # pyro4 | |
470 | #vcs.scm_app_implementation = rhodecode.lib.middleware.utils.scm_app_http |
|
472 | #vcs.scm_app_implementation = rhodecode.lib.middleware.utils.scm_app_http | |
471 |
|
473 | |||
472 | vcs.server.log_level = debug |
|
474 | vcs.server.log_level = debug | |
473 | vcs.start_server = true |
|
475 | vcs.start_server = true | |
474 | vcs.backends = hg, git, svn |
|
476 | vcs.backends = hg, git, svn | |
475 | vcs.connection_timeout = 3600 |
|
477 | vcs.connection_timeout = 3600 | |
476 | ## Compatibility version when creating SVN repositories. Defaults to newest version when commented out. |
|
478 | ## Compatibility version when creating SVN repositories. Defaults to newest version when commented out. | |
477 | ## Available options are: pre-1.4-compatible, pre-1.5-compatible, pre-1.6-compatible, pre-1.8-compatible |
|
479 | ## Available options are: pre-1.4-compatible, pre-1.5-compatible, pre-1.6-compatible, pre-1.8-compatible | |
478 | #vcs.svn.compatible_version = pre-1.8-compatible |
|
480 | #vcs.svn.compatible_version = pre-1.8-compatible | |
479 |
|
481 | |||
480 | ################################ |
|
482 | ################################ | |
481 | ### LOGGING CONFIGURATION #### |
|
483 | ### LOGGING CONFIGURATION #### | |
482 | ################################ |
|
484 | ################################ | |
483 | [loggers] |
|
485 | [loggers] | |
484 | keys = root, routes, rhodecode, sqlalchemy, beaker, pyro4, templates, whoosh_indexer |
|
486 | keys = root, routes, rhodecode, sqlalchemy, beaker, pyro4, templates, whoosh_indexer | |
485 |
|
487 | |||
486 | [handlers] |
|
488 | [handlers] | |
487 | keys = console, console_sql |
|
489 | keys = console, console_sql | |
488 |
|
490 | |||
489 | [formatters] |
|
491 | [formatters] | |
490 | keys = generic, color_formatter, color_formatter_sql |
|
492 | keys = generic, color_formatter, color_formatter_sql | |
491 |
|
493 | |||
492 | ############# |
|
494 | ############# | |
493 | ## LOGGERS ## |
|
495 | ## LOGGERS ## | |
494 | ############# |
|
496 | ############# | |
495 | [logger_root] |
|
497 | [logger_root] | |
496 | level = NOTSET |
|
498 | level = NOTSET | |
497 | handlers = console |
|
499 | handlers = console | |
498 |
|
500 | |||
499 | [logger_routes] |
|
501 | [logger_routes] | |
500 | level = DEBUG |
|
502 | level = DEBUG | |
501 | handlers = |
|
503 | handlers = | |
502 | qualname = routes.middleware |
|
504 | qualname = routes.middleware | |
503 | ## "level = DEBUG" logs the route matched and routing variables. |
|
505 | ## "level = DEBUG" logs the route matched and routing variables. | |
504 | propagate = 1 |
|
506 | propagate = 1 | |
505 |
|
507 | |||
506 | [logger_beaker] |
|
508 | [logger_beaker] | |
507 | level = DEBUG |
|
509 | level = DEBUG | |
508 | handlers = |
|
510 | handlers = | |
509 | qualname = beaker.container |
|
511 | qualname = beaker.container | |
510 | propagate = 1 |
|
512 | propagate = 1 | |
511 |
|
513 | |||
512 | [logger_pyro4] |
|
514 | [logger_pyro4] | |
513 | level = DEBUG |
|
515 | level = DEBUG | |
514 | handlers = |
|
516 | handlers = | |
515 | qualname = Pyro4 |
|
517 | qualname = Pyro4 | |
516 | propagate = 1 |
|
518 | propagate = 1 | |
517 |
|
519 | |||
518 | [logger_templates] |
|
520 | [logger_templates] | |
519 | level = INFO |
|
521 | level = INFO | |
520 | handlers = |
|
522 | handlers = | |
521 | qualname = pylons.templating |
|
523 | qualname = pylons.templating | |
522 | propagate = 1 |
|
524 | propagate = 1 | |
523 |
|
525 | |||
524 | [logger_rhodecode] |
|
526 | [logger_rhodecode] | |
525 | level = DEBUG |
|
527 | level = DEBUG | |
526 | handlers = |
|
528 | handlers = | |
527 | qualname = rhodecode |
|
529 | qualname = rhodecode | |
528 | propagate = 1 |
|
530 | propagate = 1 | |
529 |
|
531 | |||
530 | [logger_sqlalchemy] |
|
532 | [logger_sqlalchemy] | |
531 | level = INFO |
|
533 | level = INFO | |
532 | handlers = console_sql |
|
534 | handlers = console_sql | |
533 | qualname = sqlalchemy.engine |
|
535 | qualname = sqlalchemy.engine | |
534 | propagate = 0 |
|
536 | propagate = 0 | |
535 |
|
537 | |||
536 | [logger_whoosh_indexer] |
|
538 | [logger_whoosh_indexer] | |
537 | level = DEBUG |
|
539 | level = DEBUG | |
538 | handlers = |
|
540 | handlers = | |
539 | qualname = whoosh_indexer |
|
541 | qualname = whoosh_indexer | |
540 | propagate = 1 |
|
542 | propagate = 1 | |
541 |
|
543 | |||
542 | ############## |
|
544 | ############## | |
543 | ## HANDLERS ## |
|
545 | ## HANDLERS ## | |
544 | ############## |
|
546 | ############## | |
545 |
|
547 | |||
546 | [handler_console] |
|
548 | [handler_console] | |
547 | class = StreamHandler |
|
549 | class = StreamHandler | |
548 | args = (sys.stderr,) |
|
550 | args = (sys.stderr,) | |
549 | level = DEBUG |
|
551 | level = DEBUG | |
550 | formatter = color_formatter |
|
552 | formatter = color_formatter | |
551 |
|
553 | |||
552 | [handler_console_sql] |
|
554 | [handler_console_sql] | |
553 | class = StreamHandler |
|
555 | class = StreamHandler | |
554 | args = (sys.stderr,) |
|
556 | args = (sys.stderr,) | |
555 | level = DEBUG |
|
557 | level = DEBUG | |
556 | formatter = color_formatter_sql |
|
558 | formatter = color_formatter_sql | |
557 |
|
559 | |||
558 | ################ |
|
560 | ################ | |
559 | ## FORMATTERS ## |
|
561 | ## FORMATTERS ## | |
560 | ################ |
|
562 | ################ | |
561 |
|
563 | |||
562 | [formatter_generic] |
|
564 | [formatter_generic] | |
563 | class = rhodecode.lib.logging_formatter.Pyro4AwareFormatter |
|
565 | class = rhodecode.lib.logging_formatter.Pyro4AwareFormatter | |
564 | format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s |
|
566 | format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s | |
565 | datefmt = %Y-%m-%d %H:%M:%S |
|
567 | datefmt = %Y-%m-%d %H:%M:%S | |
566 |
|
568 | |||
567 | [formatter_color_formatter] |
|
569 | [formatter_color_formatter] | |
568 | class = rhodecode.lib.logging_formatter.ColorFormatter |
|
570 | class = rhodecode.lib.logging_formatter.ColorFormatter | |
569 | format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s |
|
571 | format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s | |
570 | datefmt = %Y-%m-%d %H:%M:%S |
|
572 | datefmt = %Y-%m-%d %H:%M:%S | |
571 |
|
573 | |||
572 | [formatter_color_formatter_sql] |
|
574 | [formatter_color_formatter_sql] | |
573 | class = rhodecode.lib.logging_formatter.ColorFormatterSql |
|
575 | class = rhodecode.lib.logging_formatter.ColorFormatterSql | |
574 | format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s |
|
576 | format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s | |
575 | datefmt = %Y-%m-%d %H:%M:%S |
|
577 | datefmt = %Y-%m-%d %H:%M:%S |
@@ -1,541 +1,551 b'' | |||||
1 | ################################################################################ |
|
1 | ################################################################################ | |
2 | ################################################################################ |
|
2 | ################################################################################ | |
3 | # RhodeCode Enterprise - configuration file # |
|
3 | # RhodeCode Enterprise - configuration file # | |
4 | # Built-in functions and variables # |
|
4 | # Built-in functions and variables # | |
5 | # The %(here)s variable will be replaced with the parent directory of this file# |
|
5 | # The %(here)s variable will be replaced with the parent directory of this file# | |
6 | # # |
|
6 | # # | |
7 | ################################################################################ |
|
7 | ################################################################################ | |
8 |
|
8 | |||
9 | [DEFAULT] |
|
9 | [DEFAULT] | |
10 | debug = true |
|
10 | debug = true | |
11 | pdebug = false |
|
11 | pdebug = false | |
12 | ################################################################################ |
|
12 | ################################################################################ | |
13 | ## Uncomment and replace with the email address which should receive ## |
|
13 | ## Uncomment and replace with the email address which should receive ## | |
14 | ## any error reports after an application crash ## |
|
14 | ## any error reports after an application crash ## | |
15 | ## Additionally these settings will be used by the RhodeCode mailing system ## |
|
15 | ## Additionally these settings will be used by the RhodeCode mailing system ## | |
16 | ################################################################################ |
|
16 | ################################################################################ | |
17 | #email_to = admin@localhost |
|
17 | #email_to = admin@localhost | |
18 | #error_email_from = paste_error@localhost |
|
18 | #error_email_from = paste_error@localhost | |
19 | #app_email_from = rhodecode-noreply@localhost |
|
19 | #app_email_from = rhodecode-noreply@localhost | |
20 | #error_message = |
|
20 | #error_message = | |
21 | #email_prefix = [RhodeCode] |
|
21 | #email_prefix = [RhodeCode] | |
22 |
|
22 | |||
23 | #smtp_server = mail.server.com |
|
23 | #smtp_server = mail.server.com | |
24 | #smtp_username = |
|
24 | #smtp_username = | |
25 | #smtp_password = |
|
25 | #smtp_password = | |
26 | #smtp_port = |
|
26 | #smtp_port = | |
27 | #smtp_use_tls = false |
|
27 | #smtp_use_tls = false | |
28 | #smtp_use_ssl = true |
|
28 | #smtp_use_ssl = true | |
29 | ## Specify available auth parameters here (e.g. LOGIN PLAIN CRAM-MD5, etc.) |
|
29 | ## Specify available auth parameters here (e.g. LOGIN PLAIN CRAM-MD5, etc.) | |
30 | #smtp_auth = |
|
30 | #smtp_auth = | |
31 |
|
31 | |||
32 | [server:main] |
|
32 | [server:main] | |
33 | ## COMMON ## |
|
33 | ## COMMON ## | |
34 | host = 127.0.0.1 |
|
34 | host = 127.0.0.1 | |
35 | port = 5000 |
|
35 | port = 5000 | |
36 |
|
36 | |||
37 | ########################## |
|
37 | ########################## | |
38 | ## WAITRESS WSGI SERVER ## |
|
38 | ## WAITRESS WSGI SERVER ## | |
39 | ########################## |
|
39 | ########################## | |
40 | use = egg:waitress#main |
|
40 | use = egg:waitress#main | |
41 | ## number of worker threads |
|
41 | ## number of worker threads | |
42 | threads = 5 |
|
42 | threads = 5 | |
43 | ## MAX BODY SIZE 100GB |
|
43 | ## MAX BODY SIZE 100GB | |
44 | max_request_body_size = 107374182400 |
|
44 | max_request_body_size = 107374182400 | |
45 | ## Use poll instead of select, fixes file descriptors limits problems. |
|
45 | ## Use poll instead of select, fixes file descriptors limits problems. | |
46 | ## May not work on old windows systems. |
|
46 | ## May not work on old windows systems. | |
47 | asyncore_use_poll = true |
|
47 | asyncore_use_poll = true | |
48 |
|
48 | |||
49 |
|
49 | |||
50 | ########################## |
|
50 | ########################## | |
51 | ## GUNICORN WSGI SERVER ## |
|
51 | ## GUNICORN WSGI SERVER ## | |
52 | ########################## |
|
52 | ########################## | |
53 | ## run with gunicorn --log-config <inifile.ini> --paste <inifile.ini> |
|
53 | ## run with gunicorn --log-config <inifile.ini> --paste <inifile.ini> | |
54 | #use = egg:gunicorn#main |
|
54 | #use = egg:gunicorn#main | |
55 | ## Sets the number of process workers. You must set `instance_id = *` |
|
55 | ## Sets the number of process workers. You must set `instance_id = *` | |
56 | ## when this option is set to more than one worker, recommended |
|
56 | ## when this option is set to more than one worker, recommended | |
57 | ## value is (2 * NUMBER_OF_CPUS + 1), eg 2CPU = 5 workers |
|
57 | ## value is (2 * NUMBER_OF_CPUS + 1), eg 2CPU = 5 workers | |
58 | ## The `instance_id = *` must be set in the [app:main] section below |
|
58 | ## The `instance_id = *` must be set in the [app:main] section below | |
59 | #workers = 1 |
|
59 | #workers = 1 | |
60 | ## number of threads for each of the worker, must be set to 1 for gevent |
|
60 | ## number of threads for each of the worker, must be set to 1 for gevent | |
61 | ## generally recommened to be at 1 |
|
61 | ## generally recommened to be at 1 | |
62 | #threads = 1 |
|
62 | #threads = 1 | |
63 | ## process name |
|
63 | ## process name | |
64 | #proc_name = rhodecode |
|
64 | #proc_name = rhodecode | |
65 | ## type of worker class, one of sync, gevent |
|
65 | ## type of worker class, one of sync, gevent | |
66 | ## recommended for bigger setup is using of of other than sync one |
|
66 | ## recommended for bigger setup is using of of other than sync one | |
67 | #worker_class = sync |
|
67 | #worker_class = sync | |
|
68 | ## The maximum number of simultaneous clients. Valid only for Gevent | |||
|
69 | #worker_connections = 10 | |||
68 | ## max number of requests that worker will handle before being gracefully |
|
70 | ## max number of requests that worker will handle before being gracefully | |
69 | ## restarted, could prevent memory leaks |
|
71 | ## restarted, could prevent memory leaks | |
70 | #max_requests = 1000 |
|
72 | #max_requests = 1000 | |
71 | #max_requests_jitter = 30 |
|
73 | #max_requests_jitter = 30 | |
72 | ## ammount of time a worker can spend with handling a request before it |
|
74 | ## ammount of time a worker can spend with handling a request before it | |
73 | ## gets killed and restarted. Set to 6hrs |
|
75 | ## gets killed and restarted. Set to 6hrs | |
74 | #timeout = 21600 |
|
76 | #timeout = 21600 | |
75 |
|
77 | |||
76 |
|
78 | |||
77 | ## prefix middleware for RhodeCode, disables force_https flag. |
|
79 | ## prefix middleware for RhodeCode, disables force_https flag. | |
78 | ## allows to set RhodeCode under a prefix in server. |
|
80 | ## allows to set RhodeCode under a prefix in server. | |
79 | ## eg https://server.com/<prefix>. Enable `filter-with =` option below as well. |
|
81 | ## eg https://server.com/<prefix>. Enable `filter-with =` option below as well. | |
80 | #[filter:proxy-prefix] |
|
82 | #[filter:proxy-prefix] | |
81 | #use = egg:PasteDeploy#prefix |
|
83 | #use = egg:PasteDeploy#prefix | |
82 | #prefix = /<your-prefix> |
|
84 | #prefix = /<your-prefix> | |
83 |
|
85 | |||
84 | [app:main] |
|
86 | [app:main] | |
85 | use = egg:rhodecode-enterprise-ce |
|
87 | use = egg:rhodecode-enterprise-ce | |
86 | ## enable proxy prefix middleware, defined below |
|
88 | ## enable proxy prefix middleware, defined below | |
87 | #filter-with = proxy-prefix |
|
89 | #filter-with = proxy-prefix | |
88 |
|
90 | |||
89 | full_stack = true |
|
91 | full_stack = true | |
90 |
|
92 | |||
91 | ## Serve static files via RhodeCode, disable to serve them via HTTP server |
|
93 | ## Serve static files via RhodeCode, disable to serve them via HTTP server | |
92 | static_files = true |
|
94 | static_files = true | |
93 |
|
95 | |||
94 | ## Optional Languages |
|
96 | ## Optional Languages | |
95 | ## en(default), be, de, es, fr, it, ja, pl, pt, ru, zh |
|
97 | ## en(default), be, de, es, fr, it, ja, pl, pt, ru, zh | |
96 | lang = en |
|
98 | lang = en | |
97 |
|
99 | |||
98 | ## perform a full repository scan on each server start, this should be |
|
100 | ## perform a full repository scan on each server start, this should be | |
99 | ## set to false after first startup, to allow faster server restarts. |
|
101 | ## set to false after first startup, to allow faster server restarts. | |
100 | startup.import_repos = false |
|
102 | startup.import_repos = false | |
101 |
|
103 | |||
102 | ## Uncomment and set this path to use archive download cache. |
|
104 | ## Uncomment and set this path to use archive download cache. | |
103 | ## Once enabled, generated archives will be cached at this location |
|
105 | ## Once enabled, generated archives will be cached at this location | |
104 | ## and served from the cache during subsequent requests for the same archive of |
|
106 | ## and served from the cache during subsequent requests for the same archive of | |
105 | ## the repository. |
|
107 | ## the repository. | |
106 | #archive_cache_dir = /tmp/tarballcache |
|
108 | #archive_cache_dir = /tmp/tarballcache | |
107 |
|
109 | |||
108 | ## change this to unique ID for security |
|
110 | ## change this to unique ID for security | |
109 | app_instance_uuid = rc-production |
|
111 | app_instance_uuid = rc-production | |
110 |
|
112 | |||
111 | ## cut off limit for large diffs (size in bytes) |
|
113 | ## cut off limit for large diffs (size in bytes) | |
112 | cut_off_limit_diff = 1024000 |
|
114 | cut_off_limit_diff = 1024000 | |
113 | cut_off_limit_file = 256000 |
|
115 | cut_off_limit_file = 256000 | |
114 |
|
116 | |||
115 | ## use cache version of scm repo everywhere |
|
117 | ## use cache version of scm repo everywhere | |
116 | vcs_full_cache = true |
|
118 | vcs_full_cache = true | |
117 |
|
119 | |||
118 | ## force https in RhodeCode, fixes https redirects, assumes it's always https |
|
120 | ## force https in RhodeCode, fixes https redirects, assumes it's always https | |
119 | ## Normally this is controlled by proper http flags sent from http server |
|
121 | ## Normally this is controlled by proper http flags sent from http server | |
120 | force_https = false |
|
122 | force_https = false | |
121 |
|
123 | |||
122 | ## use Strict-Transport-Security headers |
|
124 | ## use Strict-Transport-Security headers | |
123 | use_htsts = false |
|
125 | use_htsts = false | |
124 |
|
126 | |||
125 | ## number of commits stats will parse on each iteration |
|
127 | ## number of commits stats will parse on each iteration | |
126 | commit_parse_limit = 25 |
|
128 | commit_parse_limit = 25 | |
127 |
|
129 | |||
128 | ## git rev filter option, --all is the default filter, if you need to |
|
130 | ## git rev filter option, --all is the default filter, if you need to | |
129 | ## hide all refs in changelog switch this to --branches --tags |
|
131 | ## hide all refs in changelog switch this to --branches --tags | |
130 | git_rev_filter = --branches --tags |
|
132 | git_rev_filter = --branches --tags | |
131 |
|
133 | |||
132 | # Set to true if your repos are exposed using the dumb protocol |
|
134 | # Set to true if your repos are exposed using the dumb protocol | |
133 | git_update_server_info = false |
|
135 | git_update_server_info = false | |
134 |
|
136 | |||
135 | ## RSS/ATOM feed options |
|
137 | ## RSS/ATOM feed options | |
136 | rss_cut_off_limit = 256000 |
|
138 | rss_cut_off_limit = 256000 | |
137 | rss_items_per_page = 10 |
|
139 | rss_items_per_page = 10 | |
138 | rss_include_diff = false |
|
140 | rss_include_diff = false | |
139 |
|
141 | |||
140 | ## gist URL alias, used to create nicer urls for gist. This should be an |
|
142 | ## gist URL alias, used to create nicer urls for gist. This should be an | |
141 | ## url that does rewrites to _admin/gists/<gistid>. |
|
143 | ## url that does rewrites to _admin/gists/<gistid>. | |
142 | ## example: http://gist.rhodecode.org/{gistid}. Empty means use the internal |
|
144 | ## example: http://gist.rhodecode.org/{gistid}. Empty means use the internal | |
143 | ## RhodeCode url, ie. http[s]://rhodecode.server/_admin/gists/<gistid> |
|
145 | ## RhodeCode url, ie. http[s]://rhodecode.server/_admin/gists/<gistid> | |
144 | gist_alias_url = |
|
146 | gist_alias_url = | |
145 |
|
147 | |||
146 | ## List of controllers (using glob pattern syntax) that AUTH TOKENS could be |
|
148 | ## List of controllers (using glob pattern syntax) that AUTH TOKENS could be | |
147 | ## used for access. |
|
149 | ## used for access. | |
148 | ## Adding ?auth_token = <token> to the url authenticates this request as if it |
|
150 | ## Adding ?auth_token = <token> to the url authenticates this request as if it | |
149 | ## came from the the logged in user who own this authentication token. |
|
151 | ## came from the the logged in user who own this authentication token. | |
150 | ## |
|
152 | ## | |
151 | ## Syntax is <ControllerClass>:<function_pattern>. |
|
153 | ## Syntax is <ControllerClass>:<function_pattern>. | |
152 | ## To enable access to raw_files put `FilesController:raw`. |
|
154 | ## To enable access to raw_files put `FilesController:raw`. | |
153 | ## To enable access to patches add `ChangesetController:changeset_patch`. |
|
155 | ## To enable access to patches add `ChangesetController:changeset_patch`. | |
154 | ## The list should be "," separated and on a single line. |
|
156 | ## The list should be "," separated and on a single line. | |
155 | ## |
|
157 | ## | |
156 | ## Recommended controllers to enable: |
|
158 | ## Recommended controllers to enable: | |
157 | # ChangesetController:changeset_patch, |
|
159 | # ChangesetController:changeset_patch, | |
158 | # ChangesetController:changeset_raw, |
|
160 | # ChangesetController:changeset_raw, | |
159 | # FilesController:raw, |
|
161 | # FilesController:raw, | |
160 | # FilesController:archivefile, |
|
162 | # FilesController:archivefile, | |
161 | # GistsController:*, |
|
163 | # GistsController:*, | |
162 | api_access_controllers_whitelist = |
|
164 | api_access_controllers_whitelist = | |
163 |
|
165 | |||
164 | ## default encoding used to convert from and to unicode |
|
166 | ## default encoding used to convert from and to unicode | |
165 | ## can be also a comma separated list of encoding in case of mixed encodings |
|
167 | ## can be also a comma separated list of encoding in case of mixed encodings | |
166 | default_encoding = UTF-8 |
|
168 | default_encoding = UTF-8 | |
167 |
|
169 | |||
168 | ## instance-id prefix |
|
170 | ## instance-id prefix | |
169 | ## a prefix key for this instance used for cache invalidation when running |
|
171 | ## a prefix key for this instance used for cache invalidation when running | |
170 | ## multiple instances of rhodecode, make sure it's globally unique for |
|
172 | ## multiple instances of rhodecode, make sure it's globally unique for | |
171 | ## all running rhodecode instances. Leave empty if you don't use it |
|
173 | ## all running rhodecode instances. Leave empty if you don't use it | |
172 | instance_id = |
|
174 | instance_id = | |
173 |
|
175 | |||
174 | ## alternative return HTTP header for failed authentication. Default HTTP |
|
176 | ## alternative return HTTP header for failed authentication. Default HTTP | |
175 | ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with |
|
177 | ## response is 401 HTTPUnauthorized. Currently HG clients have troubles with | |
176 | ## handling that causing a series of failed authentication calls. |
|
178 | ## handling that causing a series of failed authentication calls. | |
177 | ## Set this variable to 403 to return HTTPForbidden, or any other HTTP code |
|
179 | ## Set this variable to 403 to return HTTPForbidden, or any other HTTP code | |
178 | ## This will be served instead of default 401 on bad authnetication |
|
180 | ## This will be served instead of default 401 on bad authnetication | |
179 | auth_ret_code = |
|
181 | auth_ret_code = | |
180 |
|
182 | |||
181 | ## use special detection method when serving auth_ret_code, instead of serving |
|
183 | ## use special detection method when serving auth_ret_code, instead of serving | |
182 | ## ret_code directly, use 401 initially (Which triggers credentials prompt) |
|
184 | ## ret_code directly, use 401 initially (Which triggers credentials prompt) | |
183 | ## and then serve auth_ret_code to clients |
|
185 | ## and then serve auth_ret_code to clients | |
184 | auth_ret_code_detection = false |
|
186 | auth_ret_code_detection = false | |
185 |
|
187 | |||
186 | ## locking return code. When repository is locked return this HTTP code. 2XX |
|
188 | ## locking return code. When repository is locked return this HTTP code. 2XX | |
187 | ## codes don't break the transactions while 4XX codes do |
|
189 | ## codes don't break the transactions while 4XX codes do | |
188 | lock_ret_code = 423 |
|
190 | lock_ret_code = 423 | |
189 |
|
191 | |||
190 | ## allows to change the repository location in settings page |
|
192 | ## allows to change the repository location in settings page | |
191 | allow_repo_location_change = true |
|
193 | allow_repo_location_change = true | |
192 |
|
194 | |||
193 | ## allows to setup custom hooks in settings page |
|
195 | ## allows to setup custom hooks in settings page | |
194 | allow_custom_hooks_settings = true |
|
196 | allow_custom_hooks_settings = true | |
195 |
|
197 | |||
196 | ## generated license token, goto license page in RhodeCode settings to obtain |
|
198 | ## generated license token, goto license page in RhodeCode settings to obtain | |
197 | ## new token |
|
199 | ## new token | |
198 | license_token = |
|
200 | license_token = | |
199 |
|
201 | |||
200 | ## supervisor connection uri, for managing supervisor and logs. |
|
202 | ## supervisor connection uri, for managing supervisor and logs. | |
201 | supervisor.uri = |
|
203 | supervisor.uri = | |
202 | ## supervisord group name/id we only want this RC instance to handle |
|
204 | ## supervisord group name/id we only want this RC instance to handle | |
203 | supervisor.group_id = prod |
|
205 | supervisor.group_id = prod | |
204 |
|
206 | |||
205 | ## Display extended labs settings |
|
207 | ## Display extended labs settings | |
206 | labs_settings_active = true |
|
208 | labs_settings_active = true | |
207 |
|
209 | |||
208 | #################################### |
|
210 | #################################### | |
209 | ### CELERY CONFIG #### |
|
211 | ### CELERY CONFIG #### | |
210 | #################################### |
|
212 | #################################### | |
211 | use_celery = false |
|
213 | use_celery = false | |
212 | broker.host = localhost |
|
214 | broker.host = localhost | |
213 | broker.vhost = rabbitmqhost |
|
215 | broker.vhost = rabbitmqhost | |
214 | broker.port = 5672 |
|
216 | broker.port = 5672 | |
215 | broker.user = rabbitmq |
|
217 | broker.user = rabbitmq | |
216 | broker.password = qweqwe |
|
218 | broker.password = qweqwe | |
217 |
|
219 | |||
218 | celery.imports = rhodecode.lib.celerylib.tasks |
|
220 | celery.imports = rhodecode.lib.celerylib.tasks | |
219 |
|
221 | |||
220 | celery.result.backend = amqp |
|
222 | celery.result.backend = amqp | |
221 | celery.result.dburi = amqp:// |
|
223 | celery.result.dburi = amqp:// | |
222 | celery.result.serialier = json |
|
224 | celery.result.serialier = json | |
223 |
|
225 | |||
224 | #celery.send.task.error.emails = true |
|
226 | #celery.send.task.error.emails = true | |
225 | #celery.amqp.task.result.expires = 18000 |
|
227 | #celery.amqp.task.result.expires = 18000 | |
226 |
|
228 | |||
227 | celeryd.concurrency = 2 |
|
229 | celeryd.concurrency = 2 | |
228 | #celeryd.log.file = celeryd.log |
|
230 | #celeryd.log.file = celeryd.log | |
229 | celeryd.log.level = debug |
|
231 | celeryd.log.level = debug | |
230 | celeryd.max.tasks.per.child = 1 |
|
232 | celeryd.max.tasks.per.child = 1 | |
231 |
|
233 | |||
232 | ## tasks will never be sent to the queue, but executed locally instead. |
|
234 | ## tasks will never be sent to the queue, but executed locally instead. | |
233 | celery.always.eager = false |
|
235 | celery.always.eager = false | |
234 |
|
236 | |||
235 | #################################### |
|
237 | #################################### | |
236 | ### BEAKER CACHE #### |
|
238 | ### BEAKER CACHE #### | |
237 | #################################### |
|
239 | #################################### | |
238 | # default cache dir for templates. Putting this into a ramdisk |
|
240 | # default cache dir for templates. Putting this into a ramdisk | |
239 | ## can boost performance, eg. %(here)s/data_ramdisk |
|
241 | ## can boost performance, eg. %(here)s/data_ramdisk | |
240 | cache_dir = %(here)s/data |
|
242 | cache_dir = %(here)s/data | |
241 |
|
243 | |||
242 | ## locking and default file storage for Beaker. Putting this into a ramdisk |
|
244 | ## locking and default file storage for Beaker. Putting this into a ramdisk | |
243 | ## can boost performance, eg. %(here)s/data_ramdisk/cache/beaker_data |
|
245 | ## can boost performance, eg. %(here)s/data_ramdisk/cache/beaker_data | |
244 | beaker.cache.data_dir = %(here)s/data/cache/beaker_data |
|
246 | beaker.cache.data_dir = %(here)s/data/cache/beaker_data | |
245 | beaker.cache.lock_dir = %(here)s/data/cache/beaker_lock |
|
247 | beaker.cache.lock_dir = %(here)s/data/cache/beaker_lock | |
246 |
|
248 | |||
247 | beaker.cache.regions = super_short_term, short_term, long_term, sql_cache_short, auth_plugins, repo_cache_long |
|
249 | beaker.cache.regions = super_short_term, short_term, long_term, sql_cache_short, auth_plugins, repo_cache_long | |
248 |
|
250 | |||
249 | beaker.cache.super_short_term.type = memory |
|
251 | beaker.cache.super_short_term.type = memory | |
250 | beaker.cache.super_short_term.expire = 10 |
|
252 | beaker.cache.super_short_term.expire = 10 | |
251 | beaker.cache.super_short_term.key_length = 256 |
|
253 | beaker.cache.super_short_term.key_length = 256 | |
252 |
|
254 | |||
253 | beaker.cache.short_term.type = memory |
|
255 | beaker.cache.short_term.type = memory | |
254 | beaker.cache.short_term.expire = 60 |
|
256 | beaker.cache.short_term.expire = 60 | |
255 | beaker.cache.short_term.key_length = 256 |
|
257 | beaker.cache.short_term.key_length = 256 | |
256 |
|
258 | |||
257 | beaker.cache.long_term.type = memory |
|
259 | beaker.cache.long_term.type = memory | |
258 | beaker.cache.long_term.expire = 36000 |
|
260 | beaker.cache.long_term.expire = 36000 | |
259 | beaker.cache.long_term.key_length = 256 |
|
261 | beaker.cache.long_term.key_length = 256 | |
260 |
|
262 | |||
261 | beaker.cache.sql_cache_short.type = memory |
|
263 | beaker.cache.sql_cache_short.type = memory | |
262 | beaker.cache.sql_cache_short.expire = 10 |
|
264 | beaker.cache.sql_cache_short.expire = 10 | |
263 | beaker.cache.sql_cache_short.key_length = 256 |
|
265 | beaker.cache.sql_cache_short.key_length = 256 | |
264 |
|
266 | |||
265 | # default is memory cache, configure only if required |
|
267 | # default is memory cache, configure only if required | |
266 | # using multi-node or multi-worker setup |
|
268 | # using multi-node or multi-worker setup | |
267 | #beaker.cache.auth_plugins.type = ext:database |
|
269 | #beaker.cache.auth_plugins.type = ext:database | |
268 | #beaker.cache.auth_plugins.lock_dir = %(here)s/data/cache/auth_plugin_lock |
|
270 | #beaker.cache.auth_plugins.lock_dir = %(here)s/data/cache/auth_plugin_lock | |
269 | #beaker.cache.auth_plugins.url = postgresql://postgres:secret@localhost/rhodecode |
|
271 | #beaker.cache.auth_plugins.url = postgresql://postgres:secret@localhost/rhodecode | |
270 | #beaker.cache.auth_plugins.url = mysql://root:secret@127.0.0.1/rhodecode |
|
272 | #beaker.cache.auth_plugins.url = mysql://root:secret@127.0.0.1/rhodecode | |
271 | #beaker.cache.auth_plugins.sa.pool_recycle = 3600 |
|
273 | #beaker.cache.auth_plugins.sa.pool_recycle = 3600 | |
272 | #beaker.cache.auth_plugins.sa.pool_size = 10 |
|
274 | #beaker.cache.auth_plugins.sa.pool_size = 10 | |
273 | #beaker.cache.auth_plugins.sa.max_overflow = 0 |
|
275 | #beaker.cache.auth_plugins.sa.max_overflow = 0 | |
274 |
|
276 | |||
275 | beaker.cache.repo_cache_long.type = memorylru_base |
|
277 | beaker.cache.repo_cache_long.type = memorylru_base | |
276 | beaker.cache.repo_cache_long.max_items = 4096 |
|
278 | beaker.cache.repo_cache_long.max_items = 4096 | |
277 | beaker.cache.repo_cache_long.expire = 2592000 |
|
279 | beaker.cache.repo_cache_long.expire = 2592000 | |
278 |
|
280 | |||
279 | # default is memorylru_base cache, configure only if required |
|
281 | # default is memorylru_base cache, configure only if required | |
280 | # using multi-node or multi-worker setup |
|
282 | # using multi-node or multi-worker setup | |
281 | #beaker.cache.repo_cache_long.type = ext:memcached |
|
283 | #beaker.cache.repo_cache_long.type = ext:memcached | |
282 | #beaker.cache.repo_cache_long.url = localhost:11211 |
|
284 | #beaker.cache.repo_cache_long.url = localhost:11211 | |
283 | #beaker.cache.repo_cache_long.expire = 1209600 |
|
285 | #beaker.cache.repo_cache_long.expire = 1209600 | |
284 | #beaker.cache.repo_cache_long.key_length = 256 |
|
286 | #beaker.cache.repo_cache_long.key_length = 256 | |
285 |
|
287 | |||
286 | #################################### |
|
288 | #################################### | |
287 | ### BEAKER SESSION #### |
|
289 | ### BEAKER SESSION #### | |
288 | #################################### |
|
290 | #################################### | |
289 |
|
291 | |||
290 | ## .session.type is type of storage options for the session, current allowed |
|
292 | ## .session.type is type of storage options for the session, current allowed | |
291 |
## types are file |
|
293 | ## types are file, ext:memcached, ext:database, and memory(default). | |
292 |
|
|
294 | beaker.session.type = file | |
|
295 | beaker.session.data_dir = %(here)s/data/sessions/data | |||
293 |
|
296 | |||
294 | ## db based session, fast, and allows easy management over logged in users ## |
|
297 | ## db based session, fast, and allows easy management over logged in users ## | |
295 | #beaker.session.type = ext:database |
|
298 | #beaker.session.type = ext:database | |
296 | #beaker.session.lock_dir = %(here)s/data/cache/session_db_lock |
|
|||
297 | #beaker.session.table_name = db_session |
|
299 | #beaker.session.table_name = db_session | |
298 | #beaker.session.sa.url = postgresql://postgres:secret@localhost/rhodecode |
|
300 | #beaker.session.sa.url = postgresql://postgres:secret@localhost/rhodecode | |
299 | #beaker.session.sa.url = mysql://root:secret@127.0.0.1/rhodecode |
|
301 | #beaker.session.sa.url = mysql://root:secret@127.0.0.1/rhodecode | |
300 | #beaker.session.sa.pool_recycle = 3600 |
|
302 | #beaker.session.sa.pool_recycle = 3600 | |
301 | #beaker.session.sa.echo = false |
|
303 | #beaker.session.sa.echo = false | |
302 |
|
304 | |||
303 | beaker.session.key = rhodecode |
|
305 | beaker.session.key = rhodecode | |
304 | beaker.session.secret = production-rc-uytcxaz |
|
306 | beaker.session.secret = production-rc-uytcxaz | |
|
307 | #beaker.session.lock_dir = %(here)s/data/sessions/lock | |||
305 |
|
308 | |||
306 | ## Secure encrypted cookie. Requires AES and AES python libraries |
|
309 | ## Secure encrypted cookie. Requires AES and AES python libraries | |
307 | ## you must disable beaker.session.secret to use this |
|
310 | ## you must disable beaker.session.secret to use this | |
308 | #beaker.session.encrypt_key = <key_for_encryption> |
|
311 | #beaker.session.encrypt_key = <key_for_encryption> | |
309 | #beaker.session.validate_key = <validation_key> |
|
312 | #beaker.session.validate_key = <validation_key> | |
310 |
|
313 | |||
311 | ## sets session as invalid(also logging out user) if it haven not been |
|
314 | ## sets session as invalid(also logging out user) if it haven not been | |
312 | ## accessed for given amount of time in seconds |
|
315 | ## accessed for given amount of time in seconds | |
313 | beaker.session.timeout = 2592000 |
|
316 | beaker.session.timeout = 2592000 | |
314 | beaker.session.httponly = true |
|
317 | beaker.session.httponly = true | |
315 | #beaker.session.cookie_path = /<your-prefix> |
|
318 | #beaker.session.cookie_path = /<your-prefix> | |
316 |
|
319 | |||
317 | ## uncomment for https secure cookie |
|
320 | ## uncomment for https secure cookie | |
318 | beaker.session.secure = false |
|
321 | beaker.session.secure = false | |
319 |
|
322 | |||
320 | ## auto save the session to not to use .save() |
|
323 | ## auto save the session to not to use .save() | |
321 | beaker.session.auto = false |
|
324 | beaker.session.auto = false | |
322 |
|
325 | |||
323 | ## default cookie expiration time in seconds, set to `true` to set expire |
|
326 | ## default cookie expiration time in seconds, set to `true` to set expire | |
324 | ## at browser close |
|
327 | ## at browser close | |
325 | #beaker.session.cookie_expires = 3600 |
|
328 | #beaker.session.cookie_expires = 3600 | |
326 |
|
329 | |||
327 | ################################### |
|
330 | ################################### | |
328 | ## SEARCH INDEXING CONFIGURATION ## |
|
331 | ## SEARCH INDEXING CONFIGURATION ## | |
329 | ################################### |
|
332 | ################################### | |
330 |
|
333 | |||
331 | search.module = rhodecode.lib.index.whoosh |
|
334 | search.module = rhodecode.lib.index.whoosh | |
332 | search.location = %(here)s/data/index |
|
335 | search.location = %(here)s/data/index | |
333 |
|
336 | |||
334 | ################################### |
|
337 | ################################### | |
335 | ## ERROR AND LOG HANDLING SYSTEM ## |
|
338 | ## ERROR AND LOG HANDLING SYSTEM ## | |
336 | ################################### |
|
339 | ################################### | |
337 |
|
340 | |||
338 | ## Appenlight is tailored to work with RhodeCode, see |
|
341 | ## Appenlight is tailored to work with RhodeCode, see | |
339 | ## http://appenlight.com for details how to obtain an account |
|
342 | ## http://appenlight.com for details how to obtain an account | |
340 |
|
343 | |||
341 | ## appenlight integration enabled |
|
344 | ## appenlight integration enabled | |
342 | appenlight = false |
|
345 | appenlight = false | |
343 |
|
346 | |||
344 | appenlight.server_url = https://api.appenlight.com |
|
347 | appenlight.server_url = https://api.appenlight.com | |
345 | appenlight.api_key = YOUR_API_KEY |
|
348 | appenlight.api_key = YOUR_API_KEY | |
346 | ;appenlight.transport_config = https://api.appenlight.com?threaded=1&timeout=5 |
|
349 | ;appenlight.transport_config = https://api.appenlight.com?threaded=1&timeout=5 | |
347 |
|
350 | |||
348 | # used for JS client |
|
351 | # used for JS client | |
349 | appenlight.api_public_key = YOUR_API_PUBLIC_KEY |
|
352 | appenlight.api_public_key = YOUR_API_PUBLIC_KEY | |
350 |
|
353 | |||
351 | ## TWEAK AMOUNT OF INFO SENT HERE |
|
354 | ## TWEAK AMOUNT OF INFO SENT HERE | |
352 |
|
355 | |||
353 | ## enables 404 error logging (default False) |
|
356 | ## enables 404 error logging (default False) | |
354 | appenlight.report_404 = false |
|
357 | appenlight.report_404 = false | |
355 |
|
358 | |||
356 | ## time in seconds after request is considered being slow (default 1) |
|
359 | ## time in seconds after request is considered being slow (default 1) | |
357 | appenlight.slow_request_time = 1 |
|
360 | appenlight.slow_request_time = 1 | |
358 |
|
361 | |||
359 | ## record slow requests in application |
|
362 | ## record slow requests in application | |
360 | ## (needs to be enabled for slow datastore recording and time tracking) |
|
363 | ## (needs to be enabled for slow datastore recording and time tracking) | |
361 | appenlight.slow_requests = true |
|
364 | appenlight.slow_requests = true | |
362 |
|
365 | |||
363 | ## enable hooking to application loggers |
|
366 | ## enable hooking to application loggers | |
364 | appenlight.logging = true |
|
367 | appenlight.logging = true | |
365 |
|
368 | |||
366 | ## minimum log level for log capture |
|
369 | ## minimum log level for log capture | |
367 | appenlight.logging.level = WARNING |
|
370 | appenlight.logging.level = WARNING | |
368 |
|
371 | |||
369 | ## send logs only from erroneous/slow requests |
|
372 | ## send logs only from erroneous/slow requests | |
370 | ## (saves API quota for intensive logging) |
|
373 | ## (saves API quota for intensive logging) | |
371 | appenlight.logging_on_error = false |
|
374 | appenlight.logging_on_error = false | |
372 |
|
375 | |||
373 | ## list of additonal keywords that should be grabbed from environ object |
|
376 | ## list of additonal keywords that should be grabbed from environ object | |
374 | ## can be string with comma separated list of words in lowercase |
|
377 | ## can be string with comma separated list of words in lowercase | |
375 | ## (by default client will always send following info: |
|
378 | ## (by default client will always send following info: | |
376 | ## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that |
|
379 | ## 'REMOTE_USER', 'REMOTE_ADDR', 'SERVER_NAME', 'CONTENT_TYPE' + all keys that | |
377 | ## start with HTTP* this list be extended with additional keywords here |
|
380 | ## start with HTTP* this list be extended with additional keywords here | |
378 | appenlight.environ_keys_whitelist = |
|
381 | appenlight.environ_keys_whitelist = | |
379 |
|
382 | |||
380 | ## list of keywords that should be blanked from request object |
|
383 | ## list of keywords that should be blanked from request object | |
381 | ## can be string with comma separated list of words in lowercase |
|
384 | ## can be string with comma separated list of words in lowercase | |
382 | ## (by default client will always blank keys that contain following words |
|
385 | ## (by default client will always blank keys that contain following words | |
383 | ## 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf' |
|
386 | ## 'password', 'passwd', 'pwd', 'auth_tkt', 'secret', 'csrf' | |
384 | ## this list be extended with additional keywords set here |
|
387 | ## this list be extended with additional keywords set here | |
385 | appenlight.request_keys_blacklist = |
|
388 | appenlight.request_keys_blacklist = | |
386 |
|
389 | |||
387 | ## list of namespaces that should be ignores when gathering log entries |
|
390 | ## list of namespaces that should be ignores when gathering log entries | |
388 | ## can be string with comma separated list of namespaces |
|
391 | ## can be string with comma separated list of namespaces | |
389 | ## (by default the client ignores own entries: appenlight_client.client) |
|
392 | ## (by default the client ignores own entries: appenlight_client.client) | |
390 | appenlight.log_namespace_blacklist = |
|
393 | appenlight.log_namespace_blacklist = | |
391 |
|
394 | |||
392 |
|
395 | |||
393 | ################################################################################ |
|
396 | ################################################################################ | |
394 | ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ## |
|
397 | ## WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT* ## | |
395 | ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ## |
|
398 | ## Debug mode will enable the interactive debugging tool, allowing ANYONE to ## | |
396 | ## execute malicious code after an exception is raised. ## |
|
399 | ## execute malicious code after an exception is raised. ## | |
397 | ################################################################################ |
|
400 | ################################################################################ | |
398 | set debug = false |
|
401 | set debug = false | |
399 |
|
402 | |||
400 |
|
403 | |||
401 | ############## |
|
404 | ############## | |
402 | ## STYLING ## |
|
405 | ## STYLING ## | |
403 | ############## |
|
406 | ############## | |
404 | debug_style = false |
|
407 | debug_style = false | |
405 |
|
408 | |||
406 | ######################################################### |
|
409 | ######################################################### | |
407 | ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ### |
|
410 | ### DB CONFIGS - EACH DB WILL HAVE IT'S OWN CONFIG ### | |
408 | ######################################################### |
|
411 | ######################################################### | |
409 | #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db?timeout=30 |
|
412 | #sqlalchemy.db1.url = sqlite:///%(here)s/rhodecode.db?timeout=30 | |
410 | sqlalchemy.db1.url = postgresql://postgres:qweqwe@localhost/rhodecode |
|
413 | sqlalchemy.db1.url = postgresql://postgres:qweqwe@localhost/rhodecode | |
411 | #sqlalchemy.db1.url = mysql://root:qweqwe@localhost/rhodecode |
|
414 | #sqlalchemy.db1.url = mysql://root:qweqwe@localhost/rhodecode | |
412 |
|
415 | |||
413 | # see sqlalchemy docs for other advanced settings |
|
416 | # see sqlalchemy docs for other advanced settings | |
414 |
|
417 | |||
415 | ## print the sql statements to output |
|
418 | ## print the sql statements to output | |
416 | sqlalchemy.db1.echo = false |
|
419 | sqlalchemy.db1.echo = false | |
417 | ## recycle the connections after this ammount of seconds |
|
420 | ## recycle the connections after this ammount of seconds | |
418 | sqlalchemy.db1.pool_recycle = 3600 |
|
421 | sqlalchemy.db1.pool_recycle = 3600 | |
419 | sqlalchemy.db1.convert_unicode = true |
|
422 | sqlalchemy.db1.convert_unicode = true | |
420 |
|
423 | |||
421 | ## the number of connections to keep open inside the connection pool. |
|
424 | ## the number of connections to keep open inside the connection pool. | |
422 | ## 0 indicates no limit |
|
425 | ## 0 indicates no limit | |
423 | #sqlalchemy.db1.pool_size = 5 |
|
426 | #sqlalchemy.db1.pool_size = 5 | |
424 |
|
427 | |||
425 | ## the number of connections to allow in connection pool "overflow", that is |
|
428 | ## the number of connections to allow in connection pool "overflow", that is | |
426 | ## connections that can be opened above and beyond the pool_size setting, |
|
429 | ## connections that can be opened above and beyond the pool_size setting, | |
427 | ## which defaults to five. |
|
430 | ## which defaults to five. | |
428 | #sqlalchemy.db1.max_overflow = 10 |
|
431 | #sqlalchemy.db1.max_overflow = 10 | |
429 |
|
432 | |||
430 |
|
433 | |||
431 | ################## |
|
434 | ################## | |
432 | ### VCS CONFIG ### |
|
435 | ### VCS CONFIG ### | |
433 | ################## |
|
436 | ################## | |
434 | vcs.server.enable = true |
|
437 | vcs.server.enable = true | |
435 | vcs.server = localhost:9900 |
|
438 | vcs.server = localhost:9900 | |
436 | # Available protocols: pyro4, http |
|
439 | # Available protocols: pyro4, http | |
437 | vcs.server.protocol = pyro4 |
|
440 | vcs.server.protocol = pyro4 | |
|
441 | ||||
|
442 | # available impl: | |||
|
443 | # vcsserver.scm_app (EE only, for testing), | |||
|
444 | # rhodecode.lib.middleware.utils.scm_app_http | |||
|
445 | # pyro4 | |||
|
446 | #vcs.scm_app_implementation = rhodecode.lib.middleware.utils.scm_app_http | |||
|
447 | ||||
438 | vcs.server.log_level = info |
|
448 | vcs.server.log_level = info | |
439 | vcs.start_server = false |
|
449 | vcs.start_server = false | |
440 | vcs.backends = hg, git, svn |
|
450 | vcs.backends = hg, git, svn | |
441 | vcs.connection_timeout = 3600 |
|
451 | vcs.connection_timeout = 3600 | |
442 | ## Compatibility version when creating SVN repositories. Defaults to newest version when commented out. |
|
452 | ## Compatibility version when creating SVN repositories. Defaults to newest version when commented out. | |
443 | ## Available options are: pre-1.4-compatible, pre-1.5-compatible, pre-1.6-compatible, pre-1.8-compatible |
|
453 | ## Available options are: pre-1.4-compatible, pre-1.5-compatible, pre-1.6-compatible, pre-1.8-compatible | |
444 | #vcs.svn.compatible_version = pre-1.8-compatible |
|
454 | #vcs.svn.compatible_version = pre-1.8-compatible | |
445 |
|
455 | |||
446 | ################################ |
|
456 | ################################ | |
447 | ### LOGGING CONFIGURATION #### |
|
457 | ### LOGGING CONFIGURATION #### | |
448 | ################################ |
|
458 | ################################ | |
449 | [loggers] |
|
459 | [loggers] | |
450 | keys = root, routes, rhodecode, sqlalchemy, beaker, pyro4, templates, whoosh_indexer |
|
460 | keys = root, routes, rhodecode, sqlalchemy, beaker, pyro4, templates, whoosh_indexer | |
451 |
|
461 | |||
452 | [handlers] |
|
462 | [handlers] | |
453 | keys = console, console_sql |
|
463 | keys = console, console_sql | |
454 |
|
464 | |||
455 | [formatters] |
|
465 | [formatters] | |
456 | keys = generic, color_formatter, color_formatter_sql |
|
466 | keys = generic, color_formatter, color_formatter_sql | |
457 |
|
467 | |||
458 | ############# |
|
468 | ############# | |
459 | ## LOGGERS ## |
|
469 | ## LOGGERS ## | |
460 | ############# |
|
470 | ############# | |
461 | [logger_root] |
|
471 | [logger_root] | |
462 | level = NOTSET |
|
472 | level = NOTSET | |
463 | handlers = console |
|
473 | handlers = console | |
464 |
|
474 | |||
465 | [logger_routes] |
|
475 | [logger_routes] | |
466 | level = DEBUG |
|
476 | level = DEBUG | |
467 | handlers = |
|
477 | handlers = | |
468 | qualname = routes.middleware |
|
478 | qualname = routes.middleware | |
469 | ## "level = DEBUG" logs the route matched and routing variables. |
|
479 | ## "level = DEBUG" logs the route matched and routing variables. | |
470 | propagate = 1 |
|
480 | propagate = 1 | |
471 |
|
481 | |||
472 | [logger_beaker] |
|
482 | [logger_beaker] | |
473 | level = DEBUG |
|
483 | level = DEBUG | |
474 | handlers = |
|
484 | handlers = | |
475 | qualname = beaker.container |
|
485 | qualname = beaker.container | |
476 | propagate = 1 |
|
486 | propagate = 1 | |
477 |
|
487 | |||
478 | [logger_pyro4] |
|
488 | [logger_pyro4] | |
479 | level = DEBUG |
|
489 | level = DEBUG | |
480 | handlers = |
|
490 | handlers = | |
481 | qualname = Pyro4 |
|
491 | qualname = Pyro4 | |
482 | propagate = 1 |
|
492 | propagate = 1 | |
483 |
|
493 | |||
484 | [logger_templates] |
|
494 | [logger_templates] | |
485 | level = INFO |
|
495 | level = INFO | |
486 | handlers = |
|
496 | handlers = | |
487 | qualname = pylons.templating |
|
497 | qualname = pylons.templating | |
488 | propagate = 1 |
|
498 | propagate = 1 | |
489 |
|
499 | |||
490 | [logger_rhodecode] |
|
500 | [logger_rhodecode] | |
491 | level = DEBUG |
|
501 | level = DEBUG | |
492 | handlers = |
|
502 | handlers = | |
493 | qualname = rhodecode |
|
503 | qualname = rhodecode | |
494 | propagate = 1 |
|
504 | propagate = 1 | |
495 |
|
505 | |||
496 | [logger_sqlalchemy] |
|
506 | [logger_sqlalchemy] | |
497 | level = INFO |
|
507 | level = INFO | |
498 | handlers = console_sql |
|
508 | handlers = console_sql | |
499 | qualname = sqlalchemy.engine |
|
509 | qualname = sqlalchemy.engine | |
500 | propagate = 0 |
|
510 | propagate = 0 | |
501 |
|
511 | |||
502 | [logger_whoosh_indexer] |
|
512 | [logger_whoosh_indexer] | |
503 | level = DEBUG |
|
513 | level = DEBUG | |
504 | handlers = |
|
514 | handlers = | |
505 | qualname = whoosh_indexer |
|
515 | qualname = whoosh_indexer | |
506 | propagate = 1 |
|
516 | propagate = 1 | |
507 |
|
517 | |||
508 | ############## |
|
518 | ############## | |
509 | ## HANDLERS ## |
|
519 | ## HANDLERS ## | |
510 | ############## |
|
520 | ############## | |
511 |
|
521 | |||
512 | [handler_console] |
|
522 | [handler_console] | |
513 | class = StreamHandler |
|
523 | class = StreamHandler | |
514 | args = (sys.stderr,) |
|
524 | args = (sys.stderr,) | |
515 | level = INFO |
|
525 | level = INFO | |
516 | formatter = generic |
|
526 | formatter = generic | |
517 |
|
527 | |||
518 | [handler_console_sql] |
|
528 | [handler_console_sql] | |
519 | class = StreamHandler |
|
529 | class = StreamHandler | |
520 | args = (sys.stderr,) |
|
530 | args = (sys.stderr,) | |
521 | level = WARN |
|
531 | level = WARN | |
522 | formatter = generic |
|
532 | formatter = generic | |
523 |
|
533 | |||
524 | ################ |
|
534 | ################ | |
525 | ## FORMATTERS ## |
|
535 | ## FORMATTERS ## | |
526 | ################ |
|
536 | ################ | |
527 |
|
537 | |||
528 | [formatter_generic] |
|
538 | [formatter_generic] | |
529 | class = rhodecode.lib.logging_formatter.Pyro4AwareFormatter |
|
539 | class = rhodecode.lib.logging_formatter.Pyro4AwareFormatter | |
530 | format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s |
|
540 | format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s | |
531 | datefmt = %Y-%m-%d %H:%M:%S |
|
541 | datefmt = %Y-%m-%d %H:%M:%S | |
532 |
|
542 | |||
533 | [formatter_color_formatter] |
|
543 | [formatter_color_formatter] | |
534 | class = rhodecode.lib.logging_formatter.ColorFormatter |
|
544 | class = rhodecode.lib.logging_formatter.ColorFormatter | |
535 | format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s |
|
545 | format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s | |
536 | datefmt = %Y-%m-%d %H:%M:%S |
|
546 | datefmt = %Y-%m-%d %H:%M:%S | |
537 |
|
547 | |||
538 | [formatter_color_formatter_sql] |
|
548 | [formatter_color_formatter_sql] | |
539 | class = rhodecode.lib.logging_formatter.ColorFormatterSql |
|
549 | class = rhodecode.lib.logging_formatter.ColorFormatterSql | |
540 | format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s |
|
550 | format = %(asctime)s.%(msecs)03d %(levelname)-5.5s [%(name)s] %(message)s | |
541 | datefmt = %Y-%m-%d %H:%M:%S |
|
551 | datefmt = %Y-%m-%d %H:%M:%S |
@@ -1,75 +1,76 b'' | |||||
1 | .. _rhodecode-release-notes-ref: |
|
1 | .. _rhodecode-release-notes-ref: | |
2 |
|
2 | |||
3 | Release Notes |
|
3 | Release Notes | |
4 | ============= |
|
4 | ============= | |
5 |
|
5 | |||
6 | |RCE| 4.x Versions |
|
6 | |RCE| 4.x Versions | |
7 | ------------------ |
|
7 | ------------------ | |
8 |
|
8 | |||
|
9 | release-notes-4.0.1.rst | |||
9 | release-notes-4.0.0.rst |
|
10 | release-notes-4.0.0.rst | |
10 |
|
11 | |||
11 | |RCE| 3.x Versions |
|
12 | |RCE| 3.x Versions | |
12 | ------------------ |
|
13 | ------------------ | |
13 |
|
14 | |||
14 | .. toctree:: |
|
15 | .. toctree:: | |
15 | :maxdepth: 1 |
|
16 | :maxdepth: 1 | |
16 |
|
17 | |||
17 | release-notes-3.8.4.rst |
|
18 | release-notes-3.8.4.rst | |
18 | release-notes-3.8.3.rst |
|
19 | release-notes-3.8.3.rst | |
19 | release-notes-3.8.2.rst |
|
20 | release-notes-3.8.2.rst | |
20 | release-notes-3.8.1.rst |
|
21 | release-notes-3.8.1.rst | |
21 | release-notes-3.8.0.rst |
|
22 | release-notes-3.8.0.rst | |
22 | release-notes-3.7.1.rst |
|
23 | release-notes-3.7.1.rst | |
23 | release-notes-3.7.0.rst |
|
24 | release-notes-3.7.0.rst | |
24 | release-notes-3.6.1.rst |
|
25 | release-notes-3.6.1.rst | |
25 | release-notes-3.6.0.rst |
|
26 | release-notes-3.6.0.rst | |
26 | release-notes-3.5.2.rst |
|
27 | release-notes-3.5.2.rst | |
27 | release-notes-3.5.1.rst |
|
28 | release-notes-3.5.1.rst | |
28 | release-notes-3.5.0.rst |
|
29 | release-notes-3.5.0.rst | |
29 | release-notes-3.4.1.rst |
|
30 | release-notes-3.4.1.rst | |
30 | release-notes-3.4.0.rst |
|
31 | release-notes-3.4.0.rst | |
31 | release-notes-3.3.4.rst |
|
32 | release-notes-3.3.4.rst | |
32 | release-notes-3.3.3.rst |
|
33 | release-notes-3.3.3.rst | |
33 | release-notes-3.3.2.rst |
|
34 | release-notes-3.3.2.rst | |
34 | release-notes-3.3.1.rst |
|
35 | release-notes-3.3.1.rst | |
35 | release-notes-3.3.0.rst |
|
36 | release-notes-3.3.0.rst | |
36 | release-notes-3.2.3.rst |
|
37 | release-notes-3.2.3.rst | |
37 | release-notes-3.2.2.rst |
|
38 | release-notes-3.2.2.rst | |
38 | release-notes-3.2.1.rst |
|
39 | release-notes-3.2.1.rst | |
39 | release-notes-3.2.0.rst |
|
40 | release-notes-3.2.0.rst | |
40 | release-notes-3.1.1.rst |
|
41 | release-notes-3.1.1.rst | |
41 | release-notes-3.1.0.rst |
|
42 | release-notes-3.1.0.rst | |
42 | release-notes-3.0.2.rst |
|
43 | release-notes-3.0.2.rst | |
43 | release-notes-3.0.1.rst |
|
44 | release-notes-3.0.1.rst | |
44 | release-notes-3.0.0.rst |
|
45 | release-notes-3.0.0.rst | |
45 |
|
46 | |||
46 | |RCE| 2.x Versions |
|
47 | |RCE| 2.x Versions | |
47 | ------------------ |
|
48 | ------------------ | |
48 |
|
49 | |||
49 | .. toctree:: |
|
50 | .. toctree:: | |
50 | :maxdepth: 1 |
|
51 | :maxdepth: 1 | |
51 |
|
52 | |||
52 | release-notes-2.2.8.rst |
|
53 | release-notes-2.2.8.rst | |
53 | release-notes-2.2.7.rst |
|
54 | release-notes-2.2.7.rst | |
54 | release-notes-2.2.6.rst |
|
55 | release-notes-2.2.6.rst | |
55 | release-notes-2.2.5.rst |
|
56 | release-notes-2.2.5.rst | |
56 | release-notes-2.2.4.rst |
|
57 | release-notes-2.2.4.rst | |
57 | release-notes-2.2.3.rst |
|
58 | release-notes-2.2.3.rst | |
58 | release-notes-2.2.2.rst |
|
59 | release-notes-2.2.2.rst | |
59 | release-notes-2.2.1.rst |
|
60 | release-notes-2.2.1.rst | |
60 | release-notes-2.2.0.rst |
|
61 | release-notes-2.2.0.rst | |
61 | release-notes-2.1.0.rst |
|
62 | release-notes-2.1.0.rst | |
62 | release-notes-2.0.2.rst |
|
63 | release-notes-2.0.2.rst | |
63 | release-notes-2.0.1.rst |
|
64 | release-notes-2.0.1.rst | |
64 | release-notes-2.0.0.rst |
|
65 | release-notes-2.0.0.rst | |
65 |
|
66 | |||
66 | |RCE| 1.x Versions |
|
67 | |RCE| 1.x Versions | |
67 | ------------------ |
|
68 | ------------------ | |
68 |
|
69 | |||
69 | .. toctree:: |
|
70 | .. toctree:: | |
70 | :maxdepth: 1 |
|
71 | :maxdepth: 1 | |
71 |
|
72 | |||
72 | release-notes-1.7.2.rst |
|
73 | release-notes-1.7.2.rst | |
73 | release-notes-1.7.1.rst |
|
74 | release-notes-1.7.1.rst | |
74 | release-notes-1.7.0.rst |
|
75 | release-notes-1.7.0.rst | |
75 | release-notes-1.6.0.rst |
|
76 | release-notes-1.6.0.rst |
@@ -1,1273 +1,1273 b'' | |||||
1 | { |
|
1 | { | |
2 | Babel = super.buildPythonPackage { |
|
2 | Babel = super.buildPythonPackage { | |
3 | name = "Babel-1.3"; |
|
3 | name = "Babel-1.3"; | |
4 | buildInputs = with self; []; |
|
4 | buildInputs = with self; []; | |
5 | doCheck = false; |
|
5 | doCheck = false; | |
6 | propagatedBuildInputs = with self; [pytz]; |
|
6 | propagatedBuildInputs = with self; [pytz]; | |
7 | src = fetchurl { |
|
7 | src = fetchurl { | |
8 | url = "https://pypi.python.org/packages/33/27/e3978243a03a76398c384c83f7ca879bc6e8f1511233a621fcada135606e/Babel-1.3.tar.gz"; |
|
8 | url = "https://pypi.python.org/packages/33/27/e3978243a03a76398c384c83f7ca879bc6e8f1511233a621fcada135606e/Babel-1.3.tar.gz"; | |
9 | md5 = "5264ceb02717843cbc9ffce8e6e06bdb"; |
|
9 | md5 = "5264ceb02717843cbc9ffce8e6e06bdb"; | |
10 | }; |
|
10 | }; | |
11 | }; |
|
11 | }; | |
12 | Beaker = super.buildPythonPackage { |
|
12 | Beaker = super.buildPythonPackage { | |
13 | name = "Beaker-1.7.0"; |
|
13 | name = "Beaker-1.7.0"; | |
14 | buildInputs = with self; []; |
|
14 | buildInputs = with self; []; | |
15 | doCheck = false; |
|
15 | doCheck = false; | |
16 | propagatedBuildInputs = with self; []; |
|
16 | propagatedBuildInputs = with self; []; | |
17 | src = fetchurl { |
|
17 | src = fetchurl { | |
18 | url = "https://pypi.python.org/packages/97/8e/409d2e7c009b8aa803dc9e6f239f1db7c3cdf578249087a404e7c27a505d/Beaker-1.7.0.tar.gz"; |
|
18 | url = "https://pypi.python.org/packages/97/8e/409d2e7c009b8aa803dc9e6f239f1db7c3cdf578249087a404e7c27a505d/Beaker-1.7.0.tar.gz"; | |
19 | md5 = "386be3f7fe427358881eee4622b428b3"; |
|
19 | md5 = "386be3f7fe427358881eee4622b428b3"; | |
20 | }; |
|
20 | }; | |
21 | }; |
|
21 | }; | |
22 | CProfileV = super.buildPythonPackage { |
|
22 | CProfileV = super.buildPythonPackage { | |
23 | name = "CProfileV-1.0.6"; |
|
23 | name = "CProfileV-1.0.6"; | |
24 | buildInputs = with self; []; |
|
24 | buildInputs = with self; []; | |
25 | doCheck = false; |
|
25 | doCheck = false; | |
26 | propagatedBuildInputs = with self; [bottle]; |
|
26 | propagatedBuildInputs = with self; [bottle]; | |
27 | src = fetchurl { |
|
27 | src = fetchurl { | |
28 | url = "https://pypi.python.org/packages/eb/df/983a0b6cfd3ac94abf023f5011cb04f33613ace196e33f53c86cf91850d5/CProfileV-1.0.6.tar.gz"; |
|
28 | url = "https://pypi.python.org/packages/eb/df/983a0b6cfd3ac94abf023f5011cb04f33613ace196e33f53c86cf91850d5/CProfileV-1.0.6.tar.gz"; | |
29 | md5 = "08c7c242b6e64237bc53c5d13537e03d"; |
|
29 | md5 = "08c7c242b6e64237bc53c5d13537e03d"; | |
30 | }; |
|
30 | }; | |
31 | }; |
|
31 | }; | |
32 | Fabric = super.buildPythonPackage { |
|
32 | Fabric = super.buildPythonPackage { | |
33 | name = "Fabric-1.10.0"; |
|
33 | name = "Fabric-1.10.0"; | |
34 | buildInputs = with self; []; |
|
34 | buildInputs = with self; []; | |
35 | doCheck = false; |
|
35 | doCheck = false; | |
36 | propagatedBuildInputs = with self; [paramiko]; |
|
36 | propagatedBuildInputs = with self; [paramiko]; | |
37 | src = fetchurl { |
|
37 | src = fetchurl { | |
38 | url = "https://pypi.python.org/packages/e3/5f/b6ebdb5241d5ec9eab582a5c8a01255c1107da396f849e538801d2fe64a5/Fabric-1.10.0.tar.gz"; |
|
38 | url = "https://pypi.python.org/packages/e3/5f/b6ebdb5241d5ec9eab582a5c8a01255c1107da396f849e538801d2fe64a5/Fabric-1.10.0.tar.gz"; | |
39 | md5 = "2cb96473387f0e7aa035210892352f4a"; |
|
39 | md5 = "2cb96473387f0e7aa035210892352f4a"; | |
40 | }; |
|
40 | }; | |
41 | }; |
|
41 | }; | |
42 | FormEncode = super.buildPythonPackage { |
|
42 | FormEncode = super.buildPythonPackage { | |
43 | name = "FormEncode-1.2.4"; |
|
43 | name = "FormEncode-1.2.4"; | |
44 | buildInputs = with self; []; |
|
44 | buildInputs = with self; []; | |
45 | doCheck = false; |
|
45 | doCheck = false; | |
46 | propagatedBuildInputs = with self; []; |
|
46 | propagatedBuildInputs = with self; []; | |
47 | src = fetchurl { |
|
47 | src = fetchurl { | |
48 | url = "https://pypi.python.org/packages/8e/59/0174271a6f004512e0201188593e6d319db139d14cb7490e488bbb078015/FormEncode-1.2.4.tar.gz"; |
|
48 | url = "https://pypi.python.org/packages/8e/59/0174271a6f004512e0201188593e6d319db139d14cb7490e488bbb078015/FormEncode-1.2.4.tar.gz"; | |
49 | md5 = "6bc17fb9aed8aea198975e888e2077f4"; |
|
49 | md5 = "6bc17fb9aed8aea198975e888e2077f4"; | |
50 | }; |
|
50 | }; | |
51 | }; |
|
51 | }; | |
52 | Jinja2 = super.buildPythonPackage { |
|
52 | Jinja2 = super.buildPythonPackage { | |
53 | name = "Jinja2-2.7.3"; |
|
53 | name = "Jinja2-2.7.3"; | |
54 | buildInputs = with self; []; |
|
54 | buildInputs = with self; []; | |
55 | doCheck = false; |
|
55 | doCheck = false; | |
56 | propagatedBuildInputs = with self; [MarkupSafe]; |
|
56 | propagatedBuildInputs = with self; [MarkupSafe]; | |
57 | src = fetchurl { |
|
57 | src = fetchurl { | |
58 | url = "https://pypi.python.org/packages/b0/73/eab0bca302d6d6a0b5c402f47ad1760dc9cb2dd14bbc1873ad48db258e4d/Jinja2-2.7.3.tar.gz"; |
|
58 | url = "https://pypi.python.org/packages/b0/73/eab0bca302d6d6a0b5c402f47ad1760dc9cb2dd14bbc1873ad48db258e4d/Jinja2-2.7.3.tar.gz"; | |
59 | md5 = "b9dffd2f3b43d673802fe857c8445b1a"; |
|
59 | md5 = "b9dffd2f3b43d673802fe857c8445b1a"; | |
60 | }; |
|
60 | }; | |
61 | }; |
|
61 | }; | |
62 | Mako = super.buildPythonPackage { |
|
62 | Mako = super.buildPythonPackage { | |
63 | name = "Mako-1.0.1"; |
|
63 | name = "Mako-1.0.1"; | |
64 | buildInputs = with self; []; |
|
64 | buildInputs = with self; []; | |
65 | doCheck = false; |
|
65 | doCheck = false; | |
66 | propagatedBuildInputs = with self; [MarkupSafe]; |
|
66 | propagatedBuildInputs = with self; [MarkupSafe]; | |
67 | src = fetchurl { |
|
67 | src = fetchurl { | |
68 | url = "https://pypi.python.org/packages/8e/a4/aa56533ecaa5f22ca92428f74e074d0c9337282933c722391902c8f9e0f8/Mako-1.0.1.tar.gz"; |
|
68 | url = "https://pypi.python.org/packages/8e/a4/aa56533ecaa5f22ca92428f74e074d0c9337282933c722391902c8f9e0f8/Mako-1.0.1.tar.gz"; | |
69 | md5 = "9f0aafd177b039ef67b90ea350497a54"; |
|
69 | md5 = "9f0aafd177b039ef67b90ea350497a54"; | |
70 | }; |
|
70 | }; | |
71 | }; |
|
71 | }; | |
72 | Markdown = super.buildPythonPackage { |
|
72 | Markdown = super.buildPythonPackage { | |
73 | name = "Markdown-2.6.2"; |
|
73 | name = "Markdown-2.6.2"; | |
74 | buildInputs = with self; []; |
|
74 | buildInputs = with self; []; | |
75 | doCheck = false; |
|
75 | doCheck = false; | |
76 | propagatedBuildInputs = with self; []; |
|
76 | propagatedBuildInputs = with self; []; | |
77 | src = fetchurl { |
|
77 | src = fetchurl { | |
78 | url = "https://pypi.python.org/packages/62/8b/83658b5f6c220d5fcde9f9852d46ea54765d734cfbc5a9f4c05bfc36db4d/Markdown-2.6.2.tar.gz"; |
|
78 | url = "https://pypi.python.org/packages/62/8b/83658b5f6c220d5fcde9f9852d46ea54765d734cfbc5a9f4c05bfc36db4d/Markdown-2.6.2.tar.gz"; | |
79 | md5 = "256d19afcc564dc4ce4c229bb762f7ae"; |
|
79 | md5 = "256d19afcc564dc4ce4c229bb762f7ae"; | |
80 | }; |
|
80 | }; | |
81 | }; |
|
81 | }; | |
82 | MarkupSafe = super.buildPythonPackage { |
|
82 | MarkupSafe = super.buildPythonPackage { | |
83 | name = "MarkupSafe-0.23"; |
|
83 | name = "MarkupSafe-0.23"; | |
84 | buildInputs = with self; []; |
|
84 | buildInputs = with self; []; | |
85 | doCheck = false; |
|
85 | doCheck = false; | |
86 | propagatedBuildInputs = with self; []; |
|
86 | propagatedBuildInputs = with self; []; | |
87 | src = fetchurl { |
|
87 | src = fetchurl { | |
88 | url = "https://pypi.python.org/packages/c0/41/bae1254e0396c0cc8cf1751cb7d9afc90a602353695af5952530482c963f/MarkupSafe-0.23.tar.gz"; |
|
88 | url = "https://pypi.python.org/packages/c0/41/bae1254e0396c0cc8cf1751cb7d9afc90a602353695af5952530482c963f/MarkupSafe-0.23.tar.gz"; | |
89 | md5 = "f5ab3deee4c37cd6a922fb81e730da6e"; |
|
89 | md5 = "f5ab3deee4c37cd6a922fb81e730da6e"; | |
90 | }; |
|
90 | }; | |
91 | }; |
|
91 | }; | |
92 | MySQL-python = super.buildPythonPackage { |
|
92 | MySQL-python = super.buildPythonPackage { | |
93 | name = "MySQL-python-1.2.5"; |
|
93 | name = "MySQL-python-1.2.5"; | |
94 | buildInputs = with self; []; |
|
94 | buildInputs = with self; []; | |
95 | doCheck = false; |
|
95 | doCheck = false; | |
96 | propagatedBuildInputs = with self; []; |
|
96 | propagatedBuildInputs = with self; []; | |
97 | src = fetchurl { |
|
97 | src = fetchurl { | |
98 | url = "https://pypi.python.org/packages/a5/e9/51b544da85a36a68debe7a7091f068d802fc515a3a202652828c73453cad/MySQL-python-1.2.5.zip"; |
|
98 | url = "https://pypi.python.org/packages/a5/e9/51b544da85a36a68debe7a7091f068d802fc515a3a202652828c73453cad/MySQL-python-1.2.5.zip"; | |
99 | md5 = "654f75b302db6ed8dc5a898c625e030c"; |
|
99 | md5 = "654f75b302db6ed8dc5a898c625e030c"; | |
100 | }; |
|
100 | }; | |
101 | }; |
|
101 | }; | |
102 | Paste = super.buildPythonPackage { |
|
102 | Paste = super.buildPythonPackage { | |
103 | name = "Paste-2.0.2"; |
|
103 | name = "Paste-2.0.2"; | |
104 | buildInputs = with self; []; |
|
104 | buildInputs = with self; []; | |
105 | doCheck = false; |
|
105 | doCheck = false; | |
106 | propagatedBuildInputs = with self; [six]; |
|
106 | propagatedBuildInputs = with self; [six]; | |
107 | src = fetchurl { |
|
107 | src = fetchurl { | |
108 | url = "https://pypi.python.org/packages/d5/8d/0f8ac40687b97ff3e07ebd1369be20bdb3f93864d2dc3c2ff542edb4ce50/Paste-2.0.2.tar.gz"; |
|
108 | url = "https://pypi.python.org/packages/d5/8d/0f8ac40687b97ff3e07ebd1369be20bdb3f93864d2dc3c2ff542edb4ce50/Paste-2.0.2.tar.gz"; | |
109 | md5 = "4bfc8a7eaf858f6309d2ac0f40fc951c"; |
|
109 | md5 = "4bfc8a7eaf858f6309d2ac0f40fc951c"; | |
110 | }; |
|
110 | }; | |
111 | }; |
|
111 | }; | |
112 | PasteDeploy = super.buildPythonPackage { |
|
112 | PasteDeploy = super.buildPythonPackage { | |
113 | name = "PasteDeploy-1.5.2"; |
|
113 | name = "PasteDeploy-1.5.2"; | |
114 | buildInputs = with self; []; |
|
114 | buildInputs = with self; []; | |
115 | doCheck = false; |
|
115 | doCheck = false; | |
116 | propagatedBuildInputs = with self; []; |
|
116 | propagatedBuildInputs = with self; []; | |
117 | src = fetchurl { |
|
117 | src = fetchurl { | |
118 | url = "https://pypi.python.org/packages/0f/90/8e20cdae206c543ea10793cbf4136eb9a8b3f417e04e40a29d72d9922cbd/PasteDeploy-1.5.2.tar.gz"; |
|
118 | url = "https://pypi.python.org/packages/0f/90/8e20cdae206c543ea10793cbf4136eb9a8b3f417e04e40a29d72d9922cbd/PasteDeploy-1.5.2.tar.gz"; | |
119 | md5 = "352b7205c78c8de4987578d19431af3b"; |
|
119 | md5 = "352b7205c78c8de4987578d19431af3b"; | |
120 | }; |
|
120 | }; | |
121 | }; |
|
121 | }; | |
122 | PasteScript = super.buildPythonPackage { |
|
122 | PasteScript = super.buildPythonPackage { | |
123 | name = "PasteScript-1.7.5"; |
|
123 | name = "PasteScript-1.7.5"; | |
124 | buildInputs = with self; []; |
|
124 | buildInputs = with self; []; | |
125 | doCheck = false; |
|
125 | doCheck = false; | |
126 | propagatedBuildInputs = with self; [Paste PasteDeploy]; |
|
126 | propagatedBuildInputs = with self; [Paste PasteDeploy]; | |
127 | src = fetchurl { |
|
127 | src = fetchurl { | |
128 | url = "https://pypi.python.org/packages/a5/05/fc60efa7c2f17a1dbaeccb2a903a1e90902d92b9d00eebabe3095829d806/PasteScript-1.7.5.tar.gz"; |
|
128 | url = "https://pypi.python.org/packages/a5/05/fc60efa7c2f17a1dbaeccb2a903a1e90902d92b9d00eebabe3095829d806/PasteScript-1.7.5.tar.gz"; | |
129 | md5 = "4c72d78dcb6bb993f30536842c16af4d"; |
|
129 | md5 = "4c72d78dcb6bb993f30536842c16af4d"; | |
130 | }; |
|
130 | }; | |
131 | }; |
|
131 | }; | |
132 | Pygments = super.buildPythonPackage { |
|
132 | Pygments = super.buildPythonPackage { | |
133 | name = "Pygments-2.0.2"; |
|
133 | name = "Pygments-2.0.2"; | |
134 | buildInputs = with self; []; |
|
134 | buildInputs = with self; []; | |
135 | doCheck = false; |
|
135 | doCheck = false; | |
136 | propagatedBuildInputs = with self; []; |
|
136 | propagatedBuildInputs = with self; []; | |
137 | src = fetchurl { |
|
137 | src = fetchurl { | |
138 | url = "https://pypi.python.org/packages/f4/c6/bdbc5a8a112256b2b6136af304dbae93d8b1ef8738ff2d12a51018800e46/Pygments-2.0.2.tar.gz"; |
|
138 | url = "https://pypi.python.org/packages/f4/c6/bdbc5a8a112256b2b6136af304dbae93d8b1ef8738ff2d12a51018800e46/Pygments-2.0.2.tar.gz"; | |
139 | md5 = "238587a1370d62405edabd0794b3ec4a"; |
|
139 | md5 = "238587a1370d62405edabd0794b3ec4a"; | |
140 | }; |
|
140 | }; | |
141 | }; |
|
141 | }; | |
142 | Pylons = super.buildPythonPackage { |
|
142 | Pylons = super.buildPythonPackage { | |
143 | name = "Pylons-1.0.1"; |
|
143 | name = "Pylons-1.0.1"; | |
144 | buildInputs = with self; []; |
|
144 | buildInputs = with self; []; | |
145 | doCheck = false; |
|
145 | doCheck = false; | |
146 | propagatedBuildInputs = with self; [Routes WebHelpers Beaker Paste PasteDeploy PasteScript FormEncode simplejson decorator nose Mako WebError WebTest Tempita MarkupSafe WebOb]; |
|
146 | propagatedBuildInputs = with self; [Routes WebHelpers Beaker Paste PasteDeploy PasteScript FormEncode simplejson decorator nose Mako WebError WebTest Tempita MarkupSafe WebOb]; | |
147 | src = fetchurl { |
|
147 | src = fetchurl { | |
148 | url = "https://pypi.python.org/packages/a2/69/b835a6bad00acbfeed3f33c6e44fa3f936efc998c795bfb15c61a79ecf62/Pylons-1.0.1.tar.gz"; |
|
148 | url = "https://pypi.python.org/packages/a2/69/b835a6bad00acbfeed3f33c6e44fa3f936efc998c795bfb15c61a79ecf62/Pylons-1.0.1.tar.gz"; | |
149 | md5 = "6cb880d75fa81213192142b07a6e4915"; |
|
149 | md5 = "6cb880d75fa81213192142b07a6e4915"; | |
150 | }; |
|
150 | }; | |
151 | }; |
|
151 | }; | |
152 | Pyro4 = super.buildPythonPackage { |
|
152 | Pyro4 = super.buildPythonPackage { | |
153 | name = "Pyro4-4.41"; |
|
153 | name = "Pyro4-4.41"; | |
154 | buildInputs = with self; []; |
|
154 | buildInputs = with self; []; | |
155 | doCheck = false; |
|
155 | doCheck = false; | |
156 | propagatedBuildInputs = with self; [serpent]; |
|
156 | propagatedBuildInputs = with self; [serpent]; | |
157 | src = fetchurl { |
|
157 | src = fetchurl { | |
158 | url = "https://pypi.python.org/packages/56/2b/89b566b4bf3e7f8ba790db2d1223852f8cb454c52cab7693dd41f608ca2a/Pyro4-4.41.tar.gz"; |
|
158 | url = "https://pypi.python.org/packages/56/2b/89b566b4bf3e7f8ba790db2d1223852f8cb454c52cab7693dd41f608ca2a/Pyro4-4.41.tar.gz"; | |
159 | md5 = "ed69e9bfafa9c06c049a87cb0c4c2b6c"; |
|
159 | md5 = "ed69e9bfafa9c06c049a87cb0c4c2b6c"; | |
160 | }; |
|
160 | }; | |
161 | }; |
|
161 | }; | |
162 | Routes = super.buildPythonPackage { |
|
162 | Routes = super.buildPythonPackage { | |
163 | name = "Routes-1.13"; |
|
163 | name = "Routes-1.13"; | |
164 | buildInputs = with self; []; |
|
164 | buildInputs = with self; []; | |
165 | doCheck = false; |
|
165 | doCheck = false; | |
166 | propagatedBuildInputs = with self; [repoze.lru]; |
|
166 | propagatedBuildInputs = with self; [repoze.lru]; | |
167 | src = fetchurl { |
|
167 | src = fetchurl { | |
168 | url = "https://pypi.python.org/packages/88/d3/259c3b3cde8837eb9441ab5f574a660e8a4acea8f54a078441d4d2acac1c/Routes-1.13.tar.gz"; |
|
168 | url = "https://pypi.python.org/packages/88/d3/259c3b3cde8837eb9441ab5f574a660e8a4acea8f54a078441d4d2acac1c/Routes-1.13.tar.gz"; | |
169 | md5 = "d527b0ab7dd9172b1275a41f97448783"; |
|
169 | md5 = "d527b0ab7dd9172b1275a41f97448783"; | |
170 | }; |
|
170 | }; | |
171 | }; |
|
171 | }; | |
172 | SQLAlchemy = super.buildPythonPackage { |
|
172 | SQLAlchemy = super.buildPythonPackage { | |
173 | name = "SQLAlchemy-0.9.9"; |
|
173 | name = "SQLAlchemy-0.9.9"; | |
174 | buildInputs = with self; []; |
|
174 | buildInputs = with self; []; | |
175 | doCheck = false; |
|
175 | doCheck = false; | |
176 | propagatedBuildInputs = with self; []; |
|
176 | propagatedBuildInputs = with self; []; | |
177 | src = fetchurl { |
|
177 | src = fetchurl { | |
178 | url = "https://pypi.python.org/packages/28/f7/1bbfd0d8597e8c358d5e15a166a486ad82fc5579b4e67b6ef7c05b1d182b/SQLAlchemy-0.9.9.tar.gz"; |
|
178 | url = "https://pypi.python.org/packages/28/f7/1bbfd0d8597e8c358d5e15a166a486ad82fc5579b4e67b6ef7c05b1d182b/SQLAlchemy-0.9.9.tar.gz"; | |
179 | md5 = "8a10a9bd13ed3336ef7333ac2cc679ff"; |
|
179 | md5 = "8a10a9bd13ed3336ef7333ac2cc679ff"; | |
180 | }; |
|
180 | }; | |
181 | }; |
|
181 | }; | |
182 | Sphinx = super.buildPythonPackage { |
|
182 | Sphinx = super.buildPythonPackage { | |
183 | name = "Sphinx-1.2.2"; |
|
183 | name = "Sphinx-1.2.2"; | |
184 | buildInputs = with self; []; |
|
184 | buildInputs = with self; []; | |
185 | doCheck = false; |
|
185 | doCheck = false; | |
186 | propagatedBuildInputs = with self; [Pygments docutils Jinja2]; |
|
186 | propagatedBuildInputs = with self; [Pygments docutils Jinja2]; | |
187 | src = fetchurl { |
|
187 | src = fetchurl { | |
188 | url = "https://pypi.python.org/packages/0a/50/34017e6efcd372893a416aba14b84a1a149fc7074537b0e9cb6ca7b7abe9/Sphinx-1.2.2.tar.gz"; |
|
188 | url = "https://pypi.python.org/packages/0a/50/34017e6efcd372893a416aba14b84a1a149fc7074537b0e9cb6ca7b7abe9/Sphinx-1.2.2.tar.gz"; | |
189 | md5 = "3dc73ccaa8d0bfb2d62fb671b1f7e8a4"; |
|
189 | md5 = "3dc73ccaa8d0bfb2d62fb671b1f7e8a4"; | |
190 | }; |
|
190 | }; | |
191 | }; |
|
191 | }; | |
192 | Tempita = super.buildPythonPackage { |
|
192 | Tempita = super.buildPythonPackage { | |
193 | name = "Tempita-0.5.2"; |
|
193 | name = "Tempita-0.5.2"; | |
194 | buildInputs = with self; []; |
|
194 | buildInputs = with self; []; | |
195 | doCheck = false; |
|
195 | doCheck = false; | |
196 | propagatedBuildInputs = with self; []; |
|
196 | propagatedBuildInputs = with self; []; | |
197 | src = fetchurl { |
|
197 | src = fetchurl { | |
198 | url = "https://pypi.python.org/packages/56/c8/8ed6eee83dbddf7b0fc64dd5d4454bc05e6ccaafff47991f73f2894d9ff4/Tempita-0.5.2.tar.gz"; |
|
198 | url = "https://pypi.python.org/packages/56/c8/8ed6eee83dbddf7b0fc64dd5d4454bc05e6ccaafff47991f73f2894d9ff4/Tempita-0.5.2.tar.gz"; | |
199 | md5 = "4c2f17bb9d481821c41b6fbee904cea1"; |
|
199 | md5 = "4c2f17bb9d481821c41b6fbee904cea1"; | |
200 | }; |
|
200 | }; | |
201 | }; |
|
201 | }; | |
202 | URLObject = super.buildPythonPackage { |
|
202 | URLObject = super.buildPythonPackage { | |
203 | name = "URLObject-2.4.0"; |
|
203 | name = "URLObject-2.4.0"; | |
204 | buildInputs = with self; []; |
|
204 | buildInputs = with self; []; | |
205 | doCheck = false; |
|
205 | doCheck = false; | |
206 | propagatedBuildInputs = with self; []; |
|
206 | propagatedBuildInputs = with self; []; | |
207 | src = fetchurl { |
|
207 | src = fetchurl { | |
208 | url = "https://pypi.python.org/packages/cb/b6/e25e58500f9caef85d664bec71ec67c116897bfebf8622c32cb75d1ca199/URLObject-2.4.0.tar.gz"; |
|
208 | url = "https://pypi.python.org/packages/cb/b6/e25e58500f9caef85d664bec71ec67c116897bfebf8622c32cb75d1ca199/URLObject-2.4.0.tar.gz"; | |
209 | md5 = "2ed819738a9f0a3051f31dc9924e3065"; |
|
209 | md5 = "2ed819738a9f0a3051f31dc9924e3065"; | |
210 | }; |
|
210 | }; | |
211 | }; |
|
211 | }; | |
212 | WebError = super.buildPythonPackage { |
|
212 | WebError = super.buildPythonPackage { | |
213 | name = "WebError-0.10.3"; |
|
213 | name = "WebError-0.10.3"; | |
214 | buildInputs = with self; []; |
|
214 | buildInputs = with self; []; | |
215 | doCheck = false; |
|
215 | doCheck = false; | |
216 | propagatedBuildInputs = with self; [WebOb Tempita Pygments Paste]; |
|
216 | propagatedBuildInputs = with self; [WebOb Tempita Pygments Paste]; | |
217 | src = fetchurl { |
|
217 | src = fetchurl { | |
218 | url = "https://pypi.python.org/packages/35/76/e7e5c2ce7e9c7f31b54c1ff295a495886d1279a002557d74dd8957346a79/WebError-0.10.3.tar.gz"; |
|
218 | url = "https://pypi.python.org/packages/35/76/e7e5c2ce7e9c7f31b54c1ff295a495886d1279a002557d74dd8957346a79/WebError-0.10.3.tar.gz"; | |
219 | md5 = "84b9990b0baae6fd440b1e60cdd06f9a"; |
|
219 | md5 = "84b9990b0baae6fd440b1e60cdd06f9a"; | |
220 | }; |
|
220 | }; | |
221 | }; |
|
221 | }; | |
222 | WebHelpers = super.buildPythonPackage { |
|
222 | WebHelpers = super.buildPythonPackage { | |
223 | name = "WebHelpers-1.3"; |
|
223 | name = "WebHelpers-1.3"; | |
224 | buildInputs = with self; []; |
|
224 | buildInputs = with self; []; | |
225 | doCheck = false; |
|
225 | doCheck = false; | |
226 | propagatedBuildInputs = with self; [MarkupSafe]; |
|
226 | propagatedBuildInputs = with self; [MarkupSafe]; | |
227 | src = fetchurl { |
|
227 | src = fetchurl { | |
228 | url = "https://pypi.python.org/packages/ee/68/4d07672821d514184357f1552f2dad923324f597e722de3b016ca4f7844f/WebHelpers-1.3.tar.gz"; |
|
228 | url = "https://pypi.python.org/packages/ee/68/4d07672821d514184357f1552f2dad923324f597e722de3b016ca4f7844f/WebHelpers-1.3.tar.gz"; | |
229 | md5 = "32749ffadfc40fea51075a7def32588b"; |
|
229 | md5 = "32749ffadfc40fea51075a7def32588b"; | |
230 | }; |
|
230 | }; | |
231 | }; |
|
231 | }; | |
232 | WebHelpers2 = super.buildPythonPackage { |
|
232 | WebHelpers2 = super.buildPythonPackage { | |
233 | name = "WebHelpers2-2.0"; |
|
233 | name = "WebHelpers2-2.0"; | |
234 | buildInputs = with self; []; |
|
234 | buildInputs = with self; []; | |
235 | doCheck = false; |
|
235 | doCheck = false; | |
236 | propagatedBuildInputs = with self; [MarkupSafe six]; |
|
236 | propagatedBuildInputs = with self; [MarkupSafe six]; | |
237 | src = fetchurl { |
|
237 | src = fetchurl { | |
238 | url = "https://pypi.python.org/packages/ff/30/56342c6ea522439e3662427c8d7b5e5b390dff4ff2dc92d8afcb8ab68b75/WebHelpers2-2.0.tar.gz"; |
|
238 | url = "https://pypi.python.org/packages/ff/30/56342c6ea522439e3662427c8d7b5e5b390dff4ff2dc92d8afcb8ab68b75/WebHelpers2-2.0.tar.gz"; | |
239 | md5 = "0f6b68d70c12ee0aed48c00b24da13d3"; |
|
239 | md5 = "0f6b68d70c12ee0aed48c00b24da13d3"; | |
240 | }; |
|
240 | }; | |
241 | }; |
|
241 | }; | |
242 | WebOb = super.buildPythonPackage { |
|
242 | WebOb = super.buildPythonPackage { | |
243 | name = "WebOb-1.3.1"; |
|
243 | name = "WebOb-1.3.1"; | |
244 | buildInputs = with self; []; |
|
244 | buildInputs = with self; []; | |
245 | doCheck = false; |
|
245 | doCheck = false; | |
246 | propagatedBuildInputs = with self; []; |
|
246 | propagatedBuildInputs = with self; []; | |
247 | src = fetchurl { |
|
247 | src = fetchurl { | |
248 | url = "https://pypi.python.org/packages/16/78/adfc0380b8a0d75b2d543fa7085ba98a573b1ae486d9def88d172b81b9fa/WebOb-1.3.1.tar.gz"; |
|
248 | url = "https://pypi.python.org/packages/16/78/adfc0380b8a0d75b2d543fa7085ba98a573b1ae486d9def88d172b81b9fa/WebOb-1.3.1.tar.gz"; | |
249 | md5 = "20918251c5726956ba8fef22d1556177"; |
|
249 | md5 = "20918251c5726956ba8fef22d1556177"; | |
250 | }; |
|
250 | }; | |
251 | }; |
|
251 | }; | |
252 | WebTest = super.buildPythonPackage { |
|
252 | WebTest = super.buildPythonPackage { | |
253 | name = "WebTest-1.4.3"; |
|
253 | name = "WebTest-1.4.3"; | |
254 | buildInputs = with self; []; |
|
254 | buildInputs = with self; []; | |
255 | doCheck = false; |
|
255 | doCheck = false; | |
256 | propagatedBuildInputs = with self; [WebOb]; |
|
256 | propagatedBuildInputs = with self; [WebOb]; | |
257 | src = fetchurl { |
|
257 | src = fetchurl { | |
258 | url = "https://pypi.python.org/packages/51/3d/84fd0f628df10b30c7db87895f56d0158e5411206b721ca903cb51bfd948/WebTest-1.4.3.zip"; |
|
258 | url = "https://pypi.python.org/packages/51/3d/84fd0f628df10b30c7db87895f56d0158e5411206b721ca903cb51bfd948/WebTest-1.4.3.zip"; | |
259 | md5 = "631ce728bed92c681a4020a36adbc353"; |
|
259 | md5 = "631ce728bed92c681a4020a36adbc353"; | |
260 | }; |
|
260 | }; | |
261 | }; |
|
261 | }; | |
262 | Whoosh = super.buildPythonPackage { |
|
262 | Whoosh = super.buildPythonPackage { | |
263 | name = "Whoosh-2.7.0"; |
|
263 | name = "Whoosh-2.7.0"; | |
264 | buildInputs = with self; []; |
|
264 | buildInputs = with self; []; | |
265 | doCheck = false; |
|
265 | doCheck = false; | |
266 | propagatedBuildInputs = with self; []; |
|
266 | propagatedBuildInputs = with self; []; | |
267 | src = fetchurl { |
|
267 | src = fetchurl { | |
268 | url = "https://pypi.python.org/packages/1c/dc/2f0231ff3875ded36df8c1ab851451e51a237dc0e5a86d3d96036158da94/Whoosh-2.7.0.zip"; |
|
268 | url = "https://pypi.python.org/packages/1c/dc/2f0231ff3875ded36df8c1ab851451e51a237dc0e5a86d3d96036158da94/Whoosh-2.7.0.zip"; | |
269 | md5 = "7abfd970f16fadc7311960f3fa0bc7a9"; |
|
269 | md5 = "7abfd970f16fadc7311960f3fa0bc7a9"; | |
270 | }; |
|
270 | }; | |
271 | }; |
|
271 | }; | |
272 | alembic = super.buildPythonPackage { |
|
272 | alembic = super.buildPythonPackage { | |
273 | name = "alembic-0.8.4"; |
|
273 | name = "alembic-0.8.4"; | |
274 | buildInputs = with self; []; |
|
274 | buildInputs = with self; []; | |
275 | doCheck = false; |
|
275 | doCheck = false; | |
276 | propagatedBuildInputs = with self; [SQLAlchemy Mako python-editor]; |
|
276 | propagatedBuildInputs = with self; [SQLAlchemy Mako python-editor]; | |
277 | src = fetchurl { |
|
277 | src = fetchurl { | |
278 | url = "https://pypi.python.org/packages/ca/7e/299b4499b5c75e5a38c5845145ad24755bebfb8eec07a2e1c366b7181eeb/alembic-0.8.4.tar.gz"; |
|
278 | url = "https://pypi.python.org/packages/ca/7e/299b4499b5c75e5a38c5845145ad24755bebfb8eec07a2e1c366b7181eeb/alembic-0.8.4.tar.gz"; | |
279 | md5 = "5f95d8ee62b443f9b37eb5bee76c582d"; |
|
279 | md5 = "5f95d8ee62b443f9b37eb5bee76c582d"; | |
280 | }; |
|
280 | }; | |
281 | }; |
|
281 | }; | |
282 | amqplib = super.buildPythonPackage { |
|
282 | amqplib = super.buildPythonPackage { | |
283 | name = "amqplib-1.0.2"; |
|
283 | name = "amqplib-1.0.2"; | |
284 | buildInputs = with self; []; |
|
284 | buildInputs = with self; []; | |
285 | doCheck = false; |
|
285 | doCheck = false; | |
286 | propagatedBuildInputs = with self; []; |
|
286 | propagatedBuildInputs = with self; []; | |
287 | src = fetchurl { |
|
287 | src = fetchurl { | |
288 | url = "https://pypi.python.org/packages/75/b7/8c2429bf8d92354a0118614f9a4d15e53bc69ebedce534284111de5a0102/amqplib-1.0.2.tgz"; |
|
288 | url = "https://pypi.python.org/packages/75/b7/8c2429bf8d92354a0118614f9a4d15e53bc69ebedce534284111de5a0102/amqplib-1.0.2.tgz"; | |
289 | md5 = "5c92f17fbedd99b2b4a836d4352d1e2f"; |
|
289 | md5 = "5c92f17fbedd99b2b4a836d4352d1e2f"; | |
290 | }; |
|
290 | }; | |
291 | }; |
|
291 | }; | |
292 | anyjson = super.buildPythonPackage { |
|
292 | anyjson = super.buildPythonPackage { | |
293 | name = "anyjson-0.3.3"; |
|
293 | name = "anyjson-0.3.3"; | |
294 | buildInputs = with self; []; |
|
294 | buildInputs = with self; []; | |
295 | doCheck = false; |
|
295 | doCheck = false; | |
296 | propagatedBuildInputs = with self; []; |
|
296 | propagatedBuildInputs = with self; []; | |
297 | src = fetchurl { |
|
297 | src = fetchurl { | |
298 | url = "https://pypi.python.org/packages/c3/4d/d4089e1a3dd25b46bebdb55a992b0797cff657b4477bc32ce28038fdecbc/anyjson-0.3.3.tar.gz"; |
|
298 | url = "https://pypi.python.org/packages/c3/4d/d4089e1a3dd25b46bebdb55a992b0797cff657b4477bc32ce28038fdecbc/anyjson-0.3.3.tar.gz"; | |
299 | md5 = "2ea28d6ec311aeeebaf993cb3008b27c"; |
|
299 | md5 = "2ea28d6ec311aeeebaf993cb3008b27c"; | |
300 | }; |
|
300 | }; | |
301 | }; |
|
301 | }; | |
302 | appenlight-client = super.buildPythonPackage { |
|
302 | appenlight-client = super.buildPythonPackage { | |
303 | name = "appenlight-client-0.6.14"; |
|
303 | name = "appenlight-client-0.6.14"; | |
304 | buildInputs = with self; []; |
|
304 | buildInputs = with self; []; | |
305 | doCheck = false; |
|
305 | doCheck = false; | |
306 | propagatedBuildInputs = with self; [WebOb requests]; |
|
306 | propagatedBuildInputs = with self; [WebOb requests]; | |
307 | src = fetchurl { |
|
307 | src = fetchurl { | |
308 | url = "https://pypi.python.org/packages/4d/e0/23fee3ebada8143f707e65c06bcb82992040ee64ea8355e044ed55ebf0c1/appenlight_client-0.6.14.tar.gz"; |
|
308 | url = "https://pypi.python.org/packages/4d/e0/23fee3ebada8143f707e65c06bcb82992040ee64ea8355e044ed55ebf0c1/appenlight_client-0.6.14.tar.gz"; | |
309 | md5 = "578c69b09f4356d898fff1199b98a95c"; |
|
309 | md5 = "578c69b09f4356d898fff1199b98a95c"; | |
310 | }; |
|
310 | }; | |
311 | }; |
|
311 | }; | |
312 | authomatic = super.buildPythonPackage { |
|
312 | authomatic = super.buildPythonPackage { | |
313 | name = "authomatic-0.1.0.post1"; |
|
313 | name = "authomatic-0.1.0.post1"; | |
314 | buildInputs = with self; []; |
|
314 | buildInputs = with self; []; | |
315 | doCheck = false; |
|
315 | doCheck = false; | |
316 | propagatedBuildInputs = with self; []; |
|
316 | propagatedBuildInputs = with self; []; | |
317 | src = fetchurl { |
|
317 | src = fetchurl { | |
318 | url = "https://pypi.python.org/packages/08/1a/8a930461e604c2d5a7a871e1ac59fa82ccf994c32e807230c8d2fb07815a/Authomatic-0.1.0.post1.tar.gz"; |
|
318 | url = "https://pypi.python.org/packages/08/1a/8a930461e604c2d5a7a871e1ac59fa82ccf994c32e807230c8d2fb07815a/Authomatic-0.1.0.post1.tar.gz"; | |
319 | md5 = "be3f3ce08747d776aae6d6cc8dcb49a9"; |
|
319 | md5 = "be3f3ce08747d776aae6d6cc8dcb49a9"; | |
320 | }; |
|
320 | }; | |
321 | }; |
|
321 | }; | |
322 | backport-ipaddress = super.buildPythonPackage { |
|
322 | backport-ipaddress = super.buildPythonPackage { | |
323 | name = "backport-ipaddress-0.1"; |
|
323 | name = "backport-ipaddress-0.1"; | |
324 | buildInputs = with self; []; |
|
324 | buildInputs = with self; []; | |
325 | doCheck = false; |
|
325 | doCheck = false; | |
326 | propagatedBuildInputs = with self; []; |
|
326 | propagatedBuildInputs = with self; []; | |
327 | src = fetchurl { |
|
327 | src = fetchurl { | |
328 | url = "https://pypi.python.org/packages/d3/30/54c6dab05a4dec44db25ff309f1fbb6b7a8bde3f2bade38bb9da67bbab8f/backport_ipaddress-0.1.tar.gz"; |
|
328 | url = "https://pypi.python.org/packages/d3/30/54c6dab05a4dec44db25ff309f1fbb6b7a8bde3f2bade38bb9da67bbab8f/backport_ipaddress-0.1.tar.gz"; | |
329 | md5 = "9c1f45f4361f71b124d7293a60006c05"; |
|
329 | md5 = "9c1f45f4361f71b124d7293a60006c05"; | |
330 | }; |
|
330 | }; | |
331 | }; |
|
331 | }; | |
332 | bottle = super.buildPythonPackage { |
|
332 | bottle = super.buildPythonPackage { | |
333 | name = "bottle-0.12.8"; |
|
333 | name = "bottle-0.12.8"; | |
334 | buildInputs = with self; []; |
|
334 | buildInputs = with self; []; | |
335 | doCheck = false; |
|
335 | doCheck = false; | |
336 | propagatedBuildInputs = with self; []; |
|
336 | propagatedBuildInputs = with self; []; | |
337 | src = fetchurl { |
|
337 | src = fetchurl { | |
338 | url = "https://pypi.python.org/packages/52/df/e4a408f3a7af396d186d4ecd3b389dd764f0f943b4fa8d257bfe7b49d343/bottle-0.12.8.tar.gz"; |
|
338 | url = "https://pypi.python.org/packages/52/df/e4a408f3a7af396d186d4ecd3b389dd764f0f943b4fa8d257bfe7b49d343/bottle-0.12.8.tar.gz"; | |
339 | md5 = "13132c0a8f607bf860810a6ee9064c5b"; |
|
339 | md5 = "13132c0a8f607bf860810a6ee9064c5b"; | |
340 | }; |
|
340 | }; | |
341 | }; |
|
341 | }; | |
342 | bumpversion = super.buildPythonPackage { |
|
342 | bumpversion = super.buildPythonPackage { | |
343 | name = "bumpversion-0.5.3"; |
|
343 | name = "bumpversion-0.5.3"; | |
344 | buildInputs = with self; []; |
|
344 | buildInputs = with self; []; | |
345 | doCheck = false; |
|
345 | doCheck = false; | |
346 | propagatedBuildInputs = with self; []; |
|
346 | propagatedBuildInputs = with self; []; | |
347 | src = fetchurl { |
|
347 | src = fetchurl { | |
348 | url = "https://pypi.python.org/packages/14/41/8c9da3549f8e00c84f0432c3a8cf8ed6898374714676aab91501d48760db/bumpversion-0.5.3.tar.gz"; |
|
348 | url = "https://pypi.python.org/packages/14/41/8c9da3549f8e00c84f0432c3a8cf8ed6898374714676aab91501d48760db/bumpversion-0.5.3.tar.gz"; | |
349 | md5 = "c66a3492eafcf5ad4b024be9fca29820"; |
|
349 | md5 = "c66a3492eafcf5ad4b024be9fca29820"; | |
350 | }; |
|
350 | }; | |
351 | }; |
|
351 | }; | |
352 | celery = super.buildPythonPackage { |
|
352 | celery = super.buildPythonPackage { | |
353 | name = "celery-2.2.10"; |
|
353 | name = "celery-2.2.10"; | |
354 | buildInputs = with self; []; |
|
354 | buildInputs = with self; []; | |
355 | doCheck = false; |
|
355 | doCheck = false; | |
356 | propagatedBuildInputs = with self; [python-dateutil anyjson kombu pyparsing]; |
|
356 | propagatedBuildInputs = with self; [python-dateutil anyjson kombu pyparsing]; | |
357 | src = fetchurl { |
|
357 | src = fetchurl { | |
358 | url = "https://pypi.python.org/packages/b1/64/860fd50e45844c83442e7953effcddeff66b2851d90b2d784f7201c111b8/celery-2.2.10.tar.gz"; |
|
358 | url = "https://pypi.python.org/packages/b1/64/860fd50e45844c83442e7953effcddeff66b2851d90b2d784f7201c111b8/celery-2.2.10.tar.gz"; | |
359 | md5 = "898bc87e54f278055b561316ba73e222"; |
|
359 | md5 = "898bc87e54f278055b561316ba73e222"; | |
360 | }; |
|
360 | }; | |
361 | }; |
|
361 | }; | |
362 | certifi = super.buildPythonPackage { |
|
362 | certifi = super.buildPythonPackage { | |
363 |
name = "certifi-2016. |
|
363 | name = "certifi-2016.2.28"; | |
364 | buildInputs = with self; []; |
|
364 | buildInputs = with self; []; | |
365 | doCheck = false; |
|
365 | doCheck = false; | |
366 | propagatedBuildInputs = with self; []; |
|
366 | propagatedBuildInputs = with self; []; | |
367 | src = fetchurl { |
|
367 | src = fetchurl { | |
368 | url = "https://pypi.python.org/packages/5c/f8/f6c54727c74579c6bbe5926f5deb9677c5810a33e11da58d1a4e2d09d041/certifi-2016.2.28.tar.gz"; |
|
368 | url = "https://pypi.python.org/packages/5c/f8/f6c54727c74579c6bbe5926f5deb9677c5810a33e11da58d1a4e2d09d041/certifi-2016.2.28.tar.gz"; | |
369 | md5 = "5d672aa766e1f773c75cfeccd02d3650"; |
|
369 | md5 = "5d672aa766e1f773c75cfeccd02d3650"; | |
370 | }; |
|
370 | }; | |
371 | }; |
|
371 | }; | |
372 | click = super.buildPythonPackage { |
|
372 | click = super.buildPythonPackage { | |
373 | name = "click-5.1"; |
|
373 | name = "click-5.1"; | |
374 | buildInputs = with self; []; |
|
374 | buildInputs = with self; []; | |
375 | doCheck = false; |
|
375 | doCheck = false; | |
376 | propagatedBuildInputs = with self; []; |
|
376 | propagatedBuildInputs = with self; []; | |
377 | src = fetchurl { |
|
377 | src = fetchurl { | |
378 | url = "https://pypi.python.org/packages/b7/34/a496632c4fb6c1ee76efedf77bb8d28b29363d839953d95095b12defe791/click-5.1.tar.gz"; |
|
378 | url = "https://pypi.python.org/packages/b7/34/a496632c4fb6c1ee76efedf77bb8d28b29363d839953d95095b12defe791/click-5.1.tar.gz"; | |
379 | md5 = "9c5323008cccfe232a8b161fc8196d41"; |
|
379 | md5 = "9c5323008cccfe232a8b161fc8196d41"; | |
380 | }; |
|
380 | }; | |
381 | }; |
|
381 | }; | |
382 | colander = super.buildPythonPackage { |
|
382 | colander = super.buildPythonPackage { | |
383 | name = "colander-1.2"; |
|
383 | name = "colander-1.2"; | |
384 | buildInputs = with self; []; |
|
384 | buildInputs = with self; []; | |
385 | doCheck = false; |
|
385 | doCheck = false; | |
386 | propagatedBuildInputs = with self; [translationstring iso8601]; |
|
386 | propagatedBuildInputs = with self; [translationstring iso8601]; | |
387 | src = fetchurl { |
|
387 | src = fetchurl { | |
388 | url = "https://pypi.python.org/packages/14/23/c9ceba07a6a1dc0eefbb215fc0dc64aabc2b22ee756bc0f0c13278fa0887/colander-1.2.tar.gz"; |
|
388 | url = "https://pypi.python.org/packages/14/23/c9ceba07a6a1dc0eefbb215fc0dc64aabc2b22ee756bc0f0c13278fa0887/colander-1.2.tar.gz"; | |
389 | md5 = "83db21b07936a0726e588dae1914b9ed"; |
|
389 | md5 = "83db21b07936a0726e588dae1914b9ed"; | |
390 | }; |
|
390 | }; | |
391 | }; |
|
391 | }; | |
392 | configobj = super.buildPythonPackage { |
|
392 | configobj = super.buildPythonPackage { | |
393 | name = "configobj-5.0.6"; |
|
393 | name = "configobj-5.0.6"; | |
394 | buildInputs = with self; []; |
|
394 | buildInputs = with self; []; | |
395 | doCheck = false; |
|
395 | doCheck = false; | |
396 | propagatedBuildInputs = with self; [six]; |
|
396 | propagatedBuildInputs = with self; [six]; | |
397 | src = fetchurl { |
|
397 | src = fetchurl { | |
398 | url = "https://pypi.python.org/packages/64/61/079eb60459c44929e684fa7d9e2fdca403f67d64dd9dbac27296be2e0fab/configobj-5.0.6.tar.gz"; |
|
398 | url = "https://pypi.python.org/packages/64/61/079eb60459c44929e684fa7d9e2fdca403f67d64dd9dbac27296be2e0fab/configobj-5.0.6.tar.gz"; | |
399 | md5 = "e472a3a1c2a67bb0ec9b5d54c13a47d6"; |
|
399 | md5 = "e472a3a1c2a67bb0ec9b5d54c13a47d6"; | |
400 | }; |
|
400 | }; | |
401 | }; |
|
401 | }; | |
402 | cov-core = super.buildPythonPackage { |
|
402 | cov-core = super.buildPythonPackage { | |
403 | name = "cov-core-1.15.0"; |
|
403 | name = "cov-core-1.15.0"; | |
404 | buildInputs = with self; []; |
|
404 | buildInputs = with self; []; | |
405 | doCheck = false; |
|
405 | doCheck = false; | |
406 | propagatedBuildInputs = with self; [coverage]; |
|
406 | propagatedBuildInputs = with self; [coverage]; | |
407 | src = fetchurl { |
|
407 | src = fetchurl { | |
408 | url = "https://pypi.python.org/packages/4b/87/13e75a47b4ba1be06f29f6d807ca99638bedc6b57fa491cd3de891ca2923/cov-core-1.15.0.tar.gz"; |
|
408 | url = "https://pypi.python.org/packages/4b/87/13e75a47b4ba1be06f29f6d807ca99638bedc6b57fa491cd3de891ca2923/cov-core-1.15.0.tar.gz"; | |
409 | md5 = "f519d4cb4c4e52856afb14af52919fe6"; |
|
409 | md5 = "f519d4cb4c4e52856afb14af52919fe6"; | |
410 | }; |
|
410 | }; | |
411 | }; |
|
411 | }; | |
412 | coverage = super.buildPythonPackage { |
|
412 | coverage = super.buildPythonPackage { | |
413 | name = "coverage-3.7.1"; |
|
413 | name = "coverage-3.7.1"; | |
414 | buildInputs = with self; []; |
|
414 | buildInputs = with self; []; | |
415 | doCheck = false; |
|
415 | doCheck = false; | |
416 | propagatedBuildInputs = with self; []; |
|
416 | propagatedBuildInputs = with self; []; | |
417 | src = fetchurl { |
|
417 | src = fetchurl { | |
418 | url = "https://pypi.python.org/packages/09/4f/89b06c7fdc09687bca507dc411c342556ef9c5a3b26756137a4878ff19bf/coverage-3.7.1.tar.gz"; |
|
418 | url = "https://pypi.python.org/packages/09/4f/89b06c7fdc09687bca507dc411c342556ef9c5a3b26756137a4878ff19bf/coverage-3.7.1.tar.gz"; | |
419 | md5 = "c47b36ceb17eaff3ecfab3bcd347d0df"; |
|
419 | md5 = "c47b36ceb17eaff3ecfab3bcd347d0df"; | |
420 | }; |
|
420 | }; | |
421 | }; |
|
421 | }; | |
422 | cssselect = super.buildPythonPackage { |
|
422 | cssselect = super.buildPythonPackage { | |
423 | name = "cssselect-0.9.1"; |
|
423 | name = "cssselect-0.9.1"; | |
424 | buildInputs = with self; []; |
|
424 | buildInputs = with self; []; | |
425 | doCheck = false; |
|
425 | doCheck = false; | |
426 | propagatedBuildInputs = with self; []; |
|
426 | propagatedBuildInputs = with self; []; | |
427 | src = fetchurl { |
|
427 | src = fetchurl { | |
428 | url = "https://pypi.python.org/packages/aa/e5/9ee1460d485b94a6d55732eb7ad5b6c084caf73dd6f9cb0bb7d2a78fafe8/cssselect-0.9.1.tar.gz"; |
|
428 | url = "https://pypi.python.org/packages/aa/e5/9ee1460d485b94a6d55732eb7ad5b6c084caf73dd6f9cb0bb7d2a78fafe8/cssselect-0.9.1.tar.gz"; | |
429 | md5 = "c74f45966277dc7a0f768b9b0f3522ac"; |
|
429 | md5 = "c74f45966277dc7a0f768b9b0f3522ac"; | |
430 | }; |
|
430 | }; | |
431 | }; |
|
431 | }; | |
432 | decorator = super.buildPythonPackage { |
|
432 | decorator = super.buildPythonPackage { | |
433 | name = "decorator-3.4.2"; |
|
433 | name = "decorator-3.4.2"; | |
434 | buildInputs = with self; []; |
|
434 | buildInputs = with self; []; | |
435 | doCheck = false; |
|
435 | doCheck = false; | |
436 | propagatedBuildInputs = with self; []; |
|
436 | propagatedBuildInputs = with self; []; | |
437 | src = fetchurl { |
|
437 | src = fetchurl { | |
438 | url = "https://pypi.python.org/packages/35/3a/42566eb7a2cbac774399871af04e11d7ae3fc2579e7dae85213b8d1d1c57/decorator-3.4.2.tar.gz"; |
|
438 | url = "https://pypi.python.org/packages/35/3a/42566eb7a2cbac774399871af04e11d7ae3fc2579e7dae85213b8d1d1c57/decorator-3.4.2.tar.gz"; | |
439 | md5 = "9e0536870d2b83ae27d58dbf22582f4d"; |
|
439 | md5 = "9e0536870d2b83ae27d58dbf22582f4d"; | |
440 | }; |
|
440 | }; | |
441 | }; |
|
441 | }; | |
442 | docutils = super.buildPythonPackage { |
|
442 | docutils = super.buildPythonPackage { | |
443 | name = "docutils-0.12"; |
|
443 | name = "docutils-0.12"; | |
444 | buildInputs = with self; []; |
|
444 | buildInputs = with self; []; | |
445 | doCheck = false; |
|
445 | doCheck = false; | |
446 | propagatedBuildInputs = with self; []; |
|
446 | propagatedBuildInputs = with self; []; | |
447 | src = fetchurl { |
|
447 | src = fetchurl { | |
448 | url = "https://pypi.python.org/packages/37/38/ceda70135b9144d84884ae2fc5886c6baac4edea39550f28bcd144c1234d/docutils-0.12.tar.gz"; |
|
448 | url = "https://pypi.python.org/packages/37/38/ceda70135b9144d84884ae2fc5886c6baac4edea39550f28bcd144c1234d/docutils-0.12.tar.gz"; | |
449 | md5 = "4622263b62c5c771c03502afa3157768"; |
|
449 | md5 = "4622263b62c5c771c03502afa3157768"; | |
450 | }; |
|
450 | }; | |
451 | }; |
|
451 | }; | |
452 | dogpile.cache = super.buildPythonPackage { |
|
452 | dogpile.cache = super.buildPythonPackage { | |
453 | name = "dogpile.cache-0.5.7"; |
|
453 | name = "dogpile.cache-0.5.7"; | |
454 | buildInputs = with self; []; |
|
454 | buildInputs = with self; []; | |
455 | doCheck = false; |
|
455 | doCheck = false; | |
456 | propagatedBuildInputs = with self; [dogpile.core]; |
|
456 | propagatedBuildInputs = with self; [dogpile.core]; | |
457 | src = fetchurl { |
|
457 | src = fetchurl { | |
458 | url = "https://pypi.python.org/packages/07/74/2a83bedf758156d9c95d112691bbad870d3b77ccbcfb781b4ef836ea7d96/dogpile.cache-0.5.7.tar.gz"; |
|
458 | url = "https://pypi.python.org/packages/07/74/2a83bedf758156d9c95d112691bbad870d3b77ccbcfb781b4ef836ea7d96/dogpile.cache-0.5.7.tar.gz"; | |
459 | md5 = "3e58ce41af574aab41d78e9c4190f194"; |
|
459 | md5 = "3e58ce41af574aab41d78e9c4190f194"; | |
460 | }; |
|
460 | }; | |
461 | }; |
|
461 | }; | |
462 | dogpile.core = super.buildPythonPackage { |
|
462 | dogpile.core = super.buildPythonPackage { | |
463 | name = "dogpile.core-0.4.1"; |
|
463 | name = "dogpile.core-0.4.1"; | |
464 | buildInputs = with self; []; |
|
464 | buildInputs = with self; []; | |
465 | doCheck = false; |
|
465 | doCheck = false; | |
466 | propagatedBuildInputs = with self; []; |
|
466 | propagatedBuildInputs = with self; []; | |
467 | src = fetchurl { |
|
467 | src = fetchurl { | |
468 | url = "https://pypi.python.org/packages/0e/77/e72abc04c22aedf874301861e5c1e761231c288b5de369c18be8f4b5c9bb/dogpile.core-0.4.1.tar.gz"; |
|
468 | url = "https://pypi.python.org/packages/0e/77/e72abc04c22aedf874301861e5c1e761231c288b5de369c18be8f4b5c9bb/dogpile.core-0.4.1.tar.gz"; | |
469 | md5 = "01cb19f52bba3e95c9b560f39341f045"; |
|
469 | md5 = "01cb19f52bba3e95c9b560f39341f045"; | |
470 | }; |
|
470 | }; | |
471 | }; |
|
471 | }; | |
472 | dulwich = super.buildPythonPackage { |
|
472 | dulwich = super.buildPythonPackage { | |
473 | name = "dulwich-0.12.0"; |
|
473 | name = "dulwich-0.12.0"; | |
474 | buildInputs = with self; []; |
|
474 | buildInputs = with self; []; | |
475 | doCheck = false; |
|
475 | doCheck = false; | |
476 | propagatedBuildInputs = with self; []; |
|
476 | propagatedBuildInputs = with self; []; | |
477 | src = fetchurl { |
|
477 | src = fetchurl { | |
478 | url = "https://pypi.python.org/packages/6f/04/fbe561b6d45c0ec758330d5b7f5ba4b6cb4f1ca1ab49859d2fc16320da75/dulwich-0.12.0.tar.gz"; |
|
478 | url = "https://pypi.python.org/packages/6f/04/fbe561b6d45c0ec758330d5b7f5ba4b6cb4f1ca1ab49859d2fc16320da75/dulwich-0.12.0.tar.gz"; | |
479 | md5 = "f3a8a12bd9f9dd8c233e18f3d49436fa"; |
|
479 | md5 = "f3a8a12bd9f9dd8c233e18f3d49436fa"; | |
480 | }; |
|
480 | }; | |
481 | }; |
|
481 | }; | |
482 | ecdsa = super.buildPythonPackage { |
|
482 | ecdsa = super.buildPythonPackage { | |
483 | name = "ecdsa-0.11"; |
|
483 | name = "ecdsa-0.11"; | |
484 | buildInputs = with self; []; |
|
484 | buildInputs = with self; []; | |
485 | doCheck = false; |
|
485 | doCheck = false; | |
486 | propagatedBuildInputs = with self; []; |
|
486 | propagatedBuildInputs = with self; []; | |
487 | src = fetchurl { |
|
487 | src = fetchurl { | |
488 | url = "https://pypi.python.org/packages/6c/3f/92fe5dcdcaa7bd117be21e5520c9a54375112b66ec000d209e9e9519fad1/ecdsa-0.11.tar.gz"; |
|
488 | url = "https://pypi.python.org/packages/6c/3f/92fe5dcdcaa7bd117be21e5520c9a54375112b66ec000d209e9e9519fad1/ecdsa-0.11.tar.gz"; | |
489 | md5 = "8ef586fe4dbb156697d756900cb41d7c"; |
|
489 | md5 = "8ef586fe4dbb156697d756900cb41d7c"; | |
490 | }; |
|
490 | }; | |
491 | }; |
|
491 | }; | |
492 | elasticsearch = super.buildPythonPackage { |
|
492 | elasticsearch = super.buildPythonPackage { | |
493 | name = "elasticsearch-1.9.0"; |
|
493 | name = "elasticsearch-1.9.0"; | |
494 | buildInputs = with self; []; |
|
494 | buildInputs = with self; []; | |
495 | doCheck = false; |
|
495 | doCheck = false; | |
496 | propagatedBuildInputs = with self; [urllib3]; |
|
496 | propagatedBuildInputs = with self; [urllib3]; | |
497 | src = fetchurl { |
|
497 | src = fetchurl { | |
498 | url = "https://pypi.python.org/packages/13/9b/540e311b31a10c2a904acfb08030c656047e5c7ba479d35df2799e5dccfe/elasticsearch-1.9.0.tar.gz"; |
|
498 | url = "https://pypi.python.org/packages/13/9b/540e311b31a10c2a904acfb08030c656047e5c7ba479d35df2799e5dccfe/elasticsearch-1.9.0.tar.gz"; | |
499 | md5 = "3550390baea1639479f79758d66ab032"; |
|
499 | md5 = "3550390baea1639479f79758d66ab032"; | |
500 | }; |
|
500 | }; | |
501 | }; |
|
501 | }; | |
502 | flake8 = super.buildPythonPackage { |
|
502 | flake8 = super.buildPythonPackage { | |
503 | name = "flake8-2.4.1"; |
|
503 | name = "flake8-2.4.1"; | |
504 | buildInputs = with self; []; |
|
504 | buildInputs = with self; []; | |
505 | doCheck = false; |
|
505 | doCheck = false; | |
506 | propagatedBuildInputs = with self; [pyflakes pep8 mccabe]; |
|
506 | propagatedBuildInputs = with self; [pyflakes pep8 mccabe]; | |
507 | src = fetchurl { |
|
507 | src = fetchurl { | |
508 | url = "https://pypi.python.org/packages/8f/b5/9a73c66c7dba273bac8758398f060c008a25f3e84531063b42503b5d0a95/flake8-2.4.1.tar.gz"; |
|
508 | url = "https://pypi.python.org/packages/8f/b5/9a73c66c7dba273bac8758398f060c008a25f3e84531063b42503b5d0a95/flake8-2.4.1.tar.gz"; | |
509 | md5 = "ed45d3db81a3b7c88bd63c6e37ca1d65"; |
|
509 | md5 = "ed45d3db81a3b7c88bd63c6e37ca1d65"; | |
510 | }; |
|
510 | }; | |
511 | }; |
|
511 | }; | |
512 | future = super.buildPythonPackage { |
|
512 | future = super.buildPythonPackage { | |
513 | name = "future-0.14.3"; |
|
513 | name = "future-0.14.3"; | |
514 | buildInputs = with self; []; |
|
514 | buildInputs = with self; []; | |
515 | doCheck = false; |
|
515 | doCheck = false; | |
516 | propagatedBuildInputs = with self; []; |
|
516 | propagatedBuildInputs = with self; []; | |
517 | src = fetchurl { |
|
517 | src = fetchurl { | |
518 | url = "https://pypi.python.org/packages/83/80/8ef3a11a15f8eaafafa0937b20c1b3f73527e69ab6b3fa1cf94a5a96aabb/future-0.14.3.tar.gz"; |
|
518 | url = "https://pypi.python.org/packages/83/80/8ef3a11a15f8eaafafa0937b20c1b3f73527e69ab6b3fa1cf94a5a96aabb/future-0.14.3.tar.gz"; | |
519 | md5 = "e94079b0bd1fc054929e8769fc0f6083"; |
|
519 | md5 = "e94079b0bd1fc054929e8769fc0f6083"; | |
520 | }; |
|
520 | }; | |
521 | }; |
|
521 | }; | |
522 | futures = super.buildPythonPackage { |
|
522 | futures = super.buildPythonPackage { | |
523 | name = "futures-3.0.2"; |
|
523 | name = "futures-3.0.2"; | |
524 | buildInputs = with self; []; |
|
524 | buildInputs = with self; []; | |
525 | doCheck = false; |
|
525 | doCheck = false; | |
526 | propagatedBuildInputs = with self; []; |
|
526 | propagatedBuildInputs = with self; []; | |
527 | src = fetchurl { |
|
527 | src = fetchurl { | |
528 | url = "https://pypi.python.org/packages/f8/e7/fc0fcbeb9193ba2d4de00b065e7fd5aecd0679e93ce95a07322b2b1434f4/futures-3.0.2.tar.gz"; |
|
528 | url = "https://pypi.python.org/packages/f8/e7/fc0fcbeb9193ba2d4de00b065e7fd5aecd0679e93ce95a07322b2b1434f4/futures-3.0.2.tar.gz"; | |
529 | md5 = "42aaf1e4de48d6e871d77dc1f9d96d5a"; |
|
529 | md5 = "42aaf1e4de48d6e871d77dc1f9d96d5a"; | |
530 | }; |
|
530 | }; | |
531 | }; |
|
531 | }; | |
532 | gnureadline = super.buildPythonPackage { |
|
532 | gnureadline = super.buildPythonPackage { | |
533 | name = "gnureadline-6.3.3"; |
|
533 | name = "gnureadline-6.3.3"; | |
534 | buildInputs = with self; []; |
|
534 | buildInputs = with self; []; | |
535 | doCheck = false; |
|
535 | doCheck = false; | |
536 | propagatedBuildInputs = with self; []; |
|
536 | propagatedBuildInputs = with self; []; | |
537 | src = fetchurl { |
|
537 | src = fetchurl { | |
538 | url = "https://pypi.python.org/packages/3a/ee/2c3f568b0a74974791ac590ec742ef6133e2fbd287a074ba72a53fa5e97c/gnureadline-6.3.3.tar.gz"; |
|
538 | url = "https://pypi.python.org/packages/3a/ee/2c3f568b0a74974791ac590ec742ef6133e2fbd287a074ba72a53fa5e97c/gnureadline-6.3.3.tar.gz"; | |
539 | md5 = "c4af83c9a3fbeac8f2da9b5a7c60e51c"; |
|
539 | md5 = "c4af83c9a3fbeac8f2da9b5a7c60e51c"; | |
540 | }; |
|
540 | }; | |
541 | }; |
|
541 | }; | |
542 | gprof2dot = super.buildPythonPackage { |
|
542 | gprof2dot = super.buildPythonPackage { | |
543 | name = "gprof2dot-2015.12.1"; |
|
543 | name = "gprof2dot-2015.12.1"; | |
544 | buildInputs = with self; []; |
|
544 | buildInputs = with self; []; | |
545 | doCheck = false; |
|
545 | doCheck = false; | |
546 | propagatedBuildInputs = with self; []; |
|
546 | propagatedBuildInputs = with self; []; | |
547 | src = fetchurl { |
|
547 | src = fetchurl { | |
548 | url = "https://pypi.python.org/packages/b9/34/7bf93c1952d40fa5c95ad963f4d8344b61ef58558632402eca18e6c14127/gprof2dot-2015.12.1.tar.gz"; |
|
548 | url = "https://pypi.python.org/packages/b9/34/7bf93c1952d40fa5c95ad963f4d8344b61ef58558632402eca18e6c14127/gprof2dot-2015.12.1.tar.gz"; | |
549 | md5 = "e23bf4e2f94db032750c193384b4165b"; |
|
549 | md5 = "e23bf4e2f94db032750c193384b4165b"; | |
550 | }; |
|
550 | }; | |
551 | }; |
|
551 | }; | |
552 | greenlet = super.buildPythonPackage { |
|
552 | greenlet = super.buildPythonPackage { | |
553 | name = "greenlet-0.4.7"; |
|
553 | name = "greenlet-0.4.7"; | |
554 | buildInputs = with self; []; |
|
554 | buildInputs = with self; []; | |
555 | doCheck = false; |
|
555 | doCheck = false; | |
556 | propagatedBuildInputs = with self; []; |
|
556 | propagatedBuildInputs = with self; []; | |
557 | src = fetchurl { |
|
557 | src = fetchurl { | |
558 | url = "https://pypi.python.org/packages/7a/9f/a1a0d9bdf3203ae1502c5a8434fe89d323599d78a106985bc327351a69d4/greenlet-0.4.7.zip"; |
|
558 | url = "https://pypi.python.org/packages/7a/9f/a1a0d9bdf3203ae1502c5a8434fe89d323599d78a106985bc327351a69d4/greenlet-0.4.7.zip"; | |
559 | md5 = "c2333a8ff30fa75c5d5ec0e67b461086"; |
|
559 | md5 = "c2333a8ff30fa75c5d5ec0e67b461086"; | |
560 | }; |
|
560 | }; | |
561 | }; |
|
561 | }; | |
562 | gunicorn = super.buildPythonPackage { |
|
562 | gunicorn = super.buildPythonPackage { | |
563 | name = "gunicorn-19.6.0"; |
|
563 | name = "gunicorn-19.6.0"; | |
564 | buildInputs = with self; []; |
|
564 | buildInputs = with self; []; | |
565 | doCheck = false; |
|
565 | doCheck = false; | |
566 | propagatedBuildInputs = with self; []; |
|
566 | propagatedBuildInputs = with self; []; | |
567 | src = fetchurl { |
|
567 | src = fetchurl { | |
568 | url = "https://pypi.python.org/packages/84/ce/7ea5396efad1cef682bbc4068e72a0276341d9d9d0f501da609fab9fcb80/gunicorn-19.6.0.tar.gz"; |
|
568 | url = "https://pypi.python.org/packages/84/ce/7ea5396efad1cef682bbc4068e72a0276341d9d9d0f501da609fab9fcb80/gunicorn-19.6.0.tar.gz"; | |
569 | md5 = "338e5e8a83ea0f0625f768dba4597530"; |
|
569 | md5 = "338e5e8a83ea0f0625f768dba4597530"; | |
570 | }; |
|
570 | }; | |
571 | }; |
|
571 | }; | |
572 | infrae.cache = super.buildPythonPackage { |
|
572 | infrae.cache = super.buildPythonPackage { | |
573 | name = "infrae.cache-1.0.1"; |
|
573 | name = "infrae.cache-1.0.1"; | |
574 | buildInputs = with self; []; |
|
574 | buildInputs = with self; []; | |
575 | doCheck = false; |
|
575 | doCheck = false; | |
576 | propagatedBuildInputs = with self; [Beaker repoze.lru]; |
|
576 | propagatedBuildInputs = with self; [Beaker repoze.lru]; | |
577 | src = fetchurl { |
|
577 | src = fetchurl { | |
578 | url = "https://pypi.python.org/packages/bb/f0/e7d5e984cf6592fd2807dc7bc44a93f9d18e04e6a61f87fdfb2622422d74/infrae.cache-1.0.1.tar.gz"; |
|
578 | url = "https://pypi.python.org/packages/bb/f0/e7d5e984cf6592fd2807dc7bc44a93f9d18e04e6a61f87fdfb2622422d74/infrae.cache-1.0.1.tar.gz"; | |
579 | md5 = "b09076a766747e6ed2a755cc62088e32"; |
|
579 | md5 = "b09076a766747e6ed2a755cc62088e32"; | |
580 | }; |
|
580 | }; | |
581 | }; |
|
581 | }; | |
582 | invoke = super.buildPythonPackage { |
|
582 | invoke = super.buildPythonPackage { | |
583 | name = "invoke-0.11.1"; |
|
583 | name = "invoke-0.11.1"; | |
584 | buildInputs = with self; []; |
|
584 | buildInputs = with self; []; | |
585 | doCheck = false; |
|
585 | doCheck = false; | |
586 | propagatedBuildInputs = with self; []; |
|
586 | propagatedBuildInputs = with self; []; | |
587 | src = fetchurl { |
|
587 | src = fetchurl { | |
588 | url = "https://pypi.python.org/packages/d3/bb/36a5558ea19882073def7b0edeef4a0e6282056fed96506dd10b1d532bd4/invoke-0.11.1.tar.gz"; |
|
588 | url = "https://pypi.python.org/packages/d3/bb/36a5558ea19882073def7b0edeef4a0e6282056fed96506dd10b1d532bd4/invoke-0.11.1.tar.gz"; | |
589 | md5 = "3d4ecbe26779ceef1046ecf702c9c4a8"; |
|
589 | md5 = "3d4ecbe26779ceef1046ecf702c9c4a8"; | |
590 | }; |
|
590 | }; | |
591 | }; |
|
591 | }; | |
592 | ipdb = super.buildPythonPackage { |
|
592 | ipdb = super.buildPythonPackage { | |
593 | name = "ipdb-0.8"; |
|
593 | name = "ipdb-0.8"; | |
594 | buildInputs = with self; []; |
|
594 | buildInputs = with self; []; | |
595 | doCheck = false; |
|
595 | doCheck = false; | |
596 | propagatedBuildInputs = with self; [ipython]; |
|
596 | propagatedBuildInputs = with self; [ipython]; | |
597 | src = fetchurl { |
|
597 | src = fetchurl { | |
598 | url = "https://pypi.python.org/packages/f0/25/d7dd430ced6cd8dc242a933c8682b5dbf32eb4011d82f87e34209e5ec845/ipdb-0.8.zip"; |
|
598 | url = "https://pypi.python.org/packages/f0/25/d7dd430ced6cd8dc242a933c8682b5dbf32eb4011d82f87e34209e5ec845/ipdb-0.8.zip"; | |
599 | md5 = "96dca0712efa01aa5eaf6b22071dd3ed"; |
|
599 | md5 = "96dca0712efa01aa5eaf6b22071dd3ed"; | |
600 | }; |
|
600 | }; | |
601 | }; |
|
601 | }; | |
602 | ipython = super.buildPythonPackage { |
|
602 | ipython = super.buildPythonPackage { | |
603 | name = "ipython-3.1.0"; |
|
603 | name = "ipython-3.1.0"; | |
604 | buildInputs = with self; []; |
|
604 | buildInputs = with self; []; | |
605 | doCheck = false; |
|
605 | doCheck = false; | |
606 | propagatedBuildInputs = with self; [gnureadline]; |
|
606 | propagatedBuildInputs = with self; [gnureadline]; | |
607 | src = fetchurl { |
|
607 | src = fetchurl { | |
608 | url = "https://pypi.python.org/packages/06/91/120c0835254c120af89f066afaabf81289bc2726c1fc3ca0555df6882f58/ipython-3.1.0.tar.gz"; |
|
608 | url = "https://pypi.python.org/packages/06/91/120c0835254c120af89f066afaabf81289bc2726c1fc3ca0555df6882f58/ipython-3.1.0.tar.gz"; | |
609 | md5 = "a749d90c16068687b0ec45a27e72ef8f"; |
|
609 | md5 = "a749d90c16068687b0ec45a27e72ef8f"; | |
610 | }; |
|
610 | }; | |
611 | }; |
|
611 | }; | |
612 | iso8601 = super.buildPythonPackage { |
|
612 | iso8601 = super.buildPythonPackage { | |
613 | name = "iso8601-0.1.11"; |
|
613 | name = "iso8601-0.1.11"; | |
614 | buildInputs = with self; []; |
|
614 | buildInputs = with self; []; | |
615 | doCheck = false; |
|
615 | doCheck = false; | |
616 | propagatedBuildInputs = with self; []; |
|
616 | propagatedBuildInputs = with self; []; | |
617 | src = fetchurl { |
|
617 | src = fetchurl { | |
618 | url = "https://pypi.python.org/packages/c0/75/c9209ee4d1b5975eb8c2cba4428bde6b61bd55664a98290dd015cdb18e98/iso8601-0.1.11.tar.gz"; |
|
618 | url = "https://pypi.python.org/packages/c0/75/c9209ee4d1b5975eb8c2cba4428bde6b61bd55664a98290dd015cdb18e98/iso8601-0.1.11.tar.gz"; | |
619 | md5 = "b06d11cd14a64096f907086044f0fe38"; |
|
619 | md5 = "b06d11cd14a64096f907086044f0fe38"; | |
620 | }; |
|
620 | }; | |
621 | }; |
|
621 | }; | |
622 | itsdangerous = super.buildPythonPackage { |
|
622 | itsdangerous = super.buildPythonPackage { | |
623 | name = "itsdangerous-0.24"; |
|
623 | name = "itsdangerous-0.24"; | |
624 | buildInputs = with self; []; |
|
624 | buildInputs = with self; []; | |
625 | doCheck = false; |
|
625 | doCheck = false; | |
626 | propagatedBuildInputs = with self; []; |
|
626 | propagatedBuildInputs = with self; []; | |
627 | src = fetchurl { |
|
627 | src = fetchurl { | |
628 | url = "https://pypi.python.org/packages/dc/b4/a60bcdba945c00f6d608d8975131ab3f25b22f2bcfe1dab221165194b2d4/itsdangerous-0.24.tar.gz"; |
|
628 | url = "https://pypi.python.org/packages/dc/b4/a60bcdba945c00f6d608d8975131ab3f25b22f2bcfe1dab221165194b2d4/itsdangerous-0.24.tar.gz"; | |
629 | md5 = "a3d55aa79369aef5345c036a8a26307f"; |
|
629 | md5 = "a3d55aa79369aef5345c036a8a26307f"; | |
630 | }; |
|
630 | }; | |
631 | }; |
|
631 | }; | |
632 | kombu = super.buildPythonPackage { |
|
632 | kombu = super.buildPythonPackage { | |
633 | name = "kombu-1.5.1"; |
|
633 | name = "kombu-1.5.1"; | |
634 | buildInputs = with self; []; |
|
634 | buildInputs = with self; []; | |
635 | doCheck = false; |
|
635 | doCheck = false; | |
636 | propagatedBuildInputs = with self; [anyjson amqplib]; |
|
636 | propagatedBuildInputs = with self; [anyjson amqplib]; | |
637 | src = fetchurl { |
|
637 | src = fetchurl { | |
638 | url = "https://pypi.python.org/packages/19/53/74bf2a624644b45f0850a638752514fc10a8e1cbd738f10804951a6df3f5/kombu-1.5.1.tar.gz"; |
|
638 | url = "https://pypi.python.org/packages/19/53/74bf2a624644b45f0850a638752514fc10a8e1cbd738f10804951a6df3f5/kombu-1.5.1.tar.gz"; | |
639 | md5 = "50662f3c7e9395b3d0721fb75d100b63"; |
|
639 | md5 = "50662f3c7e9395b3d0721fb75d100b63"; | |
640 | }; |
|
640 | }; | |
641 | }; |
|
641 | }; | |
642 | lxml = super.buildPythonPackage { |
|
642 | lxml = super.buildPythonPackage { | |
643 | name = "lxml-3.4.4"; |
|
643 | name = "lxml-3.4.4"; | |
644 | buildInputs = with self; []; |
|
644 | buildInputs = with self; []; | |
645 | doCheck = false; |
|
645 | doCheck = false; | |
646 | propagatedBuildInputs = with self; []; |
|
646 | propagatedBuildInputs = with self; []; | |
647 | src = fetchurl { |
|
647 | src = fetchurl { | |
648 | url = "https://pypi.python.org/packages/63/c7/4f2a2a4ad6c6fa99b14be6b3c1cece9142e2d915aa7c43c908677afc8fa4/lxml-3.4.4.tar.gz"; |
|
648 | url = "https://pypi.python.org/packages/63/c7/4f2a2a4ad6c6fa99b14be6b3c1cece9142e2d915aa7c43c908677afc8fa4/lxml-3.4.4.tar.gz"; | |
649 | md5 = "a9a65972afc173ec7a39c585f4eea69c"; |
|
649 | md5 = "a9a65972afc173ec7a39c585f4eea69c"; | |
650 | }; |
|
650 | }; | |
651 | }; |
|
651 | }; | |
652 | mccabe = super.buildPythonPackage { |
|
652 | mccabe = super.buildPythonPackage { | |
653 | name = "mccabe-0.3"; |
|
653 | name = "mccabe-0.3"; | |
654 | buildInputs = with self; []; |
|
654 | buildInputs = with self; []; | |
655 | doCheck = false; |
|
655 | doCheck = false; | |
656 | propagatedBuildInputs = with self; []; |
|
656 | propagatedBuildInputs = with self; []; | |
657 | src = fetchurl { |
|
657 | src = fetchurl { | |
658 | url = "https://pypi.python.org/packages/c9/2e/75231479e11a906b64ac43bad9d0bb534d00080b18bdca8db9da46e1faf7/mccabe-0.3.tar.gz"; |
|
658 | url = "https://pypi.python.org/packages/c9/2e/75231479e11a906b64ac43bad9d0bb534d00080b18bdca8db9da46e1faf7/mccabe-0.3.tar.gz"; | |
659 | md5 = "81640948ff226f8c12b3277059489157"; |
|
659 | md5 = "81640948ff226f8c12b3277059489157"; | |
660 | }; |
|
660 | }; | |
661 | }; |
|
661 | }; | |
662 | meld3 = super.buildPythonPackage { |
|
662 | meld3 = super.buildPythonPackage { | |
663 | name = "meld3-1.0.2"; |
|
663 | name = "meld3-1.0.2"; | |
664 | buildInputs = with self; []; |
|
664 | buildInputs = with self; []; | |
665 | doCheck = false; |
|
665 | doCheck = false; | |
666 | propagatedBuildInputs = with self; []; |
|
666 | propagatedBuildInputs = with self; []; | |
667 | src = fetchurl { |
|
667 | src = fetchurl { | |
668 | url = "https://pypi.python.org/packages/45/a0/317c6422b26c12fe0161e936fc35f36552069ba8e6f7ecbd99bbffe32a5f/meld3-1.0.2.tar.gz"; |
|
668 | url = "https://pypi.python.org/packages/45/a0/317c6422b26c12fe0161e936fc35f36552069ba8e6f7ecbd99bbffe32a5f/meld3-1.0.2.tar.gz"; | |
669 | md5 = "3ccc78cd79cffd63a751ad7684c02c91"; |
|
669 | md5 = "3ccc78cd79cffd63a751ad7684c02c91"; | |
670 | }; |
|
670 | }; | |
671 | }; |
|
671 | }; | |
672 | mock = super.buildPythonPackage { |
|
672 | mock = super.buildPythonPackage { | |
673 | name = "mock-1.0.1"; |
|
673 | name = "mock-1.0.1"; | |
674 | buildInputs = with self; []; |
|
674 | buildInputs = with self; []; | |
675 | doCheck = false; |
|
675 | doCheck = false; | |
676 | propagatedBuildInputs = with self; []; |
|
676 | propagatedBuildInputs = with self; []; | |
677 | src = fetchurl { |
|
677 | src = fetchurl { | |
678 | url = "https://pypi.python.org/packages/15/45/30273ee91feb60dabb8fbb2da7868520525f02cf910279b3047182feed80/mock-1.0.1.zip"; |
|
678 | url = "https://pypi.python.org/packages/15/45/30273ee91feb60dabb8fbb2da7868520525f02cf910279b3047182feed80/mock-1.0.1.zip"; | |
679 | md5 = "869f08d003c289a97c1a6610faf5e913"; |
|
679 | md5 = "869f08d003c289a97c1a6610faf5e913"; | |
680 | }; |
|
680 | }; | |
681 | }; |
|
681 | }; | |
682 | msgpack-python = super.buildPythonPackage { |
|
682 | msgpack-python = super.buildPythonPackage { | |
683 | name = "msgpack-python-0.4.6"; |
|
683 | name = "msgpack-python-0.4.6"; | |
684 | buildInputs = with self; []; |
|
684 | buildInputs = with self; []; | |
685 | doCheck = false; |
|
685 | doCheck = false; | |
686 | propagatedBuildInputs = with self; []; |
|
686 | propagatedBuildInputs = with self; []; | |
687 | src = fetchurl { |
|
687 | src = fetchurl { | |
688 | url = "https://pypi.python.org/packages/15/ce/ff2840885789ef8035f66cd506ea05bdb228340307d5e71a7b1e3f82224c/msgpack-python-0.4.6.tar.gz"; |
|
688 | url = "https://pypi.python.org/packages/15/ce/ff2840885789ef8035f66cd506ea05bdb228340307d5e71a7b1e3f82224c/msgpack-python-0.4.6.tar.gz"; | |
689 | md5 = "8b317669314cf1bc881716cccdaccb30"; |
|
689 | md5 = "8b317669314cf1bc881716cccdaccb30"; | |
690 | }; |
|
690 | }; | |
691 | }; |
|
691 | }; | |
692 | nose = super.buildPythonPackage { |
|
692 | nose = super.buildPythonPackage { | |
693 | name = "nose-1.3.6"; |
|
693 | name = "nose-1.3.6"; | |
694 | buildInputs = with self; []; |
|
694 | buildInputs = with self; []; | |
695 | doCheck = false; |
|
695 | doCheck = false; | |
696 | propagatedBuildInputs = with self; []; |
|
696 | propagatedBuildInputs = with self; []; | |
697 | src = fetchurl { |
|
697 | src = fetchurl { | |
698 | url = "https://pypi.python.org/packages/70/c7/469e68148d17a0d3db5ed49150242fd70a74a8147b8f3f8b87776e028d99/nose-1.3.6.tar.gz"; |
|
698 | url = "https://pypi.python.org/packages/70/c7/469e68148d17a0d3db5ed49150242fd70a74a8147b8f3f8b87776e028d99/nose-1.3.6.tar.gz"; | |
699 | md5 = "0ca546d81ca8309080fc80cb389e7a16"; |
|
699 | md5 = "0ca546d81ca8309080fc80cb389e7a16"; | |
700 | }; |
|
700 | }; | |
701 | }; |
|
701 | }; | |
702 | objgraph = super.buildPythonPackage { |
|
702 | objgraph = super.buildPythonPackage { | |
703 | name = "objgraph-2.0.0"; |
|
703 | name = "objgraph-2.0.0"; | |
704 | buildInputs = with self; []; |
|
704 | buildInputs = with self; []; | |
705 | doCheck = false; |
|
705 | doCheck = false; | |
706 | propagatedBuildInputs = with self; []; |
|
706 | propagatedBuildInputs = with self; []; | |
707 | src = fetchurl { |
|
707 | src = fetchurl { | |
708 | url = "https://pypi.python.org/packages/d7/33/ace750b59247496ed769b170586c5def7202683f3d98e737b75b767ff29e/objgraph-2.0.0.tar.gz"; |
|
708 | url = "https://pypi.python.org/packages/d7/33/ace750b59247496ed769b170586c5def7202683f3d98e737b75b767ff29e/objgraph-2.0.0.tar.gz"; | |
709 | md5 = "25b0d5e5adc74aa63ead15699614159c"; |
|
709 | md5 = "25b0d5e5adc74aa63ead15699614159c"; | |
710 | }; |
|
710 | }; | |
711 | }; |
|
711 | }; | |
712 | packaging = super.buildPythonPackage { |
|
712 | packaging = super.buildPythonPackage { | |
713 | name = "packaging-15.2"; |
|
713 | name = "packaging-15.2"; | |
714 | buildInputs = with self; []; |
|
714 | buildInputs = with self; []; | |
715 | doCheck = false; |
|
715 | doCheck = false; | |
716 | propagatedBuildInputs = with self; []; |
|
716 | propagatedBuildInputs = with self; []; | |
717 | src = fetchurl { |
|
717 | src = fetchurl { | |
718 | url = "https://pypi.python.org/packages/24/c4/185da1304f07047dc9e0c46c31db75c0351bd73458ac3efad7da3dbcfbe1/packaging-15.2.tar.gz"; |
|
718 | url = "https://pypi.python.org/packages/24/c4/185da1304f07047dc9e0c46c31db75c0351bd73458ac3efad7da3dbcfbe1/packaging-15.2.tar.gz"; | |
719 | md5 = "c16093476f6ced42128bf610e5db3784"; |
|
719 | md5 = "c16093476f6ced42128bf610e5db3784"; | |
720 | }; |
|
720 | }; | |
721 | }; |
|
721 | }; | |
722 | paramiko = super.buildPythonPackage { |
|
722 | paramiko = super.buildPythonPackage { | |
723 | name = "paramiko-1.15.1"; |
|
723 | name = "paramiko-1.15.1"; | |
724 | buildInputs = with self; []; |
|
724 | buildInputs = with self; []; | |
725 | doCheck = false; |
|
725 | doCheck = false; | |
726 | propagatedBuildInputs = with self; [pycrypto ecdsa]; |
|
726 | propagatedBuildInputs = with self; [pycrypto ecdsa]; | |
727 | src = fetchurl { |
|
727 | src = fetchurl { | |
728 | url = "https://pypi.python.org/packages/04/2b/a22d2a560c1951abbbf95a0628e245945565f70dc082d9e784666887222c/paramiko-1.15.1.tar.gz"; |
|
728 | url = "https://pypi.python.org/packages/04/2b/a22d2a560c1951abbbf95a0628e245945565f70dc082d9e784666887222c/paramiko-1.15.1.tar.gz"; | |
729 | md5 = "48c274c3f9b1282932567b21f6acf3b5"; |
|
729 | md5 = "48c274c3f9b1282932567b21f6acf3b5"; | |
730 | }; |
|
730 | }; | |
731 | }; |
|
731 | }; | |
732 | pep8 = super.buildPythonPackage { |
|
732 | pep8 = super.buildPythonPackage { | |
733 | name = "pep8-1.5.7"; |
|
733 | name = "pep8-1.5.7"; | |
734 | buildInputs = with self; []; |
|
734 | buildInputs = with self; []; | |
735 | doCheck = false; |
|
735 | doCheck = false; | |
736 | propagatedBuildInputs = with self; []; |
|
736 | propagatedBuildInputs = with self; []; | |
737 | src = fetchurl { |
|
737 | src = fetchurl { | |
738 | url = "https://pypi.python.org/packages/8b/de/259f5e735897ada1683489dd514b2a1c91aaa74e5e6b68f80acf128a6368/pep8-1.5.7.tar.gz"; |
|
738 | url = "https://pypi.python.org/packages/8b/de/259f5e735897ada1683489dd514b2a1c91aaa74e5e6b68f80acf128a6368/pep8-1.5.7.tar.gz"; | |
739 | md5 = "f6adbdd69365ecca20513c709f9b7c93"; |
|
739 | md5 = "f6adbdd69365ecca20513c709f9b7c93"; | |
740 | }; |
|
740 | }; | |
741 | }; |
|
741 | }; | |
742 | psutil = super.buildPythonPackage { |
|
742 | psutil = super.buildPythonPackage { | |
743 | name = "psutil-2.2.1"; |
|
743 | name = "psutil-2.2.1"; | |
744 | buildInputs = with self; []; |
|
744 | buildInputs = with self; []; | |
745 | doCheck = false; |
|
745 | doCheck = false; | |
746 | propagatedBuildInputs = with self; []; |
|
746 | propagatedBuildInputs = with self; []; | |
747 | src = fetchurl { |
|
747 | src = fetchurl { | |
748 | url = "https://pypi.python.org/packages/df/47/ee54ef14dd40f8ce831a7581001a5096494dc99fe71586260ca6b531fe86/psutil-2.2.1.tar.gz"; |
|
748 | url = "https://pypi.python.org/packages/df/47/ee54ef14dd40f8ce831a7581001a5096494dc99fe71586260ca6b531fe86/psutil-2.2.1.tar.gz"; | |
749 | md5 = "1a2b58cd9e3a53528bb6148f0c4d5244"; |
|
749 | md5 = "1a2b58cd9e3a53528bb6148f0c4d5244"; | |
750 | }; |
|
750 | }; | |
751 | }; |
|
751 | }; | |
752 | psycopg2 = super.buildPythonPackage { |
|
752 | psycopg2 = super.buildPythonPackage { | |
753 | name = "psycopg2-2.6"; |
|
753 | name = "psycopg2-2.6"; | |
754 | buildInputs = with self; []; |
|
754 | buildInputs = with self; []; | |
755 | doCheck = false; |
|
755 | doCheck = false; | |
756 | propagatedBuildInputs = with self; []; |
|
756 | propagatedBuildInputs = with self; []; | |
757 | src = fetchurl { |
|
757 | src = fetchurl { | |
758 | url = "https://pypi.python.org/packages/dd/c7/9016ff8ff69da269b1848276eebfb264af5badf6b38caad805426771f04d/psycopg2-2.6.tar.gz"; |
|
758 | url = "https://pypi.python.org/packages/dd/c7/9016ff8ff69da269b1848276eebfb264af5badf6b38caad805426771f04d/psycopg2-2.6.tar.gz"; | |
759 | md5 = "fbbb039a8765d561a1c04969bbae7c74"; |
|
759 | md5 = "fbbb039a8765d561a1c04969bbae7c74"; | |
760 | }; |
|
760 | }; | |
761 | }; |
|
761 | }; | |
762 | py = super.buildPythonPackage { |
|
762 | py = super.buildPythonPackage { | |
763 | name = "py-1.4.29"; |
|
763 | name = "py-1.4.29"; | |
764 | buildInputs = with self; []; |
|
764 | buildInputs = with self; []; | |
765 | doCheck = false; |
|
765 | doCheck = false; | |
766 | propagatedBuildInputs = with self; []; |
|
766 | propagatedBuildInputs = with self; []; | |
767 | src = fetchurl { |
|
767 | src = fetchurl { | |
768 | url = "https://pypi.python.org/packages/2a/bc/a1a4a332ac10069b8e5e25136a35e08a03f01fd6ab03d819889d79a1fd65/py-1.4.29.tar.gz"; |
|
768 | url = "https://pypi.python.org/packages/2a/bc/a1a4a332ac10069b8e5e25136a35e08a03f01fd6ab03d819889d79a1fd65/py-1.4.29.tar.gz"; | |
769 | md5 = "c28e0accba523a29b35a48bb703fb96c"; |
|
769 | md5 = "c28e0accba523a29b35a48bb703fb96c"; | |
770 | }; |
|
770 | }; | |
771 | }; |
|
771 | }; | |
772 | py-bcrypt = super.buildPythonPackage { |
|
772 | py-bcrypt = super.buildPythonPackage { | |
773 | name = "py-bcrypt-0.4"; |
|
773 | name = "py-bcrypt-0.4"; | |
774 | buildInputs = with self; []; |
|
774 | buildInputs = with self; []; | |
775 | doCheck = false; |
|
775 | doCheck = false; | |
776 | propagatedBuildInputs = with self; []; |
|
776 | propagatedBuildInputs = with self; []; | |
777 | src = fetchurl { |
|
777 | src = fetchurl { | |
778 | url = "https://pypi.python.org/packages/68/b1/1c3068c5c4d2e35c48b38dcc865301ebfdf45f54507086ac65ced1fd3b3d/py-bcrypt-0.4.tar.gz"; |
|
778 | url = "https://pypi.python.org/packages/68/b1/1c3068c5c4d2e35c48b38dcc865301ebfdf45f54507086ac65ced1fd3b3d/py-bcrypt-0.4.tar.gz"; | |
779 | md5 = "dd8b367d6b716a2ea2e72392525f4e36"; |
|
779 | md5 = "dd8b367d6b716a2ea2e72392525f4e36"; | |
780 | }; |
|
780 | }; | |
781 | }; |
|
781 | }; | |
782 | pycrypto = super.buildPythonPackage { |
|
782 | pycrypto = super.buildPythonPackage { | |
783 | name = "pycrypto-2.6.1"; |
|
783 | name = "pycrypto-2.6.1"; | |
784 | buildInputs = with self; []; |
|
784 | buildInputs = with self; []; | |
785 | doCheck = false; |
|
785 | doCheck = false; | |
786 | propagatedBuildInputs = with self; []; |
|
786 | propagatedBuildInputs = with self; []; | |
787 | src = fetchurl { |
|
787 | src = fetchurl { | |
788 | url = "https://pypi.python.org/packages/60/db/645aa9af249f059cc3a368b118de33889219e0362141e75d4eaf6f80f163/pycrypto-2.6.1.tar.gz"; |
|
788 | url = "https://pypi.python.org/packages/60/db/645aa9af249f059cc3a368b118de33889219e0362141e75d4eaf6f80f163/pycrypto-2.6.1.tar.gz"; | |
789 | md5 = "55a61a054aa66812daf5161a0d5d7eda"; |
|
789 | md5 = "55a61a054aa66812daf5161a0d5d7eda"; | |
790 | }; |
|
790 | }; | |
791 | }; |
|
791 | }; | |
792 | pycurl = super.buildPythonPackage { |
|
792 | pycurl = super.buildPythonPackage { | |
793 | name = "pycurl-7.19.5"; |
|
793 | name = "pycurl-7.19.5"; | |
794 | buildInputs = with self; []; |
|
794 | buildInputs = with self; []; | |
795 | doCheck = false; |
|
795 | doCheck = false; | |
796 | propagatedBuildInputs = with self; []; |
|
796 | propagatedBuildInputs = with self; []; | |
797 | src = fetchurl { |
|
797 | src = fetchurl { | |
798 | url = "https://pypi.python.org/packages/6c/48/13bad289ef6f4869b1d8fc11ae54de8cfb3cc4a2eb9f7419c506f763be46/pycurl-7.19.5.tar.gz"; |
|
798 | url = "https://pypi.python.org/packages/6c/48/13bad289ef6f4869b1d8fc11ae54de8cfb3cc4a2eb9f7419c506f763be46/pycurl-7.19.5.tar.gz"; | |
799 | md5 = "47b4eac84118e2606658122104e62072"; |
|
799 | md5 = "47b4eac84118e2606658122104e62072"; | |
800 | }; |
|
800 | }; | |
801 | }; |
|
801 | }; | |
802 | pyelasticsearch = super.buildPythonPackage { |
|
802 | pyelasticsearch = super.buildPythonPackage { | |
803 | name = "pyelasticsearch-1.4"; |
|
803 | name = "pyelasticsearch-1.4"; | |
804 | buildInputs = with self; []; |
|
804 | buildInputs = with self; []; | |
805 | doCheck = false; |
|
805 | doCheck = false; | |
806 | propagatedBuildInputs = with self; [certifi elasticsearch urllib3 simplejson six]; |
|
806 | propagatedBuildInputs = with self; [certifi elasticsearch urllib3 simplejson six]; | |
807 | src = fetchurl { |
|
807 | src = fetchurl { | |
808 | url = "https://pypi.python.org/packages/2f/3a/7643cfcfc4cbdbb20ada800bbd54ac9705d0c047d7b8f8d5eeeb3047b4eb/pyelasticsearch-1.4.tar.gz"; |
|
808 | url = "https://pypi.python.org/packages/2f/3a/7643cfcfc4cbdbb20ada800bbd54ac9705d0c047d7b8f8d5eeeb3047b4eb/pyelasticsearch-1.4.tar.gz"; | |
809 | md5 = "ed61ebb7b253364e55b4923d11e17049"; |
|
809 | md5 = "ed61ebb7b253364e55b4923d11e17049"; | |
810 | }; |
|
810 | }; | |
811 | }; |
|
811 | }; | |
812 | pyflakes = super.buildPythonPackage { |
|
812 | pyflakes = super.buildPythonPackage { | |
813 | name = "pyflakes-0.8.1"; |
|
813 | name = "pyflakes-0.8.1"; | |
814 | buildInputs = with self; []; |
|
814 | buildInputs = with self; []; | |
815 | doCheck = false; |
|
815 | doCheck = false; | |
816 | propagatedBuildInputs = with self; []; |
|
816 | propagatedBuildInputs = with self; []; | |
817 | src = fetchurl { |
|
817 | src = fetchurl { | |
818 | url = "https://pypi.python.org/packages/75/22/a90ec0252f4f87f3ffb6336504de71fe16a49d69c4538dae2f12b9360a38/pyflakes-0.8.1.tar.gz"; |
|
818 | url = "https://pypi.python.org/packages/75/22/a90ec0252f4f87f3ffb6336504de71fe16a49d69c4538dae2f12b9360a38/pyflakes-0.8.1.tar.gz"; | |
819 | md5 = "905fe91ad14b912807e8fdc2ac2e2c23"; |
|
819 | md5 = "905fe91ad14b912807e8fdc2ac2e2c23"; | |
820 | }; |
|
820 | }; | |
821 | }; |
|
821 | }; | |
822 | pyparsing = super.buildPythonPackage { |
|
822 | pyparsing = super.buildPythonPackage { | |
823 | name = "pyparsing-1.5.7"; |
|
823 | name = "pyparsing-1.5.7"; | |
824 | buildInputs = with self; []; |
|
824 | buildInputs = with self; []; | |
825 | doCheck = false; |
|
825 | doCheck = false; | |
826 | propagatedBuildInputs = with self; []; |
|
826 | propagatedBuildInputs = with self; []; | |
827 | src = fetchurl { |
|
827 | src = fetchurl { | |
828 | url = "https://pypi.python.org/packages/2e/26/e8fb5b4256a5f5036be7ce115ef8db8d06bc537becfbdc46c6af008314ee/pyparsing-1.5.7.zip"; |
|
828 | url = "https://pypi.python.org/packages/2e/26/e8fb5b4256a5f5036be7ce115ef8db8d06bc537becfbdc46c6af008314ee/pyparsing-1.5.7.zip"; | |
829 | md5 = "b86854857a368d6ccb4d5b6e76d0637f"; |
|
829 | md5 = "b86854857a368d6ccb4d5b6e76d0637f"; | |
830 | }; |
|
830 | }; | |
831 | }; |
|
831 | }; | |
832 | pyramid = super.buildPythonPackage { |
|
832 | pyramid = super.buildPythonPackage { | |
833 | name = "pyramid-1.6.1"; |
|
833 | name = "pyramid-1.6.1"; | |
834 | buildInputs = with self; []; |
|
834 | buildInputs = with self; []; | |
835 | doCheck = false; |
|
835 | doCheck = false; | |
836 | propagatedBuildInputs = with self; [setuptools WebOb repoze.lru zope.interface zope.deprecation venusian translationstring PasteDeploy]; |
|
836 | propagatedBuildInputs = with self; [setuptools WebOb repoze.lru zope.interface zope.deprecation venusian translationstring PasteDeploy]; | |
837 | src = fetchurl { |
|
837 | src = fetchurl { | |
838 | url = "https://pypi.python.org/packages/30/b3/fcc4a2a4800cbf21989e00454b5828cf1f7fe35c63e0810b350e56d4c475/pyramid-1.6.1.tar.gz"; |
|
838 | url = "https://pypi.python.org/packages/30/b3/fcc4a2a4800cbf21989e00454b5828cf1f7fe35c63e0810b350e56d4c475/pyramid-1.6.1.tar.gz"; | |
839 | md5 = "b18688ff3cc33efdbb098a35b45dd122"; |
|
839 | md5 = "b18688ff3cc33efdbb098a35b45dd122"; | |
840 | }; |
|
840 | }; | |
841 | }; |
|
841 | }; | |
842 | pyramid-beaker = super.buildPythonPackage { |
|
842 | pyramid-beaker = super.buildPythonPackage { | |
843 | name = "pyramid-beaker-0.8"; |
|
843 | name = "pyramid-beaker-0.8"; | |
844 | buildInputs = with self; []; |
|
844 | buildInputs = with self; []; | |
845 | doCheck = false; |
|
845 | doCheck = false; | |
846 | propagatedBuildInputs = with self; [pyramid Beaker]; |
|
846 | propagatedBuildInputs = with self; [pyramid Beaker]; | |
847 | src = fetchurl { |
|
847 | src = fetchurl { | |
848 | url = "https://pypi.python.org/packages/d9/6e/b85426e00fd3d57f4545f74e1c3828552d8700f13ededeef9233f7bca8be/pyramid_beaker-0.8.tar.gz"; |
|
848 | url = "https://pypi.python.org/packages/d9/6e/b85426e00fd3d57f4545f74e1c3828552d8700f13ededeef9233f7bca8be/pyramid_beaker-0.8.tar.gz"; | |
849 | md5 = "22f14be31b06549f80890e2c63a93834"; |
|
849 | md5 = "22f14be31b06549f80890e2c63a93834"; | |
850 | }; |
|
850 | }; | |
851 | }; |
|
851 | }; | |
852 | pyramid-debugtoolbar = super.buildPythonPackage { |
|
852 | pyramid-debugtoolbar = super.buildPythonPackage { | |
853 | name = "pyramid-debugtoolbar-2.4.2"; |
|
853 | name = "pyramid-debugtoolbar-2.4.2"; | |
854 | buildInputs = with self; []; |
|
854 | buildInputs = with self; []; | |
855 | doCheck = false; |
|
855 | doCheck = false; | |
856 | propagatedBuildInputs = with self; [pyramid pyramid-mako repoze.lru Pygments]; |
|
856 | propagatedBuildInputs = with self; [pyramid pyramid-mako repoze.lru Pygments]; | |
857 | src = fetchurl { |
|
857 | src = fetchurl { | |
858 | url = "https://pypi.python.org/packages/89/00/ed5426ee41ed747ba3ffd30e8230841a6878286ea67d480b1444d24f06a2/pyramid_debugtoolbar-2.4.2.tar.gz"; |
|
858 | url = "https://pypi.python.org/packages/89/00/ed5426ee41ed747ba3ffd30e8230841a6878286ea67d480b1444d24f06a2/pyramid_debugtoolbar-2.4.2.tar.gz"; | |
859 | md5 = "073ea67086cc4bd5decc3a000853642d"; |
|
859 | md5 = "073ea67086cc4bd5decc3a000853642d"; | |
860 | }; |
|
860 | }; | |
861 | }; |
|
861 | }; | |
862 | pyramid-jinja2 = super.buildPythonPackage { |
|
862 | pyramid-jinja2 = super.buildPythonPackage { | |
863 | name = "pyramid-jinja2-2.5"; |
|
863 | name = "pyramid-jinja2-2.5"; | |
864 | buildInputs = with self; []; |
|
864 | buildInputs = with self; []; | |
865 | doCheck = false; |
|
865 | doCheck = false; | |
866 | propagatedBuildInputs = with self; [pyramid zope.deprecation Jinja2 MarkupSafe]; |
|
866 | propagatedBuildInputs = with self; [pyramid zope.deprecation Jinja2 MarkupSafe]; | |
867 | src = fetchurl { |
|
867 | src = fetchurl { | |
868 | url = "https://pypi.python.org/packages/a1/80/595e26ffab7deba7208676b6936b7e5a721875710f982e59899013cae1ed/pyramid_jinja2-2.5.tar.gz"; |
|
868 | url = "https://pypi.python.org/packages/a1/80/595e26ffab7deba7208676b6936b7e5a721875710f982e59899013cae1ed/pyramid_jinja2-2.5.tar.gz"; | |
869 | md5 = "07cb6547204ac5e6f0b22a954ccee928"; |
|
869 | md5 = "07cb6547204ac5e6f0b22a954ccee928"; | |
870 | }; |
|
870 | }; | |
871 | }; |
|
871 | }; | |
872 | pyramid-mako = super.buildPythonPackage { |
|
872 | pyramid-mako = super.buildPythonPackage { | |
873 | name = "pyramid-mako-1.0.2"; |
|
873 | name = "pyramid-mako-1.0.2"; | |
874 | buildInputs = with self; []; |
|
874 | buildInputs = with self; []; | |
875 | doCheck = false; |
|
875 | doCheck = false; | |
876 | propagatedBuildInputs = with self; [pyramid Mako]; |
|
876 | propagatedBuildInputs = with self; [pyramid Mako]; | |
877 | src = fetchurl { |
|
877 | src = fetchurl { | |
878 | url = "https://pypi.python.org/packages/f1/92/7e69bcf09676d286a71cb3bbb887b16595b96f9ba7adbdc239ffdd4b1eb9/pyramid_mako-1.0.2.tar.gz"; |
|
878 | url = "https://pypi.python.org/packages/f1/92/7e69bcf09676d286a71cb3bbb887b16595b96f9ba7adbdc239ffdd4b1eb9/pyramid_mako-1.0.2.tar.gz"; | |
879 | md5 = "ee25343a97eb76bd90abdc2a774eb48a"; |
|
879 | md5 = "ee25343a97eb76bd90abdc2a774eb48a"; | |
880 | }; |
|
880 | }; | |
881 | }; |
|
881 | }; | |
882 | pysqlite = super.buildPythonPackage { |
|
882 | pysqlite = super.buildPythonPackage { | |
883 | name = "pysqlite-2.6.3"; |
|
883 | name = "pysqlite-2.6.3"; | |
884 | buildInputs = with self; []; |
|
884 | buildInputs = with self; []; | |
885 | doCheck = false; |
|
885 | doCheck = false; | |
886 | propagatedBuildInputs = with self; []; |
|
886 | propagatedBuildInputs = with self; []; | |
887 | src = fetchurl { |
|
887 | src = fetchurl { | |
888 | url = "https://pypi.python.org/packages/5c/a6/1c429cd4c8069cf4bfbd0eb4d592b3f4042155a8202df83d7e9b93aa3dc2/pysqlite-2.6.3.tar.gz"; |
|
888 | url = "https://pypi.python.org/packages/5c/a6/1c429cd4c8069cf4bfbd0eb4d592b3f4042155a8202df83d7e9b93aa3dc2/pysqlite-2.6.3.tar.gz"; | |
889 | md5 = "7ff1cedee74646b50117acff87aa1cfa"; |
|
889 | md5 = "7ff1cedee74646b50117acff87aa1cfa"; | |
890 | }; |
|
890 | }; | |
891 | }; |
|
891 | }; | |
892 | pytest = super.buildPythonPackage { |
|
892 | pytest = super.buildPythonPackage { | |
893 | name = "pytest-2.8.5"; |
|
893 | name = "pytest-2.8.5"; | |
894 | buildInputs = with self; []; |
|
894 | buildInputs = with self; []; | |
895 | doCheck = false; |
|
895 | doCheck = false; | |
896 | propagatedBuildInputs = with self; [py]; |
|
896 | propagatedBuildInputs = with self; [py]; | |
897 | src = fetchurl { |
|
897 | src = fetchurl { | |
898 | url = "https://pypi.python.org/packages/b1/3d/d7ea9b0c51e0cacded856e49859f0a13452747491e842c236bbab3714afe/pytest-2.8.5.zip"; |
|
898 | url = "https://pypi.python.org/packages/b1/3d/d7ea9b0c51e0cacded856e49859f0a13452747491e842c236bbab3714afe/pytest-2.8.5.zip"; | |
899 | md5 = "8493b06f700862f1294298d6c1b715a9"; |
|
899 | md5 = "8493b06f700862f1294298d6c1b715a9"; | |
900 | }; |
|
900 | }; | |
901 | }; |
|
901 | }; | |
902 | pytest-catchlog = super.buildPythonPackage { |
|
902 | pytest-catchlog = super.buildPythonPackage { | |
903 | name = "pytest-catchlog-1.2.2"; |
|
903 | name = "pytest-catchlog-1.2.2"; | |
904 | buildInputs = with self; []; |
|
904 | buildInputs = with self; []; | |
905 | doCheck = false; |
|
905 | doCheck = false; | |
906 | propagatedBuildInputs = with self; [py pytest]; |
|
906 | propagatedBuildInputs = with self; [py pytest]; | |
907 | src = fetchurl { |
|
907 | src = fetchurl { | |
908 | url = "https://pypi.python.org/packages/f2/2b/2faccdb1a978fab9dd0bf31cca9f6847fbe9184a0bdcc3011ac41dd44191/pytest-catchlog-1.2.2.zip"; |
|
908 | url = "https://pypi.python.org/packages/f2/2b/2faccdb1a978fab9dd0bf31cca9f6847fbe9184a0bdcc3011ac41dd44191/pytest-catchlog-1.2.2.zip"; | |
909 | md5 = "09d890c54c7456c818102b7ff8c182c8"; |
|
909 | md5 = "09d890c54c7456c818102b7ff8c182c8"; | |
910 | }; |
|
910 | }; | |
911 | }; |
|
911 | }; | |
912 | pytest-cov = super.buildPythonPackage { |
|
912 | pytest-cov = super.buildPythonPackage { | |
913 | name = "pytest-cov-1.8.1"; |
|
913 | name = "pytest-cov-1.8.1"; | |
914 | buildInputs = with self; []; |
|
914 | buildInputs = with self; []; | |
915 | doCheck = false; |
|
915 | doCheck = false; | |
916 | propagatedBuildInputs = with self; [py pytest coverage cov-core]; |
|
916 | propagatedBuildInputs = with self; [py pytest coverage cov-core]; | |
917 | src = fetchurl { |
|
917 | src = fetchurl { | |
918 | url = "https://pypi.python.org/packages/11/4b/b04646e97f1721878eb21e9f779102d84dd044d324382263b1770a3e4838/pytest-cov-1.8.1.tar.gz"; |
|
918 | url = "https://pypi.python.org/packages/11/4b/b04646e97f1721878eb21e9f779102d84dd044d324382263b1770a3e4838/pytest-cov-1.8.1.tar.gz"; | |
919 | md5 = "76c778afa2494088270348be42d759fc"; |
|
919 | md5 = "76c778afa2494088270348be42d759fc"; | |
920 | }; |
|
920 | }; | |
921 | }; |
|
921 | }; | |
922 | pytest-profiling = super.buildPythonPackage { |
|
922 | pytest-profiling = super.buildPythonPackage { | |
923 | name = "pytest-profiling-1.0.1"; |
|
923 | name = "pytest-profiling-1.0.1"; | |
924 | buildInputs = with self; []; |
|
924 | buildInputs = with self; []; | |
925 | doCheck = false; |
|
925 | doCheck = false; | |
926 | propagatedBuildInputs = with self; [six pytest gprof2dot]; |
|
926 | propagatedBuildInputs = with self; [six pytest gprof2dot]; | |
927 | src = fetchurl { |
|
927 | src = fetchurl { | |
928 | url = "https://pypi.python.org/packages/d8/67/8ffab73406e22870e07fa4dc8dce1d7689b26dba8efd00161c9b6fc01ec0/pytest-profiling-1.0.1.tar.gz"; |
|
928 | url = "https://pypi.python.org/packages/d8/67/8ffab73406e22870e07fa4dc8dce1d7689b26dba8efd00161c9b6fc01ec0/pytest-profiling-1.0.1.tar.gz"; | |
929 | md5 = "354404eb5b3fd4dc5eb7fffbb3d9b68b"; |
|
929 | md5 = "354404eb5b3fd4dc5eb7fffbb3d9b68b"; | |
930 | }; |
|
930 | }; | |
931 | }; |
|
931 | }; | |
932 | pytest-runner = super.buildPythonPackage { |
|
932 | pytest-runner = super.buildPythonPackage { | |
933 | name = "pytest-runner-2.7.1"; |
|
933 | name = "pytest-runner-2.7.1"; | |
934 | buildInputs = with self; []; |
|
934 | buildInputs = with self; []; | |
935 | doCheck = false; |
|
935 | doCheck = false; | |
936 | propagatedBuildInputs = with self; []; |
|
936 | propagatedBuildInputs = with self; []; | |
937 | src = fetchurl { |
|
937 | src = fetchurl { | |
938 | url = "https://pypi.python.org/packages/99/6b/c4ff4418d3424d4475b7af60724fd4a5cdd91ed8e489dc9443281f0052bc/pytest-runner-2.7.1.tar.gz"; |
|
938 | url = "https://pypi.python.org/packages/99/6b/c4ff4418d3424d4475b7af60724fd4a5cdd91ed8e489dc9443281f0052bc/pytest-runner-2.7.1.tar.gz"; | |
939 | md5 = "e56f0bc8d79a6bd91772b44ef4215c7e"; |
|
939 | md5 = "e56f0bc8d79a6bd91772b44ef4215c7e"; | |
940 | }; |
|
940 | }; | |
941 | }; |
|
941 | }; | |
942 | pytest-timeout = super.buildPythonPackage { |
|
942 | pytest-timeout = super.buildPythonPackage { | |
943 | name = "pytest-timeout-0.4"; |
|
943 | name = "pytest-timeout-0.4"; | |
944 | buildInputs = with self; []; |
|
944 | buildInputs = with self; []; | |
945 | doCheck = false; |
|
945 | doCheck = false; | |
946 | propagatedBuildInputs = with self; [pytest]; |
|
946 | propagatedBuildInputs = with self; [pytest]; | |
947 | src = fetchurl { |
|
947 | src = fetchurl { | |
948 | url = "https://pypi.python.org/packages/24/48/5f6bd4b8026a26e1dd427243d560a29a0f1b24a5c7cffca4bf049a7bb65b/pytest-timeout-0.4.tar.gz"; |
|
948 | url = "https://pypi.python.org/packages/24/48/5f6bd4b8026a26e1dd427243d560a29a0f1b24a5c7cffca4bf049a7bb65b/pytest-timeout-0.4.tar.gz"; | |
949 | md5 = "03b28aff69cbbfb959ed35ade5fde262"; |
|
949 | md5 = "03b28aff69cbbfb959ed35ade5fde262"; | |
950 | }; |
|
950 | }; | |
951 | }; |
|
951 | }; | |
952 | python-dateutil = super.buildPythonPackage { |
|
952 | python-dateutil = super.buildPythonPackage { | |
953 | name = "python-dateutil-1.5"; |
|
953 | name = "python-dateutil-1.5"; | |
954 | buildInputs = with self; []; |
|
954 | buildInputs = with self; []; | |
955 | doCheck = false; |
|
955 | doCheck = false; | |
956 | propagatedBuildInputs = with self; []; |
|
956 | propagatedBuildInputs = with self; []; | |
957 | src = fetchurl { |
|
957 | src = fetchurl { | |
958 | url = "https://pypi.python.org/packages/b4/7c/df59c89a753eb33c7c44e1dd42de0e9bc2ccdd5a4d576e0bfad97cc280cb/python-dateutil-1.5.tar.gz"; |
|
958 | url = "https://pypi.python.org/packages/b4/7c/df59c89a753eb33c7c44e1dd42de0e9bc2ccdd5a4d576e0bfad97cc280cb/python-dateutil-1.5.tar.gz"; | |
959 | md5 = "0dcb1de5e5cad69490a3b6ab63f0cfa5"; |
|
959 | md5 = "0dcb1de5e5cad69490a3b6ab63f0cfa5"; | |
960 | }; |
|
960 | }; | |
961 | }; |
|
961 | }; | |
962 | python-editor = super.buildPythonPackage { |
|
962 | python-editor = super.buildPythonPackage { | |
963 | name = "python-editor-1.0"; |
|
963 | name = "python-editor-1.0"; | |
964 | buildInputs = with self; []; |
|
964 | buildInputs = with self; []; | |
965 | doCheck = false; |
|
965 | doCheck = false; | |
966 | propagatedBuildInputs = with self; []; |
|
966 | propagatedBuildInputs = with self; []; | |
967 | src = fetchurl { |
|
967 | src = fetchurl { | |
968 | url = "https://pypi.python.org/packages/f5/d9/01eb441489c8bd2adb33ee4f3aea299a3db531a584cb39c57a0ecf516d9c/python-editor-1.0.tar.gz"; |
|
968 | url = "https://pypi.python.org/packages/f5/d9/01eb441489c8bd2adb33ee4f3aea299a3db531a584cb39c57a0ecf516d9c/python-editor-1.0.tar.gz"; | |
969 | md5 = "a5ead611360b17b52507297d8590b4e8"; |
|
969 | md5 = "a5ead611360b17b52507297d8590b4e8"; | |
970 | }; |
|
970 | }; | |
971 | }; |
|
971 | }; | |
972 | python-ldap = super.buildPythonPackage { |
|
972 | python-ldap = super.buildPythonPackage { | |
973 | name = "python-ldap-2.4.19"; |
|
973 | name = "python-ldap-2.4.19"; | |
974 | buildInputs = with self; []; |
|
974 | buildInputs = with self; []; | |
975 | doCheck = false; |
|
975 | doCheck = false; | |
976 | propagatedBuildInputs = with self; [setuptools]; |
|
976 | propagatedBuildInputs = with self; [setuptools]; | |
977 | src = fetchurl { |
|
977 | src = fetchurl { | |
978 | url = "https://pypi.python.org/packages/42/81/1b64838c82e64f14d4e246ff00b52e650a35c012551b891ada2b85d40737/python-ldap-2.4.19.tar.gz"; |
|
978 | url = "https://pypi.python.org/packages/42/81/1b64838c82e64f14d4e246ff00b52e650a35c012551b891ada2b85d40737/python-ldap-2.4.19.tar.gz"; | |
979 | md5 = "b941bf31d09739492aa19ef679e94ae3"; |
|
979 | md5 = "b941bf31d09739492aa19ef679e94ae3"; | |
980 | }; |
|
980 | }; | |
981 | }; |
|
981 | }; | |
982 | python-memcached = super.buildPythonPackage { |
|
982 | python-memcached = super.buildPythonPackage { | |
983 | name = "python-memcached-1.57"; |
|
983 | name = "python-memcached-1.57"; | |
984 | buildInputs = with self; []; |
|
984 | buildInputs = with self; []; | |
985 | doCheck = false; |
|
985 | doCheck = false; | |
986 | propagatedBuildInputs = with self; [six]; |
|
986 | propagatedBuildInputs = with self; [six]; | |
987 | src = fetchurl { |
|
987 | src = fetchurl { | |
988 | url = "https://pypi.python.org/packages/52/9d/eebc0dcbc5c7c66840ad207dfc1baa376dadb74912484bff73819cce01e6/python-memcached-1.57.tar.gz"; |
|
988 | url = "https://pypi.python.org/packages/52/9d/eebc0dcbc5c7c66840ad207dfc1baa376dadb74912484bff73819cce01e6/python-memcached-1.57.tar.gz"; | |
989 | md5 = "de21f64b42b2d961f3d4ad7beb5468a1"; |
|
989 | md5 = "de21f64b42b2d961f3d4ad7beb5468a1"; | |
990 | }; |
|
990 | }; | |
991 | }; |
|
991 | }; | |
992 | python-pam = super.buildPythonPackage { |
|
992 | python-pam = super.buildPythonPackage { | |
993 | name = "python-pam-1.8.2"; |
|
993 | name = "python-pam-1.8.2"; | |
994 | buildInputs = with self; []; |
|
994 | buildInputs = with self; []; | |
995 | doCheck = false; |
|
995 | doCheck = false; | |
996 | propagatedBuildInputs = with self; []; |
|
996 | propagatedBuildInputs = with self; []; | |
997 | src = fetchurl { |
|
997 | src = fetchurl { | |
998 | url = "https://pypi.python.org/packages/de/8c/f8f5d38b4f26893af267ea0b39023d4951705ab0413a39e0cf7cf4900505/python-pam-1.8.2.tar.gz"; |
|
998 | url = "https://pypi.python.org/packages/de/8c/f8f5d38b4f26893af267ea0b39023d4951705ab0413a39e0cf7cf4900505/python-pam-1.8.2.tar.gz"; | |
999 | md5 = "db71b6b999246fb05d78ecfbe166629d"; |
|
999 | md5 = "db71b6b999246fb05d78ecfbe166629d"; | |
1000 | }; |
|
1000 | }; | |
1001 | }; |
|
1001 | }; | |
1002 | pytz = super.buildPythonPackage { |
|
1002 | pytz = super.buildPythonPackage { | |
1003 | name = "pytz-2015.4"; |
|
1003 | name = "pytz-2015.4"; | |
1004 | buildInputs = with self; []; |
|
1004 | buildInputs = with self; []; | |
1005 | doCheck = false; |
|
1005 | doCheck = false; | |
1006 | propagatedBuildInputs = with self; []; |
|
1006 | propagatedBuildInputs = with self; []; | |
1007 | src = fetchurl { |
|
1007 | src = fetchurl { | |
1008 | url = "https://pypi.python.org/packages/7e/1a/f43b5c92df7b156822030fed151327ea096bcf417e45acc23bd1df43472f/pytz-2015.4.zip"; |
|
1008 | url = "https://pypi.python.org/packages/7e/1a/f43b5c92df7b156822030fed151327ea096bcf417e45acc23bd1df43472f/pytz-2015.4.zip"; | |
1009 | md5 = "233f2a2b370d03f9b5911700cc9ebf3c"; |
|
1009 | md5 = "233f2a2b370d03f9b5911700cc9ebf3c"; | |
1010 | }; |
|
1010 | }; | |
1011 | }; |
|
1011 | }; | |
1012 | pyzmq = super.buildPythonPackage { |
|
1012 | pyzmq = super.buildPythonPackage { | |
1013 | name = "pyzmq-14.6.0"; |
|
1013 | name = "pyzmq-14.6.0"; | |
1014 | buildInputs = with self; []; |
|
1014 | buildInputs = with self; []; | |
1015 | doCheck = false; |
|
1015 | doCheck = false; | |
1016 | propagatedBuildInputs = with self; []; |
|
1016 | propagatedBuildInputs = with self; []; | |
1017 | src = fetchurl { |
|
1017 | src = fetchurl { | |
1018 | url = "https://pypi.python.org/packages/8a/3b/5463d5a9d712cd8bbdac335daece0d69f6a6792da4e3dd89956c0db4e4e6/pyzmq-14.6.0.tar.gz"; |
|
1018 | url = "https://pypi.python.org/packages/8a/3b/5463d5a9d712cd8bbdac335daece0d69f6a6792da4e3dd89956c0db4e4e6/pyzmq-14.6.0.tar.gz"; | |
1019 | md5 = "395b5de95a931afa5b14c9349a5b8024"; |
|
1019 | md5 = "395b5de95a931afa5b14c9349a5b8024"; | |
1020 | }; |
|
1020 | }; | |
1021 | }; |
|
1021 | }; | |
1022 | recaptcha-client = super.buildPythonPackage { |
|
1022 | recaptcha-client = super.buildPythonPackage { | |
1023 | name = "recaptcha-client-1.0.6"; |
|
1023 | name = "recaptcha-client-1.0.6"; | |
1024 | buildInputs = with self; []; |
|
1024 | buildInputs = with self; []; | |
1025 | doCheck = false; |
|
1025 | doCheck = false; | |
1026 | propagatedBuildInputs = with self; []; |
|
1026 | propagatedBuildInputs = with self; []; | |
1027 | src = fetchurl { |
|
1027 | src = fetchurl { | |
1028 | url = "https://pypi.python.org/packages/0a/ea/5f2fbbfd894bdac1c68ef8d92019066cfcf9fbff5fe3d728d2b5c25c8db4/recaptcha-client-1.0.6.tar.gz"; |
|
1028 | url = "https://pypi.python.org/packages/0a/ea/5f2fbbfd894bdac1c68ef8d92019066cfcf9fbff5fe3d728d2b5c25c8db4/recaptcha-client-1.0.6.tar.gz"; | |
1029 | md5 = "74228180f7e1fb76c4d7089160b0d919"; |
|
1029 | md5 = "74228180f7e1fb76c4d7089160b0d919"; | |
1030 | }; |
|
1030 | }; | |
1031 | }; |
|
1031 | }; | |
1032 | repoze.lru = super.buildPythonPackage { |
|
1032 | repoze.lru = super.buildPythonPackage { | |
1033 | name = "repoze.lru-0.6"; |
|
1033 | name = "repoze.lru-0.6"; | |
1034 | buildInputs = with self; []; |
|
1034 | buildInputs = with self; []; | |
1035 | doCheck = false; |
|
1035 | doCheck = false; | |
1036 | propagatedBuildInputs = with self; []; |
|
1036 | propagatedBuildInputs = with self; []; | |
1037 | src = fetchurl { |
|
1037 | src = fetchurl { | |
1038 | url = "https://pypi.python.org/packages/6e/1e/aa15cc90217e086dc8769872c8778b409812ff036bf021b15795638939e4/repoze.lru-0.6.tar.gz"; |
|
1038 | url = "https://pypi.python.org/packages/6e/1e/aa15cc90217e086dc8769872c8778b409812ff036bf021b15795638939e4/repoze.lru-0.6.tar.gz"; | |
1039 | md5 = "2c3b64b17a8e18b405f55d46173e14dd"; |
|
1039 | md5 = "2c3b64b17a8e18b405f55d46173e14dd"; | |
1040 | }; |
|
1040 | }; | |
1041 | }; |
|
1041 | }; | |
1042 | requests = super.buildPythonPackage { |
|
1042 | requests = super.buildPythonPackage { | |
1043 | name = "requests-2.9.1"; |
|
1043 | name = "requests-2.9.1"; | |
1044 | buildInputs = with self; []; |
|
1044 | buildInputs = with self; []; | |
1045 | doCheck = false; |
|
1045 | doCheck = false; | |
1046 | propagatedBuildInputs = with self; []; |
|
1046 | propagatedBuildInputs = with self; []; | |
1047 | src = fetchurl { |
|
1047 | src = fetchurl { | |
1048 | url = "https://pypi.python.org/packages/f9/6d/07c44fb1ebe04d069459a189e7dab9e4abfe9432adcd4477367c25332748/requests-2.9.1.tar.gz"; |
|
1048 | url = "https://pypi.python.org/packages/f9/6d/07c44fb1ebe04d069459a189e7dab9e4abfe9432adcd4477367c25332748/requests-2.9.1.tar.gz"; | |
1049 | md5 = "0b7f480d19012ec52bab78292efd976d"; |
|
1049 | md5 = "0b7f480d19012ec52bab78292efd976d"; | |
1050 | }; |
|
1050 | }; | |
1051 | }; |
|
1051 | }; | |
1052 | rhodecode-enterprise-ce = super.buildPythonPackage { |
|
1052 | rhodecode-enterprise-ce = super.buildPythonPackage { | |
1053 |
name = "rhodecode-enterprise-ce-4.0. |
|
1053 | name = "rhodecode-enterprise-ce-4.0.1"; | |
1054 |
buildInputs = with self; [WebTest configobj cssselect flake8 lxml mock pytest pytest-runner |
|
1054 | buildInputs = with self; [WebTest configobj cssselect flake8 lxml mock pytest pytest-cov pytest-runner]; | |
1055 | doCheck = true; |
|
1055 | doCheck = true; | |
1056 | propagatedBuildInputs = with self; [Babel Beaker FormEncode Mako Markdown MarkupSafe MySQL-python Paste PasteDeploy PasteScript Pygments Pylons Pyro4 Routes SQLAlchemy Tempita URLObject WebError WebHelpers WebHelpers2 WebOb WebTest Whoosh alembic amqplib anyjson appenlight-client authomatic backport-ipaddress celery colander decorator docutils infrae.cache ipython iso8601 kombu msgpack-python packaging psycopg2 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 waitress zope.cachedescriptors psutil py-bcrypt]; |
|
1056 | propagatedBuildInputs = with self; [Babel Beaker FormEncode Mako Markdown MarkupSafe MySQL-python Paste PasteDeploy PasteScript Pygments Pylons Pyro4 Routes SQLAlchemy Tempita URLObject WebError WebHelpers WebHelpers2 WebOb WebTest Whoosh alembic amqplib anyjson appenlight-client authomatic backport-ipaddress celery colander decorator docutils gunicorn infrae.cache ipython iso8601 kombu msgpack-python packaging psycopg2 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 waitress zope.cachedescriptors psutil py-bcrypt]; | |
1057 | src = ./.; |
|
1057 | src = ./.; | |
1058 | }; |
|
1058 | }; | |
1059 | rhodecode-tools = super.buildPythonPackage { |
|
1059 | rhodecode-tools = super.buildPythonPackage { | |
1060 | name = "rhodecode-tools-0.7.1"; |
|
1060 | name = "rhodecode-tools-0.7.1"; | |
1061 | buildInputs = with self; []; |
|
1061 | buildInputs = with self; []; | |
1062 | doCheck = false; |
|
1062 | doCheck = false; | |
1063 | propagatedBuildInputs = with self; [click future six Mako MarkupSafe requests Whoosh pyelasticsearch]; |
|
1063 | propagatedBuildInputs = with self; [click future six Mako MarkupSafe requests Whoosh pyelasticsearch]; | |
1064 | src = fetchurl { |
|
1064 | src = fetchurl { | |
1065 | url = "https://code.rhodecode.com/rhodecode-tools-ce/archive/v0.7.1.zip"; |
|
1065 | url = "https://code.rhodecode.com/rhodecode-tools-ce/archive/v0.7.1.zip"; | |
1066 | md5 = "91daea803aaa264ce7a8213bc2220d4c"; |
|
1066 | md5 = "91daea803aaa264ce7a8213bc2220d4c"; | |
1067 | }; |
|
1067 | }; | |
1068 | }; |
|
1068 | }; | |
1069 | serpent = super.buildPythonPackage { |
|
1069 | serpent = super.buildPythonPackage { | |
1070 | name = "serpent-1.12"; |
|
1070 | name = "serpent-1.12"; | |
1071 | buildInputs = with self; []; |
|
1071 | buildInputs = with self; []; | |
1072 | doCheck = false; |
|
1072 | doCheck = false; | |
1073 | propagatedBuildInputs = with self; []; |
|
1073 | propagatedBuildInputs = with self; []; | |
1074 | src = fetchurl { |
|
1074 | src = fetchurl { | |
1075 | url = "https://pypi.python.org/packages/3b/19/1e0e83b47c09edaef8398655088036e7e67386b5c48770218ebb339fbbd5/serpent-1.12.tar.gz"; |
|
1075 | url = "https://pypi.python.org/packages/3b/19/1e0e83b47c09edaef8398655088036e7e67386b5c48770218ebb339fbbd5/serpent-1.12.tar.gz"; | |
1076 | md5 = "05869ac7b062828b34f8f927f0457b65"; |
|
1076 | md5 = "05869ac7b062828b34f8f927f0457b65"; | |
1077 | }; |
|
1077 | }; | |
1078 | }; |
|
1078 | }; | |
1079 | setproctitle = super.buildPythonPackage { |
|
1079 | setproctitle = super.buildPythonPackage { | |
1080 | name = "setproctitle-1.1.8"; |
|
1080 | name = "setproctitle-1.1.8"; | |
1081 | buildInputs = with self; []; |
|
1081 | buildInputs = with self; []; | |
1082 | doCheck = false; |
|
1082 | doCheck = false; | |
1083 | propagatedBuildInputs = with self; []; |
|
1083 | propagatedBuildInputs = with self; []; | |
1084 | src = fetchurl { |
|
1084 | src = fetchurl { | |
1085 | url = "https://pypi.python.org/packages/33/c3/ad367a4f4f1ca90468863ae727ac62f6edb558fc09a003d344a02cfc6ea6/setproctitle-1.1.8.tar.gz"; |
|
1085 | url = "https://pypi.python.org/packages/33/c3/ad367a4f4f1ca90468863ae727ac62f6edb558fc09a003d344a02cfc6ea6/setproctitle-1.1.8.tar.gz"; | |
1086 | md5 = "728f4c8c6031bbe56083a48594027edd"; |
|
1086 | md5 = "728f4c8c6031bbe56083a48594027edd"; | |
1087 | }; |
|
1087 | }; | |
1088 | }; |
|
1088 | }; | |
1089 | setuptools = super.buildPythonPackage { |
|
1089 | setuptools = super.buildPythonPackage { | |
1090 | name = "setuptools-20.8.1"; |
|
1090 | name = "setuptools-20.8.1"; | |
1091 | buildInputs = with self; []; |
|
1091 | buildInputs = with self; []; | |
1092 | doCheck = false; |
|
1092 | doCheck = false; | |
1093 | propagatedBuildInputs = with self; []; |
|
1093 | propagatedBuildInputs = with self; []; | |
1094 | src = fetchurl { |
|
1094 | src = fetchurl { | |
1095 | url = "https://pypi.python.org/packages/c4/19/c1bdc88b53da654df43770f941079dbab4e4788c2dcb5658fb86259894c7/setuptools-20.8.1.zip"; |
|
1095 | url = "https://pypi.python.org/packages/c4/19/c1bdc88b53da654df43770f941079dbab4e4788c2dcb5658fb86259894c7/setuptools-20.8.1.zip"; | |
1096 | md5 = "fe58a5cac0df20bb83942b252a4b0543"; |
|
1096 | md5 = "fe58a5cac0df20bb83942b252a4b0543"; | |
1097 | }; |
|
1097 | }; | |
1098 | }; |
|
1098 | }; | |
1099 | setuptools-scm = super.buildPythonPackage { |
|
1099 | setuptools-scm = super.buildPythonPackage { | |
1100 | name = "setuptools-scm-1.11.0"; |
|
1100 | name = "setuptools-scm-1.11.0"; | |
1101 | buildInputs = with self; []; |
|
1101 | buildInputs = with self; []; | |
1102 | doCheck = false; |
|
1102 | doCheck = false; | |
1103 | propagatedBuildInputs = with self; []; |
|
1103 | propagatedBuildInputs = with self; []; | |
1104 | src = fetchurl { |
|
1104 | src = fetchurl { | |
1105 | url = "https://pypi.python.org/packages/cd/5f/e3a038292358058d83d764a47d09114aa5a8003ed4529518f9e580f1a94f/setuptools_scm-1.11.0.tar.gz"; |
|
1105 | url = "https://pypi.python.org/packages/cd/5f/e3a038292358058d83d764a47d09114aa5a8003ed4529518f9e580f1a94f/setuptools_scm-1.11.0.tar.gz"; | |
1106 | md5 = "4c5c896ba52e134bbc3507bac6400087"; |
|
1106 | md5 = "4c5c896ba52e134bbc3507bac6400087"; | |
1107 | }; |
|
1107 | }; | |
1108 | }; |
|
1108 | }; | |
1109 | simplejson = super.buildPythonPackage { |
|
1109 | simplejson = super.buildPythonPackage { | |
1110 | name = "simplejson-3.7.2"; |
|
1110 | name = "simplejson-3.7.2"; | |
1111 | buildInputs = with self; []; |
|
1111 | buildInputs = with self; []; | |
1112 | doCheck = false; |
|
1112 | doCheck = false; | |
1113 | propagatedBuildInputs = with self; []; |
|
1113 | propagatedBuildInputs = with self; []; | |
1114 | src = fetchurl { |
|
1114 | src = fetchurl { | |
1115 | url = "https://pypi.python.org/packages/6d/89/7f13f099344eea9d6722779a1f165087cb559598107844b1ac5dbd831fb1/simplejson-3.7.2.tar.gz"; |
|
1115 | url = "https://pypi.python.org/packages/6d/89/7f13f099344eea9d6722779a1f165087cb559598107844b1ac5dbd831fb1/simplejson-3.7.2.tar.gz"; | |
1116 | md5 = "a5fc7d05d4cb38492285553def5d4b46"; |
|
1116 | md5 = "a5fc7d05d4cb38492285553def5d4b46"; | |
1117 | }; |
|
1117 | }; | |
1118 | }; |
|
1118 | }; | |
1119 | six = super.buildPythonPackage { |
|
1119 | six = super.buildPythonPackage { | |
1120 | name = "six-1.9.0"; |
|
1120 | name = "six-1.9.0"; | |
1121 | buildInputs = with self; []; |
|
1121 | buildInputs = with self; []; | |
1122 | doCheck = false; |
|
1122 | doCheck = false; | |
1123 | propagatedBuildInputs = with self; []; |
|
1123 | propagatedBuildInputs = with self; []; | |
1124 | src = fetchurl { |
|
1124 | src = fetchurl { | |
1125 | url = "https://pypi.python.org/packages/16/64/1dc5e5976b17466fd7d712e59cbe9fb1e18bec153109e5ba3ed6c9102f1a/six-1.9.0.tar.gz"; |
|
1125 | url = "https://pypi.python.org/packages/16/64/1dc5e5976b17466fd7d712e59cbe9fb1e18bec153109e5ba3ed6c9102f1a/six-1.9.0.tar.gz"; | |
1126 | md5 = "476881ef4012262dfc8adc645ee786c4"; |
|
1126 | md5 = "476881ef4012262dfc8adc645ee786c4"; | |
1127 | }; |
|
1127 | }; | |
1128 | }; |
|
1128 | }; | |
1129 | subprocess32 = super.buildPythonPackage { |
|
1129 | subprocess32 = super.buildPythonPackage { | |
1130 | name = "subprocess32-3.2.6"; |
|
1130 | name = "subprocess32-3.2.6"; | |
1131 | buildInputs = with self; []; |
|
1131 | buildInputs = with self; []; | |
1132 | doCheck = false; |
|
1132 | doCheck = false; | |
1133 | propagatedBuildInputs = with self; []; |
|
1133 | propagatedBuildInputs = with self; []; | |
1134 | src = fetchurl { |
|
1134 | src = fetchurl { | |
1135 | url = "https://pypi.python.org/packages/28/8d/33ccbff51053f59ae6c357310cac0e79246bbed1d345ecc6188b176d72c3/subprocess32-3.2.6.tar.gz"; |
|
1135 | url = "https://pypi.python.org/packages/28/8d/33ccbff51053f59ae6c357310cac0e79246bbed1d345ecc6188b176d72c3/subprocess32-3.2.6.tar.gz"; | |
1136 | md5 = "754c5ab9f533e764f931136974b618f1"; |
|
1136 | md5 = "754c5ab9f533e764f931136974b618f1"; | |
1137 | }; |
|
1137 | }; | |
1138 | }; |
|
1138 | }; | |
1139 | supervisor = super.buildPythonPackage { |
|
1139 | supervisor = super.buildPythonPackage { | |
1140 | name = "supervisor-3.1.3"; |
|
1140 | name = "supervisor-3.1.3"; | |
1141 | buildInputs = with self; []; |
|
1141 | buildInputs = with self; []; | |
1142 | doCheck = false; |
|
1142 | doCheck = false; | |
1143 | propagatedBuildInputs = with self; [meld3]; |
|
1143 | propagatedBuildInputs = with self; [meld3]; | |
1144 | src = fetchurl { |
|
1144 | src = fetchurl { | |
1145 | url = "https://pypi.python.org/packages/a6/41/65ad5bd66230b173eb4d0b8810230f3a9c59ef52ae066e540b6b99895db7/supervisor-3.1.3.tar.gz"; |
|
1145 | url = "https://pypi.python.org/packages/a6/41/65ad5bd66230b173eb4d0b8810230f3a9c59ef52ae066e540b6b99895db7/supervisor-3.1.3.tar.gz"; | |
1146 | md5 = "aad263c4fbc070de63dd354864d5e552"; |
|
1146 | md5 = "aad263c4fbc070de63dd354864d5e552"; | |
1147 | }; |
|
1147 | }; | |
1148 | }; |
|
1148 | }; | |
1149 | transifex-client = super.buildPythonPackage { |
|
1149 | transifex-client = super.buildPythonPackage { | |
1150 | name = "transifex-client-0.10"; |
|
1150 | name = "transifex-client-0.10"; | |
1151 | buildInputs = with self; []; |
|
1151 | buildInputs = with self; []; | |
1152 | doCheck = false; |
|
1152 | doCheck = false; | |
1153 | propagatedBuildInputs = with self; []; |
|
1153 | propagatedBuildInputs = with self; []; | |
1154 | src = fetchurl { |
|
1154 | src = fetchurl { | |
1155 | url = "https://pypi.python.org/packages/f3/4e/7b925192aee656fb3e04fa6381c8b3dc40198047c3b4a356f6cfd642c809/transifex-client-0.10.tar.gz"; |
|
1155 | url = "https://pypi.python.org/packages/f3/4e/7b925192aee656fb3e04fa6381c8b3dc40198047c3b4a356f6cfd642c809/transifex-client-0.10.tar.gz"; | |
1156 | md5 = "5549538d84b8eede6b254cd81ae024fa"; |
|
1156 | md5 = "5549538d84b8eede6b254cd81ae024fa"; | |
1157 | }; |
|
1157 | }; | |
1158 | }; |
|
1158 | }; | |
1159 | translationstring = super.buildPythonPackage { |
|
1159 | translationstring = super.buildPythonPackage { | |
1160 | name = "translationstring-1.3"; |
|
1160 | name = "translationstring-1.3"; | |
1161 | buildInputs = with self; []; |
|
1161 | buildInputs = with self; []; | |
1162 | doCheck = false; |
|
1162 | doCheck = false; | |
1163 | propagatedBuildInputs = with self; []; |
|
1163 | propagatedBuildInputs = with self; []; | |
1164 | src = fetchurl { |
|
1164 | src = fetchurl { | |
1165 | url = "https://pypi.python.org/packages/5e/eb/bee578cc150b44c653b63f5ebe258b5d0d812ddac12497e5f80fcad5d0b4/translationstring-1.3.tar.gz"; |
|
1165 | url = "https://pypi.python.org/packages/5e/eb/bee578cc150b44c653b63f5ebe258b5d0d812ddac12497e5f80fcad5d0b4/translationstring-1.3.tar.gz"; | |
1166 | md5 = "a4b62e0f3c189c783a1685b3027f7c90"; |
|
1166 | md5 = "a4b62e0f3c189c783a1685b3027f7c90"; | |
1167 | }; |
|
1167 | }; | |
1168 | }; |
|
1168 | }; | |
1169 | trollius = super.buildPythonPackage { |
|
1169 | trollius = super.buildPythonPackage { | |
1170 | name = "trollius-1.0.4"; |
|
1170 | name = "trollius-1.0.4"; | |
1171 | buildInputs = with self; []; |
|
1171 | buildInputs = with self; []; | |
1172 | doCheck = false; |
|
1172 | doCheck = false; | |
1173 | propagatedBuildInputs = with self; [futures]; |
|
1173 | propagatedBuildInputs = with self; [futures]; | |
1174 | src = fetchurl { |
|
1174 | src = fetchurl { | |
1175 | url = "https://pypi.python.org/packages/aa/e6/4141db437f55e6ee7a3fb69663239e3fde7841a811b4bef293145ad6c836/trollius-1.0.4.tar.gz"; |
|
1175 | url = "https://pypi.python.org/packages/aa/e6/4141db437f55e6ee7a3fb69663239e3fde7841a811b4bef293145ad6c836/trollius-1.0.4.tar.gz"; | |
1176 | md5 = "3631a464d49d0cbfd30ab2918ef2b783"; |
|
1176 | md5 = "3631a464d49d0cbfd30ab2918ef2b783"; | |
1177 | }; |
|
1177 | }; | |
1178 | }; |
|
1178 | }; | |
1179 | uWSGI = super.buildPythonPackage { |
|
1179 | uWSGI = super.buildPythonPackage { | |
1180 | name = "uWSGI-2.0.11.2"; |
|
1180 | name = "uWSGI-2.0.11.2"; | |
1181 | buildInputs = with self; []; |
|
1181 | buildInputs = with self; []; | |
1182 | doCheck = false; |
|
1182 | doCheck = false; | |
1183 | propagatedBuildInputs = with self; []; |
|
1183 | propagatedBuildInputs = with self; []; | |
1184 | src = fetchurl { |
|
1184 | src = fetchurl { | |
1185 | url = "https://pypi.python.org/packages/9b/78/918db0cfab0546afa580c1e565209c49aaf1476bbfe491314eadbe47c556/uwsgi-2.0.11.2.tar.gz"; |
|
1185 | url = "https://pypi.python.org/packages/9b/78/918db0cfab0546afa580c1e565209c49aaf1476bbfe491314eadbe47c556/uwsgi-2.0.11.2.tar.gz"; | |
1186 | md5 = "1f02dcbee7f6f61de4b1fd68350cf16f"; |
|
1186 | md5 = "1f02dcbee7f6f61de4b1fd68350cf16f"; | |
1187 | }; |
|
1187 | }; | |
1188 | }; |
|
1188 | }; | |
1189 | urllib3 = super.buildPythonPackage { |
|
1189 | urllib3 = super.buildPythonPackage { | |
1190 | name = "urllib3-1.15.1"; |
|
1190 | name = "urllib3-1.15.1"; | |
1191 | buildInputs = with self; []; |
|
1191 | buildInputs = with self; []; | |
1192 | doCheck = false; |
|
1192 | doCheck = false; | |
1193 | propagatedBuildInputs = with self; []; |
|
1193 | propagatedBuildInputs = with self; []; | |
1194 | src = fetchurl { |
|
1194 | src = fetchurl { | |
1195 | url = "https://pypi.python.org/packages/49/26/a7d12ea00cb4b9fa1e13b5980e5a04a1fe7c477eb8f657ce0b757a7a497d/urllib3-1.15.1.tar.gz"; |
|
1195 | url = "https://pypi.python.org/packages/49/26/a7d12ea00cb4b9fa1e13b5980e5a04a1fe7c477eb8f657ce0b757a7a497d/urllib3-1.15.1.tar.gz"; | |
1196 | md5 = "5be254b0dbb55d1307ede99e1895c8dd"; |
|
1196 | md5 = "5be254b0dbb55d1307ede99e1895c8dd"; | |
1197 | }; |
|
1197 | }; | |
1198 | }; |
|
1198 | }; | |
1199 | venusian = super.buildPythonPackage { |
|
1199 | venusian = super.buildPythonPackage { | |
1200 | name = "venusian-1.0"; |
|
1200 | name = "venusian-1.0"; | |
1201 | buildInputs = with self; []; |
|
1201 | buildInputs = with self; []; | |
1202 | doCheck = false; |
|
1202 | doCheck = false; | |
1203 | propagatedBuildInputs = with self; []; |
|
1203 | propagatedBuildInputs = with self; []; | |
1204 | src = fetchurl { |
|
1204 | src = fetchurl { | |
1205 | url = "https://pypi.python.org/packages/86/20/1948e0dfc4930ddde3da8c33612f6a5717c0b4bc28f591a5c5cf014dd390/venusian-1.0.tar.gz"; |
|
1205 | url = "https://pypi.python.org/packages/86/20/1948e0dfc4930ddde3da8c33612f6a5717c0b4bc28f591a5c5cf014dd390/venusian-1.0.tar.gz"; | |
1206 | md5 = "dccf2eafb7113759d60c86faf5538756"; |
|
1206 | md5 = "dccf2eafb7113759d60c86faf5538756"; | |
1207 | }; |
|
1207 | }; | |
1208 | }; |
|
1208 | }; | |
1209 | waitress = super.buildPythonPackage { |
|
1209 | waitress = super.buildPythonPackage { | |
1210 | name = "waitress-0.8.9"; |
|
1210 | name = "waitress-0.8.9"; | |
1211 | buildInputs = with self; []; |
|
1211 | buildInputs = with self; []; | |
1212 | doCheck = false; |
|
1212 | doCheck = false; | |
1213 | propagatedBuildInputs = with self; [setuptools]; |
|
1213 | propagatedBuildInputs = with self; [setuptools]; | |
1214 | src = fetchurl { |
|
1214 | src = fetchurl { | |
1215 | url = "https://pypi.python.org/packages/ee/65/fc9dee74a909a1187ca51e4f15ad9c4d35476e4ab5813f73421505c48053/waitress-0.8.9.tar.gz"; |
|
1215 | url = "https://pypi.python.org/packages/ee/65/fc9dee74a909a1187ca51e4f15ad9c4d35476e4ab5813f73421505c48053/waitress-0.8.9.tar.gz"; | |
1216 | md5 = "da3f2e62b3676be5dd630703a68e2a04"; |
|
1216 | md5 = "da3f2e62b3676be5dd630703a68e2a04"; | |
1217 | }; |
|
1217 | }; | |
1218 | }; |
|
1218 | }; | |
1219 | wsgiref = super.buildPythonPackage { |
|
1219 | wsgiref = super.buildPythonPackage { | |
1220 | name = "wsgiref-0.1.2"; |
|
1220 | name = "wsgiref-0.1.2"; | |
1221 | buildInputs = with self; []; |
|
1221 | buildInputs = with self; []; | |
1222 | doCheck = false; |
|
1222 | doCheck = false; | |
1223 | propagatedBuildInputs = with self; []; |
|
1223 | propagatedBuildInputs = with self; []; | |
1224 | src = fetchurl { |
|
1224 | src = fetchurl { | |
1225 | url = "https://pypi.python.org/packages/41/9e/309259ce8dff8c596e8c26df86dbc4e848b9249fd36797fd60be456f03fc/wsgiref-0.1.2.zip"; |
|
1225 | url = "https://pypi.python.org/packages/41/9e/309259ce8dff8c596e8c26df86dbc4e848b9249fd36797fd60be456f03fc/wsgiref-0.1.2.zip"; | |
1226 | md5 = "29b146e6ebd0f9fb119fe321f7bcf6cb"; |
|
1226 | md5 = "29b146e6ebd0f9fb119fe321f7bcf6cb"; | |
1227 | }; |
|
1227 | }; | |
1228 | }; |
|
1228 | }; | |
1229 | zope.cachedescriptors = super.buildPythonPackage { |
|
1229 | zope.cachedescriptors = super.buildPythonPackage { | |
1230 | name = "zope.cachedescriptors-4.0.0"; |
|
1230 | name = "zope.cachedescriptors-4.0.0"; | |
1231 | buildInputs = with self; []; |
|
1231 | buildInputs = with self; []; | |
1232 | doCheck = false; |
|
1232 | doCheck = false; | |
1233 | propagatedBuildInputs = with self; [setuptools]; |
|
1233 | propagatedBuildInputs = with self; [setuptools]; | |
1234 | src = fetchurl { |
|
1234 | src = fetchurl { | |
1235 | url = "https://pypi.python.org/packages/40/33/694b6644c37f28553f4b9f20b3c3a20fb709a22574dff20b5bdffb09ecd5/zope.cachedescriptors-4.0.0.tar.gz"; |
|
1235 | url = "https://pypi.python.org/packages/40/33/694b6644c37f28553f4b9f20b3c3a20fb709a22574dff20b5bdffb09ecd5/zope.cachedescriptors-4.0.0.tar.gz"; | |
1236 | md5 = "8d308de8c936792c8e758058fcb7d0f0"; |
|
1236 | md5 = "8d308de8c936792c8e758058fcb7d0f0"; | |
1237 | }; |
|
1237 | }; | |
1238 | }; |
|
1238 | }; | |
1239 | zope.deprecation = super.buildPythonPackage { |
|
1239 | zope.deprecation = super.buildPythonPackage { | |
1240 | name = "zope.deprecation-4.1.2"; |
|
1240 | name = "zope.deprecation-4.1.2"; | |
1241 | buildInputs = with self; []; |
|
1241 | buildInputs = with self; []; | |
1242 | doCheck = false; |
|
1242 | doCheck = false; | |
1243 | propagatedBuildInputs = with self; [setuptools]; |
|
1243 | propagatedBuildInputs = with self; [setuptools]; | |
1244 | src = fetchurl { |
|
1244 | src = fetchurl { | |
1245 | url = "https://pypi.python.org/packages/c1/d3/3919492d5e57d8dd01b36f30b34fc8404a30577392b1eb817c303499ad20/zope.deprecation-4.1.2.tar.gz"; |
|
1245 | url = "https://pypi.python.org/packages/c1/d3/3919492d5e57d8dd01b36f30b34fc8404a30577392b1eb817c303499ad20/zope.deprecation-4.1.2.tar.gz"; | |
1246 | md5 = "e9a663ded58f4f9f7881beb56cae2782"; |
|
1246 | md5 = "e9a663ded58f4f9f7881beb56cae2782"; | |
1247 | }; |
|
1247 | }; | |
1248 | }; |
|
1248 | }; | |
1249 | zope.event = super.buildPythonPackage { |
|
1249 | zope.event = super.buildPythonPackage { | |
1250 | name = "zope.event-4.0.3"; |
|
1250 | name = "zope.event-4.0.3"; | |
1251 | buildInputs = with self; []; |
|
1251 | buildInputs = with self; []; | |
1252 | doCheck = false; |
|
1252 | doCheck = false; | |
1253 | propagatedBuildInputs = with self; [setuptools]; |
|
1253 | propagatedBuildInputs = with self; [setuptools]; | |
1254 | src = fetchurl { |
|
1254 | src = fetchurl { | |
1255 | url = "https://pypi.python.org/packages/c1/29/91ba884d7d6d96691df592e9e9c2bfa57a47040ec1ff47eff18c85137152/zope.event-4.0.3.tar.gz"; |
|
1255 | url = "https://pypi.python.org/packages/c1/29/91ba884d7d6d96691df592e9e9c2bfa57a47040ec1ff47eff18c85137152/zope.event-4.0.3.tar.gz"; | |
1256 | md5 = "9a3780916332b18b8b85f522bcc3e249"; |
|
1256 | md5 = "9a3780916332b18b8b85f522bcc3e249"; | |
1257 | }; |
|
1257 | }; | |
1258 | }; |
|
1258 | }; | |
1259 | zope.interface = super.buildPythonPackage { |
|
1259 | zope.interface = super.buildPythonPackage { | |
1260 | name = "zope.interface-4.1.3"; |
|
1260 | name = "zope.interface-4.1.3"; | |
1261 | buildInputs = with self; []; |
|
1261 | buildInputs = with self; []; | |
1262 | doCheck = false; |
|
1262 | doCheck = false; | |
1263 | propagatedBuildInputs = with self; [setuptools]; |
|
1263 | propagatedBuildInputs = with self; [setuptools]; | |
1264 | src = fetchurl { |
|
1264 | src = fetchurl { | |
1265 | url = "https://pypi.python.org/packages/9d/81/2509ca3c6f59080123c1a8a97125eb48414022618cec0e64eb1313727bfe/zope.interface-4.1.3.tar.gz"; |
|
1265 | url = "https://pypi.python.org/packages/9d/81/2509ca3c6f59080123c1a8a97125eb48414022618cec0e64eb1313727bfe/zope.interface-4.1.3.tar.gz"; | |
1266 | md5 = "9ae3d24c0c7415deb249dd1a132f0f79"; |
|
1266 | md5 = "9ae3d24c0c7415deb249dd1a132f0f79"; | |
1267 | }; |
|
1267 | }; | |
1268 | }; |
|
1268 | }; | |
1269 |
|
1269 | |||
1270 | ### Test requirements |
|
1270 | ### Test requirements | |
1271 |
|
1271 | |||
1272 |
|
1272 | |||
1273 | } |
|
1273 | } |
@@ -1,166 +1,163 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 | # Copyright (C) 2012-2016 RhodeCode GmbH |
|
3 | # Copyright (C) 2012-2016 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
7 | # (only), as published by the Free Software Foundation. |
|
7 | # (only), as published by the Free Software Foundation. | |
8 | # |
|
8 | # | |
9 | # This program is distributed in the hope that it will be useful, |
|
9 | # This program is distributed in the hope that it will be useful, | |
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | # GNU General Public License for more details. |
|
12 | # GNU General Public License for more details. | |
13 | # |
|
13 | # | |
14 | # You should have received a copy of the GNU Affero General Public License |
|
14 | # You should have received a copy of the GNU Affero General Public License | |
15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
16 | # |
|
16 | # | |
17 | # This program is dual-licensed. If you wish to learn more about the |
|
17 | # This program is dual-licensed. If you wish to learn more about the | |
18 | # RhodeCode Enterprise Edition, including its added features, Support services, |
|
18 | # RhodeCode Enterprise Edition, including its added features, Support services, | |
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ |
|
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |
20 |
|
20 | |||
21 | """ |
|
21 | """ | |
22 | RhodeCode authentication plugin for Jasig CAS |
|
22 | RhodeCode authentication plugin for Jasig CAS | |
23 | http://www.jasig.org/cas |
|
23 | http://www.jasig.org/cas | |
24 | """ |
|
24 | """ | |
25 |
|
25 | |||
26 |
|
26 | |||
27 | import colander |
|
27 | import colander | |
28 | import logging |
|
28 | import logging | |
29 | import rhodecode |
|
29 | import rhodecode | |
30 | import urllib |
|
30 | import urllib | |
31 | import urllib2 |
|
31 | import urllib2 | |
32 |
|
32 | |||
33 | from pylons.i18n.translation import lazy_ugettext as _ |
|
33 | from pylons.i18n.translation import lazy_ugettext as _ | |
34 | from sqlalchemy.ext.hybrid import hybrid_property |
|
34 | from sqlalchemy.ext.hybrid import hybrid_property | |
35 |
|
35 | |||
36 | from rhodecode.authentication.base import RhodeCodeExternalAuthPlugin |
|
36 | from rhodecode.authentication.base import RhodeCodeExternalAuthPlugin | |
37 | from rhodecode.authentication.schema import AuthnPluginSettingsSchemaBase |
|
37 | from rhodecode.authentication.schema import AuthnPluginSettingsSchemaBase | |
38 | from rhodecode.authentication.routes import AuthnPluginResourceBase |
|
38 | from rhodecode.authentication.routes import AuthnPluginResourceBase | |
39 | from rhodecode.lib.ext_json import formatted_json |
|
|||
40 | from rhodecode.lib.utils2 import safe_unicode |
|
39 | from rhodecode.lib.utils2 import safe_unicode | |
41 | from rhodecode.model.db import User |
|
40 | from rhodecode.model.db import User | |
42 |
|
41 | |||
43 | log = logging.getLogger(__name__) |
|
42 | log = logging.getLogger(__name__) | |
44 |
|
43 | |||
45 |
|
44 | |||
46 | def plugin_factory(plugin_id, *args, **kwds): |
|
45 | def plugin_factory(plugin_id, *args, **kwds): | |
47 | """ |
|
46 | """ | |
48 | Factory function that is called during plugin discovery. |
|
47 | Factory function that is called during plugin discovery. | |
49 | It returns the plugin instance. |
|
48 | It returns the plugin instance. | |
50 | """ |
|
49 | """ | |
51 | plugin = RhodeCodeAuthPlugin(plugin_id) |
|
50 | plugin = RhodeCodeAuthPlugin(plugin_id) | |
52 | return plugin |
|
51 | return plugin | |
53 |
|
52 | |||
54 |
|
53 | |||
55 | class JasigCasAuthnResource(AuthnPluginResourceBase): |
|
54 | class JasigCasAuthnResource(AuthnPluginResourceBase): | |
56 | pass |
|
55 | pass | |
57 |
|
56 | |||
58 |
|
57 | |||
59 | class JasigCasSettingsSchema(AuthnPluginSettingsSchemaBase): |
|
58 | class JasigCasSettingsSchema(AuthnPluginSettingsSchemaBase): | |
60 | service_url = colander.SchemaNode( |
|
59 | service_url = colander.SchemaNode( | |
61 | colander.String(), |
|
60 | colander.String(), | |
62 | default='https://domain.com/cas/v1/tickets', |
|
61 | default='https://domain.com/cas/v1/tickets', | |
63 | description=_('The url of the Jasig CAS REST service'), |
|
62 | description=_('The url of the Jasig CAS REST service'), | |
64 | title=_('URL'), |
|
63 | title=_('URL'), | |
65 | widget='string') |
|
64 | widget='string') | |
66 |
|
65 | |||
67 |
|
66 | |||
68 | class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): |
|
67 | class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): | |
69 |
|
68 | |||
70 | def includeme(self, config): |
|
69 | def includeme(self, config): | |
71 | config.add_authn_plugin(self) |
|
70 | config.add_authn_plugin(self) | |
72 | config.add_authn_resource(self.get_id(), JasigCasAuthnResource(self)) |
|
71 | config.add_authn_resource(self.get_id(), JasigCasAuthnResource(self)) | |
73 | config.add_view( |
|
72 | config.add_view( | |
74 | 'rhodecode.authentication.views.AuthnPluginViewBase', |
|
73 | 'rhodecode.authentication.views.AuthnPluginViewBase', | |
75 | attr='settings_get', |
|
74 | attr='settings_get', | |
76 | request_method='GET', |
|
75 | request_method='GET', | |
77 | route_name='auth_home', |
|
76 | route_name='auth_home', | |
78 | context=JasigCasAuthnResource) |
|
77 | context=JasigCasAuthnResource) | |
79 | config.add_view( |
|
78 | config.add_view( | |
80 | 'rhodecode.authentication.views.AuthnPluginViewBase', |
|
79 | 'rhodecode.authentication.views.AuthnPluginViewBase', | |
81 | attr='settings_post', |
|
80 | attr='settings_post', | |
82 | request_method='POST', |
|
81 | request_method='POST', | |
83 | route_name='auth_home', |
|
82 | route_name='auth_home', | |
84 | context=JasigCasAuthnResource) |
|
83 | context=JasigCasAuthnResource) | |
85 |
|
84 | |||
86 | def get_settings_schema(self): |
|
85 | def get_settings_schema(self): | |
87 | return JasigCasSettingsSchema() |
|
86 | return JasigCasSettingsSchema() | |
88 |
|
87 | |||
89 | def get_display_name(self): |
|
88 | def get_display_name(self): | |
90 | return _('Jasig-CAS') |
|
89 | return _('Jasig-CAS') | |
91 |
|
90 | |||
92 | @hybrid_property |
|
91 | @hybrid_property | |
93 | def name(self): |
|
92 | def name(self): | |
94 | return "jasig-cas" |
|
93 | return "jasig-cas" | |
95 |
|
94 | |||
96 | @hybrid_property |
|
95 | @hybrid_property | |
97 | def is_container_auth(self): |
|
96 | def is_container_auth(self): | |
98 | return True |
|
97 | return True | |
99 |
|
98 | |||
100 | def use_fake_password(self): |
|
99 | def use_fake_password(self): | |
101 | return True |
|
100 | return True | |
102 |
|
101 | |||
103 | def user_activation_state(self): |
|
102 | def user_activation_state(self): | |
104 | def_user_perms = User.get_default_user().AuthUser.permissions['global'] |
|
103 | def_user_perms = User.get_default_user().AuthUser.permissions['global'] | |
105 | return 'hg.extern_activate.auto' in def_user_perms |
|
104 | return 'hg.extern_activate.auto' in def_user_perms | |
106 |
|
105 | |||
107 | def auth(self, userobj, username, password, settings, **kwargs): |
|
106 | def auth(self, userobj, username, password, settings, **kwargs): | |
108 | """ |
|
107 | """ | |
109 | Given a user object (which may be null), username, a plaintext password, |
|
108 | Given a user object (which may be null), username, a plaintext password, | |
110 | and a settings object (containing all the keys needed as listed in settings()), |
|
109 | and a settings object (containing all the keys needed as listed in settings()), | |
111 | authenticate this user's login attempt. |
|
110 | authenticate this user's login attempt. | |
112 |
|
111 | |||
113 | Return None on failure. On success, return a dictionary of the form: |
|
112 | Return None on failure. On success, return a dictionary of the form: | |
114 |
|
113 | |||
115 | see: RhodeCodeAuthPluginBase.auth_func_attrs |
|
114 | see: RhodeCodeAuthPluginBase.auth_func_attrs | |
116 | This is later validated for correctness |
|
115 | This is later validated for correctness | |
117 | """ |
|
116 | """ | |
118 | if not username or not password: |
|
117 | if not username or not password: | |
119 | log.debug('Empty username or password skipping...') |
|
118 | log.debug('Empty username or password skipping...') | |
120 | return None |
|
119 | return None | |
121 |
|
120 | |||
122 |
log.debug("Jasig CAS settings: |
|
121 | log.debug("Jasig CAS settings: %s", settings) | |
123 | params = urllib.urlencode({'username': username, 'password': password}) |
|
122 | params = urllib.urlencode({'username': username, 'password': password}) | |
124 | headers = {"Content-type": "application/x-www-form-urlencoded", |
|
123 | headers = {"Content-type": "application/x-www-form-urlencoded", | |
125 | "Accept": "text/plain", |
|
124 | "Accept": "text/plain", | |
126 | "User-Agent": "RhodeCode-auth-%s" % rhodecode.__version__} |
|
125 | "User-Agent": "RhodeCode-auth-%s" % rhodecode.__version__} | |
127 | url = settings["service_url"] |
|
126 | url = settings["service_url"] | |
128 |
|
127 | |||
129 | log.debug("Sent Jasig CAS: \n%s" |
|
128 | log.debug("Sent Jasig CAS: \n%s", | |
130 | % (formatted_json({"url": url, |
|
129 | {"url": url, "body": params, "headers": headers}) | |
131 | "body": params, |
|
|||
132 | "headers": headers}))) |
|
|||
133 | request = urllib2.Request(url, params, headers) |
|
130 | request = urllib2.Request(url, params, headers) | |
134 | try: |
|
131 | try: | |
135 | response = urllib2.urlopen(request) |
|
132 | response = urllib2.urlopen(request) | |
136 | except urllib2.HTTPError as e: |
|
133 | except urllib2.HTTPError as e: | |
137 | log.debug("HTTPError when requesting Jasig CAS (status code: %d)" % e.code) |
|
134 | log.debug("HTTPError when requesting Jasig CAS (status code: %d)" % e.code) | |
138 | return None |
|
135 | return None | |
139 | except urllib2.URLError as e: |
|
136 | except urllib2.URLError as e: | |
140 | log.debug("URLError when requesting Jasig CAS url: %s " % url) |
|
137 | log.debug("URLError when requesting Jasig CAS url: %s " % url) | |
141 | return None |
|
138 | return None | |
142 |
|
139 | |||
143 | # old attrs fetched from RhodeCode database |
|
140 | # old attrs fetched from RhodeCode database | |
144 | admin = getattr(userobj, 'admin', False) |
|
141 | admin = getattr(userobj, 'admin', False) | |
145 | active = getattr(userobj, 'active', True) |
|
142 | active = getattr(userobj, 'active', True) | |
146 | email = getattr(userobj, 'email', '') |
|
143 | email = getattr(userobj, 'email', '') | |
147 | username = getattr(userobj, 'username', username) |
|
144 | username = getattr(userobj, 'username', username) | |
148 | firstname = getattr(userobj, 'firstname', '') |
|
145 | firstname = getattr(userobj, 'firstname', '') | |
149 | lastname = getattr(userobj, 'lastname', '') |
|
146 | lastname = getattr(userobj, 'lastname', '') | |
150 | extern_type = getattr(userobj, 'extern_type', '') |
|
147 | extern_type = getattr(userobj, 'extern_type', '') | |
151 |
|
148 | |||
152 | user_attrs = { |
|
149 | user_attrs = { | |
153 | 'username': username, |
|
150 | 'username': username, | |
154 | 'firstname': safe_unicode(firstname or username), |
|
151 | 'firstname': safe_unicode(firstname or username), | |
155 | 'lastname': safe_unicode(lastname or ''), |
|
152 | 'lastname': safe_unicode(lastname or ''), | |
156 | 'groups': [], |
|
153 | 'groups': [], | |
157 | 'email': email or '', |
|
154 | 'email': email or '', | |
158 | 'admin': admin or False, |
|
155 | 'admin': admin or False, | |
159 | 'active': active, |
|
156 | 'active': active, | |
160 | 'active_from_extern': True, |
|
157 | 'active_from_extern': True, | |
161 | 'extern_name': username, |
|
158 | 'extern_name': username, | |
162 | 'extern_type': extern_type, |
|
159 | 'extern_type': extern_type, | |
163 | } |
|
160 | } | |
164 |
|
161 | |||
165 | log.info('user %s authenticated correctly' % user_attrs['username']) |
|
162 | log.info('user %s authenticated correctly' % user_attrs['username']) | |
166 | return user_attrs |
|
163 | return user_attrs |
@@ -1,448 +1,447 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 | # Copyright (C) 2010-2016 RhodeCode GmbH |
|
3 | # Copyright (C) 2010-2016 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
7 | # (only), as published by the Free Software Foundation. |
|
7 | # (only), as published by the Free Software Foundation. | |
8 | # |
|
8 | # | |
9 | # This program is distributed in the hope that it will be useful, |
|
9 | # This program is distributed in the hope that it will be useful, | |
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | # GNU General Public License for more details. |
|
12 | # GNU General Public License for more details. | |
13 | # |
|
13 | # | |
14 | # You should have received a copy of the GNU Affero General Public License |
|
14 | # You should have received a copy of the GNU Affero General Public License | |
15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
16 | # |
|
16 | # | |
17 | # This program is dual-licensed. If you wish to learn more about the |
|
17 | # This program is dual-licensed. If you wish to learn more about the | |
18 | # RhodeCode Enterprise Edition, including its added features, Support services, |
|
18 | # RhodeCode Enterprise Edition, including its added features, Support services, | |
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ |
|
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |
20 |
|
20 | |||
21 | """ |
|
21 | """ | |
22 | RhodeCode authentication plugin for LDAP |
|
22 | RhodeCode authentication plugin for LDAP | |
23 | """ |
|
23 | """ | |
24 |
|
24 | |||
25 |
|
25 | |||
26 | import colander |
|
26 | import colander | |
27 | import logging |
|
27 | import logging | |
28 | import traceback |
|
28 | import traceback | |
29 |
|
29 | |||
30 | from pylons.i18n.translation import lazy_ugettext as _ |
|
30 | from pylons.i18n.translation import lazy_ugettext as _ | |
31 | from sqlalchemy.ext.hybrid import hybrid_property |
|
31 | from sqlalchemy.ext.hybrid import hybrid_property | |
32 |
|
32 | |||
33 | from rhodecode.authentication.base import RhodeCodeExternalAuthPlugin |
|
33 | from rhodecode.authentication.base import RhodeCodeExternalAuthPlugin | |
34 | from rhodecode.authentication.schema import AuthnPluginSettingsSchemaBase |
|
34 | from rhodecode.authentication.schema import AuthnPluginSettingsSchemaBase | |
35 | from rhodecode.authentication.routes import AuthnPluginResourceBase |
|
35 | from rhodecode.authentication.routes import AuthnPluginResourceBase | |
36 | from rhodecode.lib.exceptions import ( |
|
36 | from rhodecode.lib.exceptions import ( | |
37 | LdapConnectionError, LdapUsernameError, LdapPasswordError, LdapImportError |
|
37 | LdapConnectionError, LdapUsernameError, LdapPasswordError, LdapImportError | |
38 | ) |
|
38 | ) | |
39 | from rhodecode.lib.ext_json import formatted_json |
|
|||
40 | from rhodecode.lib.utils2 import safe_unicode, safe_str |
|
39 | from rhodecode.lib.utils2 import safe_unicode, safe_str | |
41 | from rhodecode.model.db import User |
|
40 | from rhodecode.model.db import User | |
42 | from rhodecode.model.validators import Missing |
|
41 | from rhodecode.model.validators import Missing | |
43 |
|
42 | |||
44 | log = logging.getLogger(__name__) |
|
43 | log = logging.getLogger(__name__) | |
45 |
|
44 | |||
46 | try: |
|
45 | try: | |
47 | import ldap |
|
46 | import ldap | |
48 | except ImportError: |
|
47 | except ImportError: | |
49 | # means that python-ldap is not installed |
|
48 | # means that python-ldap is not installed | |
50 | ldap = Missing() |
|
49 | ldap = Missing() | |
51 |
|
50 | |||
52 |
|
51 | |||
53 | def plugin_factory(plugin_id, *args, **kwds): |
|
52 | def plugin_factory(plugin_id, *args, **kwds): | |
54 | """ |
|
53 | """ | |
55 | Factory function that is called during plugin discovery. |
|
54 | Factory function that is called during plugin discovery. | |
56 | It returns the plugin instance. |
|
55 | It returns the plugin instance. | |
57 | """ |
|
56 | """ | |
58 | plugin = RhodeCodeAuthPlugin(plugin_id) |
|
57 | plugin = RhodeCodeAuthPlugin(plugin_id) | |
59 | return plugin |
|
58 | return plugin | |
60 |
|
59 | |||
61 |
|
60 | |||
62 | class LdapAuthnResource(AuthnPluginResourceBase): |
|
61 | class LdapAuthnResource(AuthnPluginResourceBase): | |
63 | pass |
|
62 | pass | |
64 |
|
63 | |||
65 |
|
64 | |||
66 | class LdapSettingsSchema(AuthnPluginSettingsSchemaBase): |
|
65 | class LdapSettingsSchema(AuthnPluginSettingsSchemaBase): | |
67 | tls_kind_choices = ['PLAIN', 'LDAPS', 'START_TLS'] |
|
66 | tls_kind_choices = ['PLAIN', 'LDAPS', 'START_TLS'] | |
68 | tls_reqcert_choices = ['NEVER', 'ALLOW', 'TRY', 'DEMAND', 'HARD'] |
|
67 | tls_reqcert_choices = ['NEVER', 'ALLOW', 'TRY', 'DEMAND', 'HARD'] | |
69 | search_scope_choices = ['BASE', 'ONELEVEL', 'SUBTREE'] |
|
68 | search_scope_choices = ['BASE', 'ONELEVEL', 'SUBTREE'] | |
70 |
|
69 | |||
71 | host = colander.SchemaNode( |
|
70 | host = colander.SchemaNode( | |
72 | colander.String(), |
|
71 | colander.String(), | |
73 | default='', |
|
72 | default='', | |
74 | description=_('Host of the LDAP Server'), |
|
73 | description=_('Host of the LDAP Server'), | |
75 | title=_('LDAP Host'), |
|
74 | title=_('LDAP Host'), | |
76 | widget='string') |
|
75 | widget='string') | |
77 | port = colander.SchemaNode( |
|
76 | port = colander.SchemaNode( | |
78 | colander.Int(), |
|
77 | colander.Int(), | |
79 | default=389, |
|
78 | default=389, | |
80 | description=_('Port that the LDAP server is listening on'), |
|
79 | description=_('Port that the LDAP server is listening on'), | |
81 | title=_('Port'), |
|
80 | title=_('Port'), | |
82 | validator=colander.Range(min=0, max=65536), |
|
81 | validator=colander.Range(min=0, max=65536), | |
83 | widget='int') |
|
82 | widget='int') | |
84 | dn_user = colander.SchemaNode( |
|
83 | dn_user = colander.SchemaNode( | |
85 | colander.String(), |
|
84 | colander.String(), | |
86 | default='', |
|
85 | default='', | |
87 | description=_('User to connect to LDAP'), |
|
86 | description=_('User to connect to LDAP'), | |
88 | missing='', |
|
87 | missing='', | |
89 | title=_('Account'), |
|
88 | title=_('Account'), | |
90 | widget='string') |
|
89 | widget='string') | |
91 | dn_pass = colander.SchemaNode( |
|
90 | dn_pass = colander.SchemaNode( | |
92 | colander.String(), |
|
91 | colander.String(), | |
93 | default='', |
|
92 | default='', | |
94 | description=_('Password to connect to LDAP'), |
|
93 | description=_('Password to connect to LDAP'), | |
95 | missing='', |
|
94 | missing='', | |
96 | title=_('Password'), |
|
95 | title=_('Password'), | |
97 | widget='password') |
|
96 | widget='password') | |
98 | tls_kind = colander.SchemaNode( |
|
97 | tls_kind = colander.SchemaNode( | |
99 | colander.String(), |
|
98 | colander.String(), | |
100 | default=tls_kind_choices[0], |
|
99 | default=tls_kind_choices[0], | |
101 | description=_('TLS Type'), |
|
100 | description=_('TLS Type'), | |
102 | title=_('Connection Security'), |
|
101 | title=_('Connection Security'), | |
103 | validator=colander.OneOf(tls_kind_choices), |
|
102 | validator=colander.OneOf(tls_kind_choices), | |
104 | widget='select') |
|
103 | widget='select') | |
105 | tls_reqcert = colander.SchemaNode( |
|
104 | tls_reqcert = colander.SchemaNode( | |
106 | colander.String(), |
|
105 | colander.String(), | |
107 | default=tls_reqcert_choices[0], |
|
106 | default=tls_reqcert_choices[0], | |
108 | description=_('Require Cert over TLS?'), |
|
107 | description=_('Require Cert over TLS?'), | |
109 | title=_('Certificate Checks'), |
|
108 | title=_('Certificate Checks'), | |
110 | validator=colander.OneOf(tls_reqcert_choices), |
|
109 | validator=colander.OneOf(tls_reqcert_choices), | |
111 | widget='select') |
|
110 | widget='select') | |
112 | base_dn = colander.SchemaNode( |
|
111 | base_dn = colander.SchemaNode( | |
113 | colander.String(), |
|
112 | colander.String(), | |
114 | default='', |
|
113 | default='', | |
115 | description=_('Base DN to search (e.g., dc=mydomain,dc=com)'), |
|
114 | description=_('Base DN to search (e.g., dc=mydomain,dc=com)'), | |
116 | missing='', |
|
115 | missing='', | |
117 | title=_('Base DN'), |
|
116 | title=_('Base DN'), | |
118 | widget='string') |
|
117 | widget='string') | |
119 | filter = colander.SchemaNode( |
|
118 | filter = colander.SchemaNode( | |
120 | colander.String(), |
|
119 | colander.String(), | |
121 | default='', |
|
120 | default='', | |
122 | description=_('Filter to narrow results (e.g., ou=Users, etc)'), |
|
121 | description=_('Filter to narrow results (e.g., ou=Users, etc)'), | |
123 | missing='', |
|
122 | missing='', | |
124 | title=_('LDAP Search Filter'), |
|
123 | title=_('LDAP Search Filter'), | |
125 | widget='string') |
|
124 | widget='string') | |
126 | search_scope = colander.SchemaNode( |
|
125 | search_scope = colander.SchemaNode( | |
127 | colander.String(), |
|
126 | colander.String(), | |
128 | default=search_scope_choices[0], |
|
127 | default=search_scope_choices[0], | |
129 | description=_('How deep to search LDAP'), |
|
128 | description=_('How deep to search LDAP'), | |
130 | title=_('LDAP Search Scope'), |
|
129 | title=_('LDAP Search Scope'), | |
131 | validator=colander.OneOf(search_scope_choices), |
|
130 | validator=colander.OneOf(search_scope_choices), | |
132 | widget='select') |
|
131 | widget='select') | |
133 | attr_login = colander.SchemaNode( |
|
132 | attr_login = colander.SchemaNode( | |
134 | colander.String(), |
|
133 | colander.String(), | |
135 | default='', |
|
134 | default='', | |
136 | description=_('LDAP Attribute to map to user name'), |
|
135 | description=_('LDAP Attribute to map to user name'), | |
137 | title=_('Login Attribute'), |
|
136 | title=_('Login Attribute'), | |
138 | missing_msg=_('The LDAP Login attribute of the CN must be specified'), |
|
137 | missing_msg=_('The LDAP Login attribute of the CN must be specified'), | |
139 | widget='string') |
|
138 | widget='string') | |
140 | attr_firstname = colander.SchemaNode( |
|
139 | attr_firstname = colander.SchemaNode( | |
141 | colander.String(), |
|
140 | colander.String(), | |
142 | default='', |
|
141 | default='', | |
143 | description=_('LDAP Attribute to map to first name'), |
|
142 | description=_('LDAP Attribute to map to first name'), | |
144 | missing='', |
|
143 | missing='', | |
145 | title=_('First Name Attribute'), |
|
144 | title=_('First Name Attribute'), | |
146 | widget='string') |
|
145 | widget='string') | |
147 | attr_lastname = colander.SchemaNode( |
|
146 | attr_lastname = colander.SchemaNode( | |
148 | colander.String(), |
|
147 | colander.String(), | |
149 | default='', |
|
148 | default='', | |
150 | description=_('LDAP Attribute to map to last name'), |
|
149 | description=_('LDAP Attribute to map to last name'), | |
151 | missing='', |
|
150 | missing='', | |
152 | title=_('Last Name Attribute'), |
|
151 | title=_('Last Name Attribute'), | |
153 | widget='string') |
|
152 | widget='string') | |
154 | attr_email = colander.SchemaNode( |
|
153 | attr_email = colander.SchemaNode( | |
155 | colander.String(), |
|
154 | colander.String(), | |
156 | default='', |
|
155 | default='', | |
157 | description=_('LDAP Attribute to map to email address'), |
|
156 | description=_('LDAP Attribute to map to email address'), | |
158 | missing='', |
|
157 | missing='', | |
159 | title=_('Email Attribute'), |
|
158 | title=_('Email Attribute'), | |
160 | widget='string') |
|
159 | widget='string') | |
161 |
|
160 | |||
162 |
|
161 | |||
163 | class AuthLdap(object): |
|
162 | class AuthLdap(object): | |
164 |
|
163 | |||
165 | def _build_servers(self): |
|
164 | def _build_servers(self): | |
166 | return ', '.join( |
|
165 | return ', '.join( | |
167 | ["{}://{}:{}".format( |
|
166 | ["{}://{}:{}".format( | |
168 | self.ldap_server_type, host.strip(), self.LDAP_SERVER_PORT) |
|
167 | self.ldap_server_type, host.strip(), self.LDAP_SERVER_PORT) | |
169 | for host in self.SERVER_ADDRESSES]) |
|
168 | for host in self.SERVER_ADDRESSES]) | |
170 |
|
169 | |||
171 | def __init__(self, server, base_dn, port=389, bind_dn='', bind_pass='', |
|
170 | def __init__(self, server, base_dn, port=389, bind_dn='', bind_pass='', | |
172 | tls_kind='PLAIN', tls_reqcert='DEMAND', ldap_version=3, |
|
171 | tls_kind='PLAIN', tls_reqcert='DEMAND', ldap_version=3, | |
173 | search_scope='SUBTREE', attr_login='uid', |
|
172 | search_scope='SUBTREE', attr_login='uid', | |
174 | ldap_filter='(&(objectClass=user)(!(objectClass=computer)))'): |
|
173 | ldap_filter='(&(objectClass=user)(!(objectClass=computer)))'): | |
175 | if isinstance(ldap, Missing): |
|
174 | if isinstance(ldap, Missing): | |
176 | raise LdapImportError("Missing or incompatible ldap library") |
|
175 | raise LdapImportError("Missing or incompatible ldap library") | |
177 |
|
176 | |||
178 | self.ldap_version = ldap_version |
|
177 | self.ldap_version = ldap_version | |
179 | self.ldap_server_type = 'ldap' |
|
178 | self.ldap_server_type = 'ldap' | |
180 |
|
179 | |||
181 | self.TLS_KIND = tls_kind |
|
180 | self.TLS_KIND = tls_kind | |
182 |
|
181 | |||
183 | if self.TLS_KIND == 'LDAPS': |
|
182 | if self.TLS_KIND == 'LDAPS': | |
184 | port = port or 689 |
|
183 | port = port or 689 | |
185 | self.ldap_server_type += 's' |
|
184 | self.ldap_server_type += 's' | |
186 |
|
185 | |||
187 | OPT_X_TLS_DEMAND = 2 |
|
186 | OPT_X_TLS_DEMAND = 2 | |
188 | self.TLS_REQCERT = getattr(ldap, 'OPT_X_TLS_%s' % tls_reqcert, |
|
187 | self.TLS_REQCERT = getattr(ldap, 'OPT_X_TLS_%s' % tls_reqcert, | |
189 | OPT_X_TLS_DEMAND) |
|
188 | OPT_X_TLS_DEMAND) | |
190 | # split server into list |
|
189 | # split server into list | |
191 | self.SERVER_ADDRESSES = server.split(',') |
|
190 | self.SERVER_ADDRESSES = server.split(',') | |
192 | self.LDAP_SERVER_PORT = port |
|
191 | self.LDAP_SERVER_PORT = port | |
193 |
|
192 | |||
194 | # USE FOR READ ONLY BIND TO LDAP SERVER |
|
193 | # USE FOR READ ONLY BIND TO LDAP SERVER | |
195 | self.attr_login = attr_login |
|
194 | self.attr_login = attr_login | |
196 |
|
195 | |||
197 | self.LDAP_BIND_DN = safe_str(bind_dn) |
|
196 | self.LDAP_BIND_DN = safe_str(bind_dn) | |
198 | self.LDAP_BIND_PASS = safe_str(bind_pass) |
|
197 | self.LDAP_BIND_PASS = safe_str(bind_pass) | |
199 | self.LDAP_SERVER = self._build_servers() |
|
198 | self.LDAP_SERVER = self._build_servers() | |
200 | self.SEARCH_SCOPE = getattr(ldap, 'SCOPE_%s' % search_scope) |
|
199 | self.SEARCH_SCOPE = getattr(ldap, 'SCOPE_%s' % search_scope) | |
201 | self.BASE_DN = safe_str(base_dn) |
|
200 | self.BASE_DN = safe_str(base_dn) | |
202 | self.LDAP_FILTER = safe_str(ldap_filter) |
|
201 | self.LDAP_FILTER = safe_str(ldap_filter) | |
203 |
|
202 | |||
204 | def _get_ldap_server(self): |
|
203 | def _get_ldap_server(self): | |
205 | if hasattr(ldap, 'OPT_X_TLS_CACERTDIR'): |
|
204 | if hasattr(ldap, 'OPT_X_TLS_CACERTDIR'): | |
206 | ldap.set_option(ldap.OPT_X_TLS_CACERTDIR, |
|
205 | ldap.set_option(ldap.OPT_X_TLS_CACERTDIR, | |
207 | '/etc/openldap/cacerts') |
|
206 | '/etc/openldap/cacerts') | |
208 | ldap.set_option(ldap.OPT_REFERRALS, ldap.OPT_OFF) |
|
207 | ldap.set_option(ldap.OPT_REFERRALS, ldap.OPT_OFF) | |
209 | ldap.set_option(ldap.OPT_RESTART, ldap.OPT_ON) |
|
208 | ldap.set_option(ldap.OPT_RESTART, ldap.OPT_ON) | |
210 | ldap.set_option(ldap.OPT_TIMEOUT, 20) |
|
209 | ldap.set_option(ldap.OPT_TIMEOUT, 20) | |
211 | ldap.set_option(ldap.OPT_NETWORK_TIMEOUT, 10) |
|
210 | ldap.set_option(ldap.OPT_NETWORK_TIMEOUT, 10) | |
212 | ldap.set_option(ldap.OPT_TIMELIMIT, 15) |
|
211 | ldap.set_option(ldap.OPT_TIMELIMIT, 15) | |
213 | if self.TLS_KIND != 'PLAIN': |
|
212 | if self.TLS_KIND != 'PLAIN': | |
214 | ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, self.TLS_REQCERT) |
|
213 | ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, self.TLS_REQCERT) | |
215 | server = ldap.initialize(self.LDAP_SERVER) |
|
214 | server = ldap.initialize(self.LDAP_SERVER) | |
216 | if self.ldap_version == 2: |
|
215 | if self.ldap_version == 2: | |
217 | server.protocol = ldap.VERSION2 |
|
216 | server.protocol = ldap.VERSION2 | |
218 | else: |
|
217 | else: | |
219 | server.protocol = ldap.VERSION3 |
|
218 | server.protocol = ldap.VERSION3 | |
220 |
|
219 | |||
221 | if self.TLS_KIND == 'START_TLS': |
|
220 | if self.TLS_KIND == 'START_TLS': | |
222 | server.start_tls_s() |
|
221 | server.start_tls_s() | |
223 |
|
222 | |||
224 | if self.LDAP_BIND_DN and self.LDAP_BIND_PASS: |
|
223 | if self.LDAP_BIND_DN and self.LDAP_BIND_PASS: | |
225 | log.debug('Trying simple_bind with password and given DN: %s', |
|
224 | log.debug('Trying simple_bind with password and given DN: %s', | |
226 | self.LDAP_BIND_DN) |
|
225 | self.LDAP_BIND_DN) | |
227 | server.simple_bind_s(self.LDAP_BIND_DN, self.LDAP_BIND_PASS) |
|
226 | server.simple_bind_s(self.LDAP_BIND_DN, self.LDAP_BIND_PASS) | |
228 |
|
227 | |||
229 | return server |
|
228 | return server | |
230 |
|
229 | |||
231 | def get_uid(self, username): |
|
230 | def get_uid(self, username): | |
232 | from rhodecode.lib.helpers import chop_at |
|
231 | from rhodecode.lib.helpers import chop_at | |
233 | uid = username |
|
232 | uid = username | |
234 | for server_addr in self.SERVER_ADDRESSES: |
|
233 | for server_addr in self.SERVER_ADDRESSES: | |
235 | uid = chop_at(username, "@%s" % server_addr) |
|
234 | uid = chop_at(username, "@%s" % server_addr) | |
236 | return uid |
|
235 | return uid | |
237 |
|
236 | |||
238 | def fetch_attrs_from_simple_bind(self, server, dn, username, password): |
|
237 | def fetch_attrs_from_simple_bind(self, server, dn, username, password): | |
239 | try: |
|
238 | try: | |
240 | log.debug('Trying simple bind with %s', dn) |
|
239 | log.debug('Trying simple bind with %s', dn) | |
241 | server.simple_bind_s(dn, safe_str(password)) |
|
240 | server.simple_bind_s(dn, safe_str(password)) | |
242 | user = server.search_ext_s( |
|
241 | user = server.search_ext_s( | |
243 | dn, ldap.SCOPE_BASE, '(objectClass=*)', )[0] |
|
242 | dn, ldap.SCOPE_BASE, '(objectClass=*)', )[0] | |
244 | _, attrs = user |
|
243 | _, attrs = user | |
245 | return attrs |
|
244 | return attrs | |
246 |
|
245 | |||
247 | except ldap.INVALID_CREDENTIALS: |
|
246 | except ldap.INVALID_CREDENTIALS: | |
248 | log.debug( |
|
247 | log.debug( | |
249 | "LDAP rejected password for user '%s': %s, org_exc:", |
|
248 | "LDAP rejected password for user '%s': %s, org_exc:", | |
250 | username, dn, exc_info=True) |
|
249 | username, dn, exc_info=True) | |
251 |
|
250 | |||
252 | def authenticate_ldap(self, username, password): |
|
251 | def authenticate_ldap(self, username, password): | |
253 | """ |
|
252 | """ | |
254 | Authenticate a user via LDAP and return his/her LDAP properties. |
|
253 | Authenticate a user via LDAP and return his/her LDAP properties. | |
255 |
|
254 | |||
256 | Raises AuthenticationError if the credentials are rejected, or |
|
255 | Raises AuthenticationError if the credentials are rejected, or | |
257 | EnvironmentError if the LDAP server can't be reached. |
|
256 | EnvironmentError if the LDAP server can't be reached. | |
258 |
|
257 | |||
259 | :param username: username |
|
258 | :param username: username | |
260 | :param password: password |
|
259 | :param password: password | |
261 | """ |
|
260 | """ | |
262 |
|
261 | |||
263 | uid = self.get_uid(username) |
|
262 | uid = self.get_uid(username) | |
264 |
|
263 | |||
265 | if not password: |
|
264 | if not password: | |
266 | msg = "Authenticating user %s with blank password not allowed" |
|
265 | msg = "Authenticating user %s with blank password not allowed" | |
267 | log.warning(msg, username) |
|
266 | log.warning(msg, username) | |
268 | raise LdapPasswordError(msg) |
|
267 | raise LdapPasswordError(msg) | |
269 | if "," in username: |
|
268 | if "," in username: | |
270 | raise LdapUsernameError("invalid character in username: ,") |
|
269 | raise LdapUsernameError("invalid character in username: ,") | |
271 | try: |
|
270 | try: | |
272 | server = self._get_ldap_server() |
|
271 | server = self._get_ldap_server() | |
273 | filter_ = '(&%s(%s=%s))' % ( |
|
272 | filter_ = '(&%s(%s=%s))' % ( | |
274 | self.LDAP_FILTER, self.attr_login, username) |
|
273 | self.LDAP_FILTER, self.attr_login, username) | |
275 | log.debug("Authenticating %r filter %s at %s", self.BASE_DN, |
|
274 | log.debug("Authenticating %r filter %s at %s", self.BASE_DN, | |
276 | filter_, self.LDAP_SERVER) |
|
275 | filter_, self.LDAP_SERVER) | |
277 | lobjects = server.search_ext_s( |
|
276 | lobjects = server.search_ext_s( | |
278 | self.BASE_DN, self.SEARCH_SCOPE, filter_) |
|
277 | self.BASE_DN, self.SEARCH_SCOPE, filter_) | |
279 |
|
278 | |||
280 | if not lobjects: |
|
279 | if not lobjects: | |
281 | raise ldap.NO_SUCH_OBJECT() |
|
280 | raise ldap.NO_SUCH_OBJECT() | |
282 |
|
281 | |||
283 | for (dn, _attrs) in lobjects: |
|
282 | for (dn, _attrs) in lobjects: | |
284 | if dn is None: |
|
283 | if dn is None: | |
285 | continue |
|
284 | continue | |
286 |
|
285 | |||
287 | user_attrs = self.fetch_attrs_from_simple_bind( |
|
286 | user_attrs = self.fetch_attrs_from_simple_bind( | |
288 | server, dn, username, password) |
|
287 | server, dn, username, password) | |
289 | if user_attrs: |
|
288 | if user_attrs: | |
290 | break |
|
289 | break | |
291 |
|
290 | |||
292 | else: |
|
291 | else: | |
293 | log.debug("No matching LDAP objects for authentication " |
|
292 | log.debug("No matching LDAP objects for authentication " | |
294 | "of '%s' (%s)", uid, username) |
|
293 | "of '%s' (%s)", uid, username) | |
295 | raise LdapPasswordError('Failed to authenticate user ' |
|
294 | raise LdapPasswordError('Failed to authenticate user ' | |
296 | 'with given password') |
|
295 | 'with given password') | |
297 |
|
296 | |||
298 | except ldap.NO_SUCH_OBJECT: |
|
297 | except ldap.NO_SUCH_OBJECT: | |
299 | log.debug("LDAP says no such user '%s' (%s), org_exc:", |
|
298 | log.debug("LDAP says no such user '%s' (%s), org_exc:", | |
300 | uid, username, exc_info=True) |
|
299 | uid, username, exc_info=True) | |
301 | raise LdapUsernameError() |
|
300 | raise LdapUsernameError() | |
302 | except ldap.SERVER_DOWN: |
|
301 | except ldap.SERVER_DOWN: | |
303 | org_exc = traceback.format_exc() |
|
302 | org_exc = traceback.format_exc() | |
304 | raise LdapConnectionError( |
|
303 | raise LdapConnectionError( | |
305 | "LDAP can't access authentication " |
|
304 | "LDAP can't access authentication " | |
306 | "server, org_exc:%s" % org_exc) |
|
305 | "server, org_exc:%s" % org_exc) | |
307 |
|
306 | |||
308 | return dn, user_attrs |
|
307 | return dn, user_attrs | |
309 |
|
308 | |||
310 |
|
309 | |||
311 | class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): |
|
310 | class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): | |
312 | # used to define dynamic binding in the |
|
311 | # used to define dynamic binding in the | |
313 | DYNAMIC_BIND_VAR = '$login' |
|
312 | DYNAMIC_BIND_VAR = '$login' | |
314 |
|
313 | |||
315 | def includeme(self, config): |
|
314 | def includeme(self, config): | |
316 | config.add_authn_plugin(self) |
|
315 | config.add_authn_plugin(self) | |
317 | config.add_authn_resource(self.get_id(), LdapAuthnResource(self)) |
|
316 | config.add_authn_resource(self.get_id(), LdapAuthnResource(self)) | |
318 | config.add_view( |
|
317 | config.add_view( | |
319 | 'rhodecode.authentication.views.AuthnPluginViewBase', |
|
318 | 'rhodecode.authentication.views.AuthnPluginViewBase', | |
320 | attr='settings_get', |
|
319 | attr='settings_get', | |
321 | request_method='GET', |
|
320 | request_method='GET', | |
322 | route_name='auth_home', |
|
321 | route_name='auth_home', | |
323 | context=LdapAuthnResource) |
|
322 | context=LdapAuthnResource) | |
324 | config.add_view( |
|
323 | config.add_view( | |
325 | 'rhodecode.authentication.views.AuthnPluginViewBase', |
|
324 | 'rhodecode.authentication.views.AuthnPluginViewBase', | |
326 | attr='settings_post', |
|
325 | attr='settings_post', | |
327 | request_method='POST', |
|
326 | request_method='POST', | |
328 | route_name='auth_home', |
|
327 | route_name='auth_home', | |
329 | context=LdapAuthnResource) |
|
328 | context=LdapAuthnResource) | |
330 |
|
329 | |||
331 | def get_settings_schema(self): |
|
330 | def get_settings_schema(self): | |
332 | return LdapSettingsSchema() |
|
331 | return LdapSettingsSchema() | |
333 |
|
332 | |||
334 | def get_display_name(self): |
|
333 | def get_display_name(self): | |
335 | return _('LDAP') |
|
334 | return _('LDAP') | |
336 |
|
335 | |||
337 | @hybrid_property |
|
336 | @hybrid_property | |
338 | def name(self): |
|
337 | def name(self): | |
339 | return "ldap" |
|
338 | return "ldap" | |
340 |
|
339 | |||
341 | def use_fake_password(self): |
|
340 | def use_fake_password(self): | |
342 | return True |
|
341 | return True | |
343 |
|
342 | |||
344 | def user_activation_state(self): |
|
343 | def user_activation_state(self): | |
345 | def_user_perms = User.get_default_user().AuthUser.permissions['global'] |
|
344 | def_user_perms = User.get_default_user().AuthUser.permissions['global'] | |
346 | return 'hg.extern_activate.auto' in def_user_perms |
|
345 | return 'hg.extern_activate.auto' in def_user_perms | |
347 |
|
346 | |||
348 | def try_dynamic_binding(self, username, password, current_args): |
|
347 | def try_dynamic_binding(self, username, password, current_args): | |
349 | """ |
|
348 | """ | |
350 | Detects marker inside our original bind, and uses dynamic auth if |
|
349 | Detects marker inside our original bind, and uses dynamic auth if | |
351 | present |
|
350 | present | |
352 | """ |
|
351 | """ | |
353 |
|
352 | |||
354 | org_bind = current_args['bind_dn'] |
|
353 | org_bind = current_args['bind_dn'] | |
355 | passwd = current_args['bind_pass'] |
|
354 | passwd = current_args['bind_pass'] | |
356 |
|
355 | |||
357 | def has_bind_marker(username): |
|
356 | def has_bind_marker(username): | |
358 | if self.DYNAMIC_BIND_VAR in username: |
|
357 | if self.DYNAMIC_BIND_VAR in username: | |
359 | return True |
|
358 | return True | |
360 |
|
359 | |||
361 | # we only passed in user with "special" variable |
|
360 | # we only passed in user with "special" variable | |
362 | if org_bind and has_bind_marker(org_bind) and not passwd: |
|
361 | if org_bind and has_bind_marker(org_bind) and not passwd: | |
363 | log.debug('Using dynamic user/password binding for ldap ' |
|
362 | log.debug('Using dynamic user/password binding for ldap ' | |
364 | 'authentication. Replacing `%s` with username', |
|
363 | 'authentication. Replacing `%s` with username', | |
365 | self.DYNAMIC_BIND_VAR) |
|
364 | self.DYNAMIC_BIND_VAR) | |
366 | current_args['bind_dn'] = org_bind.replace( |
|
365 | current_args['bind_dn'] = org_bind.replace( | |
367 | self.DYNAMIC_BIND_VAR, username) |
|
366 | self.DYNAMIC_BIND_VAR, username) | |
368 | current_args['bind_pass'] = password |
|
367 | current_args['bind_pass'] = password | |
369 |
|
368 | |||
370 | return current_args |
|
369 | return current_args | |
371 |
|
370 | |||
372 | def auth(self, userobj, username, password, settings, **kwargs): |
|
371 | def auth(self, userobj, username, password, settings, **kwargs): | |
373 | """ |
|
372 | """ | |
374 | Given a user object (which may be null), username, a plaintext password, |
|
373 | Given a user object (which may be null), username, a plaintext password, | |
375 | and a settings object (containing all the keys needed as listed in |
|
374 | and a settings object (containing all the keys needed as listed in | |
376 | settings()), authenticate this user's login attempt. |
|
375 | settings()), authenticate this user's login attempt. | |
377 |
|
376 | |||
378 | Return None on failure. On success, return a dictionary of the form: |
|
377 | Return None on failure. On success, return a dictionary of the form: | |
379 |
|
378 | |||
380 | see: RhodeCodeAuthPluginBase.auth_func_attrs |
|
379 | see: RhodeCodeAuthPluginBase.auth_func_attrs | |
381 | This is later validated for correctness |
|
380 | This is later validated for correctness | |
382 | """ |
|
381 | """ | |
383 |
|
382 | |||
384 | if not username or not password: |
|
383 | if not username or not password: | |
385 | log.debug('Empty username or password skipping...') |
|
384 | log.debug('Empty username or password skipping...') | |
386 | return None |
|
385 | return None | |
387 |
|
386 | |||
388 | ldap_args = { |
|
387 | ldap_args = { | |
389 | 'server': settings.get('host', ''), |
|
388 | 'server': settings.get('host', ''), | |
390 | 'base_dn': settings.get('base_dn', ''), |
|
389 | 'base_dn': settings.get('base_dn', ''), | |
391 | 'port': settings.get('port'), |
|
390 | 'port': settings.get('port'), | |
392 | 'bind_dn': settings.get('dn_user'), |
|
391 | 'bind_dn': settings.get('dn_user'), | |
393 | 'bind_pass': settings.get('dn_pass'), |
|
392 | 'bind_pass': settings.get('dn_pass'), | |
394 | 'tls_kind': settings.get('tls_kind'), |
|
393 | 'tls_kind': settings.get('tls_kind'), | |
395 | 'tls_reqcert': settings.get('tls_reqcert'), |
|
394 | 'tls_reqcert': settings.get('tls_reqcert'), | |
396 | 'search_scope': settings.get('search_scope'), |
|
395 | 'search_scope': settings.get('search_scope'), | |
397 | 'attr_login': settings.get('attr_login'), |
|
396 | 'attr_login': settings.get('attr_login'), | |
398 | 'ldap_version': 3, |
|
397 | 'ldap_version': 3, | |
399 | 'ldap_filter': settings.get('filter'), |
|
398 | 'ldap_filter': settings.get('filter'), | |
400 | } |
|
399 | } | |
401 |
|
400 | |||
402 | ldap_attrs = self.try_dynamic_binding(username, password, ldap_args) |
|
401 | ldap_attrs = self.try_dynamic_binding(username, password, ldap_args) | |
403 |
|
402 | |||
404 | log.debug('Checking for ldap authentication.') |
|
403 | log.debug('Checking for ldap authentication.') | |
405 |
|
404 | |||
406 | try: |
|
405 | try: | |
407 | aldap = AuthLdap(**ldap_args) |
|
406 | aldap = AuthLdap(**ldap_args) | |
408 | (user_dn, ldap_attrs) = aldap.authenticate_ldap(username, password) |
|
407 | (user_dn, ldap_attrs) = aldap.authenticate_ldap(username, password) | |
409 | log.debug('Got ldap DN response %s', user_dn) |
|
408 | log.debug('Got ldap DN response %s', user_dn) | |
410 |
|
409 | |||
411 | def get_ldap_attr(k): |
|
410 | def get_ldap_attr(k): | |
412 | return ldap_attrs.get(settings.get(k), [''])[0] |
|
411 | return ldap_attrs.get(settings.get(k), [''])[0] | |
413 |
|
412 | |||
414 | # old attrs fetched from RhodeCode database |
|
413 | # old attrs fetched from RhodeCode database | |
415 | admin = getattr(userobj, 'admin', False) |
|
414 | admin = getattr(userobj, 'admin', False) | |
416 | active = getattr(userobj, 'active', True) |
|
415 | active = getattr(userobj, 'active', True) | |
417 | email = getattr(userobj, 'email', '') |
|
416 | email = getattr(userobj, 'email', '') | |
418 | username = getattr(userobj, 'username', username) |
|
417 | username = getattr(userobj, 'username', username) | |
419 | firstname = getattr(userobj, 'firstname', '') |
|
418 | firstname = getattr(userobj, 'firstname', '') | |
420 | lastname = getattr(userobj, 'lastname', '') |
|
419 | lastname = getattr(userobj, 'lastname', '') | |
421 | extern_type = getattr(userobj, 'extern_type', '') |
|
420 | extern_type = getattr(userobj, 'extern_type', '') | |
422 |
|
421 | |||
423 | groups = [] |
|
422 | groups = [] | |
424 | user_attrs = { |
|
423 | user_attrs = { | |
425 | 'username': username, |
|
424 | 'username': username, | |
426 | 'firstname': safe_unicode( |
|
425 | 'firstname': safe_unicode( | |
427 | get_ldap_attr('attr_firstname') or firstname), |
|
426 | get_ldap_attr('attr_firstname') or firstname), | |
428 | 'lastname': safe_unicode( |
|
427 | 'lastname': safe_unicode( | |
429 | get_ldap_attr('attr_lastname') or lastname), |
|
428 | get_ldap_attr('attr_lastname') or lastname), | |
430 | 'groups': groups, |
|
429 | 'groups': groups, | |
431 | 'email': get_ldap_attr('attr_email' or email), |
|
430 | 'email': get_ldap_attr('attr_email' or email), | |
432 | 'admin': admin, |
|
431 | 'admin': admin, | |
433 | 'active': active, |
|
432 | 'active': active, | |
434 | "active_from_extern": None, |
|
433 | "active_from_extern": None, | |
435 | 'extern_name': user_dn, |
|
434 | 'extern_name': user_dn, | |
436 | 'extern_type': extern_type, |
|
435 | 'extern_type': extern_type, | |
437 | } |
|
436 | } | |
438 |
log.debug('ldap user: |
|
437 | log.debug('ldap user: %s', user_attrs) | |
439 | log.info('user %s authenticated correctly', user_attrs['username']) |
|
438 | log.info('user %s authenticated correctly', user_attrs['username']) | |
440 |
|
439 | |||
441 | return user_attrs |
|
440 | return user_attrs | |
442 |
|
441 | |||
443 | except (LdapUsernameError, LdapPasswordError, LdapImportError): |
|
442 | except (LdapUsernameError, LdapPasswordError, LdapImportError): | |
444 | log.exception("LDAP related exception") |
|
443 | log.exception("LDAP related exception") | |
445 | return None |
|
444 | return None | |
446 | except (Exception,): |
|
445 | except (Exception,): | |
447 | log.exception("Other exception") |
|
446 | log.exception("Other exception") | |
448 | return None |
|
447 | return None |
@@ -1,156 +1,155 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 | # Copyright (C) 2012-2016 RhodeCode GmbH |
|
3 | # Copyright (C) 2012-2016 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
7 | # (only), as published by the Free Software Foundation. |
|
7 | # (only), as published by the Free Software Foundation. | |
8 | # |
|
8 | # | |
9 | # This program is distributed in the hope that it will be useful, |
|
9 | # This program is distributed in the hope that it will be useful, | |
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | # GNU General Public License for more details. |
|
12 | # GNU General Public License for more details. | |
13 | # |
|
13 | # | |
14 | # You should have received a copy of the GNU Affero General Public License |
|
14 | # You should have received a copy of the GNU Affero General Public License | |
15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
16 | # |
|
16 | # | |
17 | # This program is dual-licensed. If you wish to learn more about the |
|
17 | # This program is dual-licensed. If you wish to learn more about the | |
18 | # RhodeCode Enterprise Edition, including its added features, Support services, |
|
18 | # RhodeCode Enterprise Edition, including its added features, Support services, | |
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ |
|
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |
20 | """ |
|
20 | """ | |
21 | RhodeCode authentication library for PAM |
|
21 | RhodeCode authentication library for PAM | |
22 | """ |
|
22 | """ | |
23 |
|
23 | |||
24 | import colander |
|
24 | import colander | |
25 | import grp |
|
25 | import grp | |
26 | import logging |
|
26 | import logging | |
27 | import pam |
|
27 | import pam | |
28 | import pwd |
|
28 | import pwd | |
29 | import re |
|
29 | import re | |
30 | import socket |
|
30 | import socket | |
31 |
|
31 | |||
32 | from pylons.i18n.translation import lazy_ugettext as _ |
|
32 | from pylons.i18n.translation import lazy_ugettext as _ | |
33 | from sqlalchemy.ext.hybrid import hybrid_property |
|
33 | from sqlalchemy.ext.hybrid import hybrid_property | |
34 |
|
34 | |||
35 | from rhodecode.authentication.base import RhodeCodeExternalAuthPlugin |
|
35 | from rhodecode.authentication.base import RhodeCodeExternalAuthPlugin | |
36 | from rhodecode.authentication.schema import AuthnPluginSettingsSchemaBase |
|
36 | from rhodecode.authentication.schema import AuthnPluginSettingsSchemaBase | |
37 | from rhodecode.authentication.routes import AuthnPluginResourceBase |
|
37 | from rhodecode.authentication.routes import AuthnPluginResourceBase | |
38 | from rhodecode.lib.ext_json import formatted_json |
|
|||
39 |
|
38 | |||
40 | log = logging.getLogger(__name__) |
|
39 | log = logging.getLogger(__name__) | |
41 |
|
40 | |||
42 |
|
41 | |||
43 | def plugin_factory(plugin_id, *args, **kwds): |
|
42 | def plugin_factory(plugin_id, *args, **kwds): | |
44 | """ |
|
43 | """ | |
45 | Factory function that is called during plugin discovery. |
|
44 | Factory function that is called during plugin discovery. | |
46 | It returns the plugin instance. |
|
45 | It returns the plugin instance. | |
47 | """ |
|
46 | """ | |
48 | plugin = RhodeCodeAuthPlugin(plugin_id) |
|
47 | plugin = RhodeCodeAuthPlugin(plugin_id) | |
49 | return plugin |
|
48 | return plugin | |
50 |
|
49 | |||
51 |
|
50 | |||
52 | class PamAuthnResource(AuthnPluginResourceBase): |
|
51 | class PamAuthnResource(AuthnPluginResourceBase): | |
53 | pass |
|
52 | pass | |
54 |
|
53 | |||
55 |
|
54 | |||
56 | class PamSettingsSchema(AuthnPluginSettingsSchemaBase): |
|
55 | class PamSettingsSchema(AuthnPluginSettingsSchemaBase): | |
57 | service = colander.SchemaNode( |
|
56 | service = colander.SchemaNode( | |
58 | colander.String(), |
|
57 | colander.String(), | |
59 | default='login', |
|
58 | default='login', | |
60 | description=_('PAM service name to use for authentication.'), |
|
59 | description=_('PAM service name to use for authentication.'), | |
61 | title=_('PAM service name'), |
|
60 | title=_('PAM service name'), | |
62 | widget='string') |
|
61 | widget='string') | |
63 | gecos = colander.SchemaNode( |
|
62 | gecos = colander.SchemaNode( | |
64 | colander.String(), |
|
63 | colander.String(), | |
65 | default='(?P<last_name>.+),\s*(?P<first_name>\w+)', |
|
64 | default='(?P<last_name>.+),\s*(?P<first_name>\w+)', | |
66 | description=_('Regular expression for extracting user name/email etc. ' |
|
65 | description=_('Regular expression for extracting user name/email etc. ' | |
67 | 'from Unix userinfo.'), |
|
66 | 'from Unix userinfo.'), | |
68 | title=_('Gecos Regex'), |
|
67 | title=_('Gecos Regex'), | |
69 | widget='string') |
|
68 | widget='string') | |
70 |
|
69 | |||
71 |
|
70 | |||
72 | class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): |
|
71 | class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): | |
73 | # PAM authentication can be slow. Repository operations involve a lot of |
|
72 | # PAM authentication can be slow. Repository operations involve a lot of | |
74 | # auth calls. Little caching helps speedup push/pull operations significantly |
|
73 | # auth calls. Little caching helps speedup push/pull operations significantly | |
75 | AUTH_CACHE_TTL = 4 |
|
74 | AUTH_CACHE_TTL = 4 | |
76 |
|
75 | |||
77 | def includeme(self, config): |
|
76 | def includeme(self, config): | |
78 | config.add_authn_plugin(self) |
|
77 | config.add_authn_plugin(self) | |
79 | config.add_authn_resource(self.get_id(), PamAuthnResource(self)) |
|
78 | config.add_authn_resource(self.get_id(), PamAuthnResource(self)) | |
80 | config.add_view( |
|
79 | config.add_view( | |
81 | 'rhodecode.authentication.views.AuthnPluginViewBase', |
|
80 | 'rhodecode.authentication.views.AuthnPluginViewBase', | |
82 | attr='settings_get', |
|
81 | attr='settings_get', | |
83 | request_method='GET', |
|
82 | request_method='GET', | |
84 | route_name='auth_home', |
|
83 | route_name='auth_home', | |
85 | context=PamAuthnResource) |
|
84 | context=PamAuthnResource) | |
86 | config.add_view( |
|
85 | config.add_view( | |
87 | 'rhodecode.authentication.views.AuthnPluginViewBase', |
|
86 | 'rhodecode.authentication.views.AuthnPluginViewBase', | |
88 | attr='settings_post', |
|
87 | attr='settings_post', | |
89 | request_method='POST', |
|
88 | request_method='POST', | |
90 | route_name='auth_home', |
|
89 | route_name='auth_home', | |
91 | context=PamAuthnResource) |
|
90 | context=PamAuthnResource) | |
92 |
|
91 | |||
93 | def get_display_name(self): |
|
92 | def get_display_name(self): | |
94 | return _('PAM') |
|
93 | return _('PAM') | |
95 |
|
94 | |||
96 | @hybrid_property |
|
95 | @hybrid_property | |
97 | def name(self): |
|
96 | def name(self): | |
98 | return "pam" |
|
97 | return "pam" | |
99 |
|
98 | |||
100 | def get_settings_schema(self): |
|
99 | def get_settings_schema(self): | |
101 | return PamSettingsSchema() |
|
100 | return PamSettingsSchema() | |
102 |
|
101 | |||
103 | def use_fake_password(self): |
|
102 | def use_fake_password(self): | |
104 | return True |
|
103 | return True | |
105 |
|
104 | |||
106 | def auth(self, userobj, username, password, settings, **kwargs): |
|
105 | def auth(self, userobj, username, password, settings, **kwargs): | |
107 | if not username or not password: |
|
106 | if not username or not password: | |
108 | log.debug('Empty username or password skipping...') |
|
107 | log.debug('Empty username or password skipping...') | |
109 | return None |
|
108 | return None | |
110 |
|
109 | |||
111 | auth_result = pam.authenticate(username, password, settings["service"]) |
|
110 | auth_result = pam.authenticate(username, password, settings["service"]) | |
112 |
|
111 | |||
113 | if not auth_result: |
|
112 | if not auth_result: | |
114 | log.error("PAM was unable to authenticate user: %s" % (username, )) |
|
113 | log.error("PAM was unable to authenticate user: %s" % (username, )) | |
115 | return None |
|
114 | return None | |
116 |
|
115 | |||
117 | log.debug('Got PAM response %s' % (auth_result, )) |
|
116 | log.debug('Got PAM response %s' % (auth_result, )) | |
118 |
|
117 | |||
119 | # old attrs fetched from RhodeCode database |
|
118 | # old attrs fetched from RhodeCode database | |
120 | default_email = "%s@%s" % (username, socket.gethostname()) |
|
119 | default_email = "%s@%s" % (username, socket.gethostname()) | |
121 | admin = getattr(userobj, 'admin', False) |
|
120 | admin = getattr(userobj, 'admin', False) | |
122 | active = getattr(userobj, 'active', True) |
|
121 | active = getattr(userobj, 'active', True) | |
123 | email = getattr(userobj, 'email', '') or default_email |
|
122 | email = getattr(userobj, 'email', '') or default_email | |
124 | username = getattr(userobj, 'username', username) |
|
123 | username = getattr(userobj, 'username', username) | |
125 | firstname = getattr(userobj, 'firstname', '') |
|
124 | firstname = getattr(userobj, 'firstname', '') | |
126 | lastname = getattr(userobj, 'lastname', '') |
|
125 | lastname = getattr(userobj, 'lastname', '') | |
127 | extern_type = getattr(userobj, 'extern_type', '') |
|
126 | extern_type = getattr(userobj, 'extern_type', '') | |
128 |
|
127 | |||
129 | user_attrs = { |
|
128 | user_attrs = { | |
130 | 'username': username, |
|
129 | 'username': username, | |
131 | 'firstname': firstname, |
|
130 | 'firstname': firstname, | |
132 | 'lastname': lastname, |
|
131 | 'lastname': lastname, | |
133 | 'groups': [g.gr_name for g in grp.getgrall() |
|
132 | 'groups': [g.gr_name for g in grp.getgrall() | |
134 | if username in g.gr_mem], |
|
133 | if username in g.gr_mem], | |
135 | 'email': email, |
|
134 | 'email': email, | |
136 | 'admin': admin, |
|
135 | 'admin': admin, | |
137 | 'active': active, |
|
136 | 'active': active, | |
138 | 'active_from_extern': None, |
|
137 | 'active_from_extern': None, | |
139 | 'extern_name': username, |
|
138 | 'extern_name': username, | |
140 | 'extern_type': extern_type, |
|
139 | 'extern_type': extern_type, | |
141 | } |
|
140 | } | |
142 |
|
141 | |||
143 | try: |
|
142 | try: | |
144 | user_data = pwd.getpwnam(username) |
|
143 | user_data = pwd.getpwnam(username) | |
145 | regex = settings["gecos"] |
|
144 | regex = settings["gecos"] | |
146 | match = re.search(regex, user_data.pw_gecos) |
|
145 | match = re.search(regex, user_data.pw_gecos) | |
147 | if match: |
|
146 | if match: | |
148 | user_attrs["firstname"] = match.group('first_name') |
|
147 | user_attrs["firstname"] = match.group('first_name') | |
149 | user_attrs["lastname"] = match.group('last_name') |
|
148 | user_attrs["lastname"] = match.group('last_name') | |
150 | except Exception: |
|
149 | except Exception: | |
151 | log.warning("Cannot extract additional info for PAM user") |
|
150 | log.warning("Cannot extract additional info for PAM user") | |
152 | pass |
|
151 | pass | |
153 |
|
152 | |||
154 |
log.debug("pamuser: |
|
153 | log.debug("pamuser: %s", user_attrs) | |
155 | log.info('user %s authenticated correctly' % user_attrs['username']) |
|
154 | log.info('user %s authenticated correctly' % user_attrs['username']) | |
156 | return user_attrs |
|
155 | return user_attrs |
@@ -1,440 +1,441 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 | # Copyright (C) 2014-2016 RhodeCode GmbH |
|
3 | # Copyright (C) 2014-2016 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
7 | # (only), as published by the Free Software Foundation. |
|
7 | # (only), as published by the Free Software Foundation. | |
8 | # |
|
8 | # | |
9 | # This program is distributed in the hope that it will be useful, |
|
9 | # This program is distributed in the hope that it will be useful, | |
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | # GNU General Public License for more details. |
|
12 | # GNU General Public License for more details. | |
13 | # |
|
13 | # | |
14 | # You should have received a copy of the GNU Affero General Public License |
|
14 | # You should have received a copy of the GNU Affero General Public License | |
15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
16 | # |
|
16 | # | |
17 | # This program is dual-licensed. If you wish to learn more about the |
|
17 | # This program is dual-licensed. If you wish to learn more about the | |
18 | # RhodeCode Enterprise Edition, including its added features, Support services, |
|
18 | # RhodeCode Enterprise Edition, including its added features, Support services, | |
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ |
|
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |
20 |
|
20 | |||
21 | """ |
|
21 | """ | |
22 | SimpleVCS middleware for handling protocol request (push/clone etc.) |
|
22 | SimpleVCS middleware for handling protocol request (push/clone etc.) | |
23 | It's implemented with basic auth function |
|
23 | It's implemented with basic auth function | |
24 | """ |
|
24 | """ | |
25 |
|
25 | |||
26 | import os |
|
26 | import os | |
27 | import logging |
|
27 | import logging | |
28 | import importlib |
|
28 | import importlib | |
29 | from functools import wraps |
|
29 | from functools import wraps | |
30 |
|
30 | |||
31 | from paste.httpheaders import REMOTE_USER, AUTH_TYPE |
|
31 | from paste.httpheaders import REMOTE_USER, AUTH_TYPE | |
32 | from webob.exc import ( |
|
32 | from webob.exc import ( | |
33 | HTTPNotFound, HTTPForbidden, HTTPNotAcceptable, HTTPInternalServerError) |
|
33 | HTTPNotFound, HTTPForbidden, HTTPNotAcceptable, HTTPInternalServerError) | |
34 |
|
34 | |||
35 | import rhodecode |
|
35 | import rhodecode | |
36 | from rhodecode.authentication.base import authenticate, VCS_TYPE |
|
36 | from rhodecode.authentication.base import authenticate, VCS_TYPE | |
37 | from rhodecode.lib.auth import AuthUser, HasPermissionAnyMiddleware |
|
37 | from rhodecode.lib.auth import AuthUser, HasPermissionAnyMiddleware | |
38 | from rhodecode.lib.base import BasicAuth, get_ip_addr, vcs_operation_context |
|
38 | from rhodecode.lib.base import BasicAuth, get_ip_addr, vcs_operation_context | |
39 | from rhodecode.lib.exceptions import ( |
|
39 | from rhodecode.lib.exceptions import ( | |
40 | HTTPLockedRC, HTTPRequirementError, UserCreationError, |
|
40 | HTTPLockedRC, HTTPRequirementError, UserCreationError, | |
41 | NotAllowedToCreateUserError) |
|
41 | NotAllowedToCreateUserError) | |
42 | from rhodecode.lib.hooks_daemon import prepare_callback_daemon |
|
42 | from rhodecode.lib.hooks_daemon import prepare_callback_daemon | |
43 | from rhodecode.lib.middleware import appenlight |
|
43 | from rhodecode.lib.middleware import appenlight | |
44 | from rhodecode.lib.middleware.utils import scm_app |
|
44 | from rhodecode.lib.middleware.utils import scm_app | |
45 | from rhodecode.lib.utils import is_valid_repo |
|
45 | from rhodecode.lib.utils import is_valid_repo | |
46 | from rhodecode.lib.utils2 import safe_str, fix_PATH, str2bool |
|
46 | from rhodecode.lib.utils2 import safe_str, fix_PATH, str2bool | |
47 | from rhodecode.model import meta |
|
47 | from rhodecode.model import meta | |
48 | from rhodecode.model.db import User, Repository |
|
48 | from rhodecode.model.db import User, Repository | |
49 | from rhodecode.model.scm import ScmModel |
|
49 | from rhodecode.model.scm import ScmModel | |
50 | from rhodecode.model.settings import SettingsModel |
|
50 | from rhodecode.model.settings import SettingsModel | |
51 |
|
51 | |||
52 | log = logging.getLogger(__name__) |
|
52 | log = logging.getLogger(__name__) | |
53 |
|
53 | |||
54 |
|
54 | |||
55 | def initialize_generator(factory): |
|
55 | def initialize_generator(factory): | |
56 | """ |
|
56 | """ | |
57 | Initializes the returned generator by draining its first element. |
|
57 | Initializes the returned generator by draining its first element. | |
58 |
|
58 | |||
59 | This can be used to give a generator an initializer, which is the code |
|
59 | This can be used to give a generator an initializer, which is the code | |
60 | up to the first yield statement. This decorator enforces that the first |
|
60 | up to the first yield statement. This decorator enforces that the first | |
61 | produced element has the value ``"__init__"`` to make its special |
|
61 | produced element has the value ``"__init__"`` to make its special | |
62 | purpose very explicit in the using code. |
|
62 | purpose very explicit in the using code. | |
63 | """ |
|
63 | """ | |
64 |
|
64 | |||
65 | @wraps(factory) |
|
65 | @wraps(factory) | |
66 | def wrapper(*args, **kwargs): |
|
66 | def wrapper(*args, **kwargs): | |
67 | gen = factory(*args, **kwargs) |
|
67 | gen = factory(*args, **kwargs) | |
68 | try: |
|
68 | try: | |
69 | init = gen.next() |
|
69 | init = gen.next() | |
70 | except StopIteration: |
|
70 | except StopIteration: | |
71 | raise ValueError('Generator must yield at least one element.') |
|
71 | raise ValueError('Generator must yield at least one element.') | |
72 | if init != "__init__": |
|
72 | if init != "__init__": | |
73 | raise ValueError('First yielded element must be "__init__".') |
|
73 | raise ValueError('First yielded element must be "__init__".') | |
74 | return gen |
|
74 | return gen | |
75 | return wrapper |
|
75 | return wrapper | |
76 |
|
76 | |||
77 |
|
77 | |||
78 | class SimpleVCS(object): |
|
78 | class SimpleVCS(object): | |
79 | """Common functionality for SCM HTTP handlers.""" |
|
79 | """Common functionality for SCM HTTP handlers.""" | |
80 |
|
80 | |||
81 | SCM = 'unknown' |
|
81 | SCM = 'unknown' | |
82 |
|
82 | |||
83 | def __init__(self, application, config): |
|
83 | def __init__(self, application, config): | |
84 | self.application = application |
|
84 | self.application = application | |
85 | self.config = config |
|
85 | self.config = config | |
86 | # base path of repo locations |
|
86 | # base path of repo locations | |
87 | self.basepath = self.config['base_path'] |
|
87 | self.basepath = self.config['base_path'] | |
88 | # authenticate this VCS request using authfunc |
|
88 | # authenticate this VCS request using authfunc | |
89 | auth_ret_code_detection = \ |
|
89 | auth_ret_code_detection = \ | |
90 | str2bool(self.config.get('auth_ret_code_detection', False)) |
|
90 | str2bool(self.config.get('auth_ret_code_detection', False)) | |
91 | self.authenticate = BasicAuth('', authenticate, |
|
91 | self.authenticate = BasicAuth('', authenticate, | |
92 | config.get('auth_ret_code'), |
|
92 | config.get('auth_ret_code'), | |
93 | auth_ret_code_detection) |
|
93 | auth_ret_code_detection) | |
94 | self.ip_addr = '0.0.0.0' |
|
94 | self.ip_addr = '0.0.0.0' | |
95 |
|
95 | |||
96 | @property |
|
96 | @property | |
97 | def scm_app(self): |
|
97 | def scm_app(self): | |
98 | custom_implementation = self.config.get('vcs.scm_app_implementation') |
|
98 | custom_implementation = self.config.get('vcs.scm_app_implementation') | |
99 | if custom_implementation: |
|
99 | if custom_implementation: | |
100 | log.info( |
|
100 | log.info( | |
101 | "Using custom implementation of scm_app: %s", |
|
101 | "Using custom implementation of scm_app: %s", | |
102 | custom_implementation) |
|
102 | custom_implementation) | |
103 | scm_app_impl = importlib.import_module(custom_implementation) |
|
103 | scm_app_impl = importlib.import_module(custom_implementation) | |
104 | else: |
|
104 | else: | |
105 | scm_app_impl = scm_app |
|
105 | scm_app_impl = scm_app | |
106 | return scm_app_impl |
|
106 | return scm_app_impl | |
107 |
|
107 | |||
108 | def _get_by_id(self, repo_name): |
|
108 | def _get_by_id(self, repo_name): | |
109 | """ |
|
109 | """ | |
110 | Gets a special pattern _<ID> from clone url and tries to replace it |
|
110 | Gets a special pattern _<ID> from clone url and tries to replace it | |
111 | with a repository_name for support of _<ID> non changable urls |
|
111 | with a repository_name for support of _<ID> non changable urls | |
112 |
|
112 | |||
113 | :param repo_name: |
|
113 | :param repo_name: | |
114 | """ |
|
114 | """ | |
115 |
|
115 | |||
116 | data = repo_name.split('/') |
|
116 | data = repo_name.split('/') | |
117 | if len(data) >= 2: |
|
117 | if len(data) >= 2: | |
118 | from rhodecode.model.repo import RepoModel |
|
118 | from rhodecode.model.repo import RepoModel | |
119 | by_id_match = RepoModel().get_repo_by_id(repo_name) |
|
119 | by_id_match = RepoModel().get_repo_by_id(repo_name) | |
120 | if by_id_match: |
|
120 | if by_id_match: | |
121 | data[1] = by_id_match.repo_name |
|
121 | data[1] = by_id_match.repo_name | |
122 |
|
122 | |||
123 | return safe_str('/'.join(data)) |
|
123 | return safe_str('/'.join(data)) | |
124 |
|
124 | |||
125 | def _invalidate_cache(self, repo_name): |
|
125 | def _invalidate_cache(self, repo_name): | |
126 | """ |
|
126 | """ | |
127 | Set's cache for this repository for invalidation on next access |
|
127 | Set's cache for this repository for invalidation on next access | |
128 |
|
128 | |||
129 | :param repo_name: full repo name, also a cache key |
|
129 | :param repo_name: full repo name, also a cache key | |
130 | """ |
|
130 | """ | |
131 | ScmModel().mark_for_invalidation(repo_name) |
|
131 | ScmModel().mark_for_invalidation(repo_name) | |
132 |
|
132 | |||
133 | def is_valid_and_existing_repo(self, repo_name, base_path, scm_type): |
|
133 | def is_valid_and_existing_repo(self, repo_name, base_path, scm_type): | |
134 | db_repo = Repository.get_by_repo_name(repo_name) |
|
134 | db_repo = Repository.get_by_repo_name(repo_name) | |
135 | if not db_repo: |
|
135 | if not db_repo: | |
136 |
log.debug('Repository `%s` not found inside the database.' |
|
136 | log.debug('Repository `%s` not found inside the database.', | |
|
137 | repo_name) | |||
137 | return False |
|
138 | return False | |
138 |
|
139 | |||
139 | if db_repo.repo_type != scm_type: |
|
140 | if db_repo.repo_type != scm_type: | |
140 | log.warning( |
|
141 | log.warning( | |
141 | 'Repository `%s` have incorrect scm_type, expected %s got %s', |
|
142 | 'Repository `%s` have incorrect scm_type, expected %s got %s', | |
142 | repo_name, db_repo.repo_type, scm_type) |
|
143 | repo_name, db_repo.repo_type, scm_type) | |
143 | return False |
|
144 | return False | |
144 |
|
145 | |||
145 | return is_valid_repo(repo_name, base_path, expect_scm=scm_type) |
|
146 | return is_valid_repo(repo_name, base_path, expect_scm=scm_type) | |
146 |
|
147 | |||
147 | def valid_and_active_user(self, user): |
|
148 | def valid_and_active_user(self, user): | |
148 | """ |
|
149 | """ | |
149 | Checks if that user is not empty, and if it's actually object it checks |
|
150 | Checks if that user is not empty, and if it's actually object it checks | |
150 | if he's active. |
|
151 | if he's active. | |
151 |
|
152 | |||
152 | :param user: user object or None |
|
153 | :param user: user object or None | |
153 | :return: boolean |
|
154 | :return: boolean | |
154 | """ |
|
155 | """ | |
155 | if user is None: |
|
156 | if user is None: | |
156 | return False |
|
157 | return False | |
157 |
|
158 | |||
158 | elif user.active: |
|
159 | elif user.active: | |
159 | return True |
|
160 | return True | |
160 |
|
161 | |||
161 | return False |
|
162 | return False | |
162 |
|
163 | |||
163 | def _check_permission(self, action, user, repo_name, ip_addr=None): |
|
164 | def _check_permission(self, action, user, repo_name, ip_addr=None): | |
164 | """ |
|
165 | """ | |
165 | Checks permissions using action (push/pull) user and repository |
|
166 | Checks permissions using action (push/pull) user and repository | |
166 | name |
|
167 | name | |
167 |
|
168 | |||
168 | :param action: push or pull action |
|
169 | :param action: push or pull action | |
169 | :param user: user instance |
|
170 | :param user: user instance | |
170 | :param repo_name: repository name |
|
171 | :param repo_name: repository name | |
171 | """ |
|
172 | """ | |
172 | # check IP |
|
173 | # check IP | |
173 | inherit = user.inherit_default_permissions |
|
174 | inherit = user.inherit_default_permissions | |
174 | ip_allowed = AuthUser.check_ip_allowed(user.user_id, ip_addr, |
|
175 | ip_allowed = AuthUser.check_ip_allowed(user.user_id, ip_addr, | |
175 | inherit_from_default=inherit) |
|
176 | inherit_from_default=inherit) | |
176 | if ip_allowed: |
|
177 | if ip_allowed: | |
177 | log.info('Access for IP:%s allowed', ip_addr) |
|
178 | log.info('Access for IP:%s allowed', ip_addr) | |
178 | else: |
|
179 | else: | |
179 | return False |
|
180 | return False | |
180 |
|
181 | |||
181 | if action == 'push': |
|
182 | if action == 'push': | |
182 | if not HasPermissionAnyMiddleware('repository.write', |
|
183 | if not HasPermissionAnyMiddleware('repository.write', | |
183 | 'repository.admin')(user, |
|
184 | 'repository.admin')(user, | |
184 | repo_name): |
|
185 | repo_name): | |
185 | return False |
|
186 | return False | |
186 |
|
187 | |||
187 | else: |
|
188 | else: | |
188 | # any other action need at least read permission |
|
189 | # any other action need at least read permission | |
189 | if not HasPermissionAnyMiddleware('repository.read', |
|
190 | if not HasPermissionAnyMiddleware('repository.read', | |
190 | 'repository.write', |
|
191 | 'repository.write', | |
191 | 'repository.admin')(user, |
|
192 | 'repository.admin')(user, | |
192 | repo_name): |
|
193 | repo_name): | |
193 | return False |
|
194 | return False | |
194 |
|
195 | |||
195 | return True |
|
196 | return True | |
196 |
|
197 | |||
197 | def _check_ssl(self, environ, start_response): |
|
198 | def _check_ssl(self, environ, start_response): | |
198 | """ |
|
199 | """ | |
199 | Checks the SSL check flag and returns False if SSL is not present |
|
200 | Checks the SSL check flag and returns False if SSL is not present | |
200 | and required True otherwise |
|
201 | and required True otherwise | |
201 | """ |
|
202 | """ | |
202 | org_proto = environ['wsgi._org_proto'] |
|
203 | org_proto = environ['wsgi._org_proto'] | |
203 | # check if we have SSL required ! if not it's a bad request ! |
|
204 | # check if we have SSL required ! if not it's a bad request ! | |
204 | require_ssl = str2bool( |
|
205 | require_ssl = str2bool( | |
205 | SettingsModel().get_ui_by_key('push_ssl').ui_value) |
|
206 | SettingsModel().get_ui_by_key('push_ssl').ui_value) | |
206 | if require_ssl and org_proto == 'http': |
|
207 | if require_ssl and org_proto == 'http': | |
207 | log.debug('proto is %s and SSL is required BAD REQUEST !', |
|
208 | log.debug('proto is %s and SSL is required BAD REQUEST !', | |
208 | org_proto) |
|
209 | org_proto) | |
209 | return False |
|
210 | return False | |
210 | return True |
|
211 | return True | |
211 |
|
212 | |||
212 | def __call__(self, environ, start_response): |
|
213 | def __call__(self, environ, start_response): | |
213 | try: |
|
214 | try: | |
214 | return self._handle_request(environ, start_response) |
|
215 | return self._handle_request(environ, start_response) | |
215 | except Exception: |
|
216 | except Exception: | |
216 | log.exception("Exception while handling request") |
|
217 | log.exception("Exception while handling request") | |
217 | appenlight.track_exception(environ) |
|
218 | appenlight.track_exception(environ) | |
218 | return HTTPInternalServerError()(environ, start_response) |
|
219 | return HTTPInternalServerError()(environ, start_response) | |
219 | finally: |
|
220 | finally: | |
220 | meta.Session.remove() |
|
221 | meta.Session.remove() | |
221 |
|
222 | |||
222 | def _handle_request(self, environ, start_response): |
|
223 | def _handle_request(self, environ, start_response): | |
223 |
|
224 | |||
224 | if not self._check_ssl(environ, start_response): |
|
225 | if not self._check_ssl(environ, start_response): | |
225 | reason = ('SSL required, while RhodeCode was unable ' |
|
226 | reason = ('SSL required, while RhodeCode was unable ' | |
226 | 'to detect this as SSL request') |
|
227 | 'to detect this as SSL request') | |
227 | log.debug('User not allowed to proceed, %s', reason) |
|
228 | log.debug('User not allowed to proceed, %s', reason) | |
228 | return HTTPNotAcceptable(reason)(environ, start_response) |
|
229 | return HTTPNotAcceptable(reason)(environ, start_response) | |
229 |
|
230 | |||
230 | ip_addr = get_ip_addr(environ) |
|
231 | ip_addr = get_ip_addr(environ) | |
231 | username = None |
|
232 | username = None | |
232 |
|
233 | |||
233 | # skip passing error to error controller |
|
234 | # skip passing error to error controller | |
234 | environ['pylons.status_code_redirect'] = True |
|
235 | environ['pylons.status_code_redirect'] = True | |
235 |
|
236 | |||
236 | # ====================================================================== |
|
237 | # ====================================================================== | |
237 | # EXTRACT REPOSITORY NAME FROM ENV |
|
238 | # EXTRACT REPOSITORY NAME FROM ENV | |
238 | # ====================================================================== |
|
239 | # ====================================================================== | |
239 | environ['PATH_INFO'] = self._get_by_id(environ['PATH_INFO']) |
|
240 | environ['PATH_INFO'] = self._get_by_id(environ['PATH_INFO']) | |
240 | repo_name = self._get_repository_name(environ) |
|
241 | repo_name = self._get_repository_name(environ) | |
241 | environ['REPO_NAME'] = repo_name |
|
242 | environ['REPO_NAME'] = repo_name | |
242 | log.debug('Extracted repo name is %s', repo_name) |
|
243 | log.debug('Extracted repo name is %s', repo_name) | |
243 |
|
244 | |||
244 | # check for type, presence in database and on filesystem |
|
245 | # check for type, presence in database and on filesystem | |
245 | if not self.is_valid_and_existing_repo( |
|
246 | if not self.is_valid_and_existing_repo( | |
246 | repo_name, self.basepath, self.SCM): |
|
247 | repo_name, self.basepath, self.SCM): | |
247 | return HTTPNotFound()(environ, start_response) |
|
248 | return HTTPNotFound()(environ, start_response) | |
248 |
|
249 | |||
249 | # ====================================================================== |
|
250 | # ====================================================================== | |
250 | # GET ACTION PULL or PUSH |
|
251 | # GET ACTION PULL or PUSH | |
251 | # ====================================================================== |
|
252 | # ====================================================================== | |
252 | action = self._get_action(environ) |
|
253 | action = self._get_action(environ) | |
253 |
|
254 | |||
254 | # ====================================================================== |
|
255 | # ====================================================================== | |
255 | # CHECK ANONYMOUS PERMISSION |
|
256 | # CHECK ANONYMOUS PERMISSION | |
256 | # ====================================================================== |
|
257 | # ====================================================================== | |
257 | if action in ['pull', 'push']: |
|
258 | if action in ['pull', 'push']: | |
258 | anonymous_user = User.get_default_user() |
|
259 | anonymous_user = User.get_default_user() | |
259 | username = anonymous_user.username |
|
260 | username = anonymous_user.username | |
260 | if anonymous_user.active: |
|
261 | if anonymous_user.active: | |
261 | # ONLY check permissions if the user is activated |
|
262 | # ONLY check permissions if the user is activated | |
262 | anonymous_perm = self._check_permission( |
|
263 | anonymous_perm = self._check_permission( | |
263 | action, anonymous_user, repo_name, ip_addr) |
|
264 | action, anonymous_user, repo_name, ip_addr) | |
264 | else: |
|
265 | else: | |
265 | anonymous_perm = False |
|
266 | anonymous_perm = False | |
266 |
|
267 | |||
267 | if not anonymous_user.active or not anonymous_perm: |
|
268 | if not anonymous_user.active or not anonymous_perm: | |
268 | if not anonymous_user.active: |
|
269 | if not anonymous_user.active: | |
269 | log.debug('Anonymous access is disabled, running ' |
|
270 | log.debug('Anonymous access is disabled, running ' | |
270 | 'authentication') |
|
271 | 'authentication') | |
271 |
|
272 | |||
272 | if not anonymous_perm: |
|
273 | if not anonymous_perm: | |
273 | log.debug('Not enough credentials to access this ' |
|
274 | log.debug('Not enough credentials to access this ' | |
274 | 'repository as anonymous user') |
|
275 | 'repository as anonymous user') | |
275 |
|
276 | |||
276 | username = None |
|
277 | username = None | |
277 | # ============================================================== |
|
278 | # ============================================================== | |
278 | # DEFAULT PERM FAILED OR ANONYMOUS ACCESS IS DISABLED SO WE |
|
279 | # DEFAULT PERM FAILED OR ANONYMOUS ACCESS IS DISABLED SO WE | |
279 | # NEED TO AUTHENTICATE AND ASK FOR AUTH USER PERMISSIONS |
|
280 | # NEED TO AUTHENTICATE AND ASK FOR AUTH USER PERMISSIONS | |
280 | # ============================================================== |
|
281 | # ============================================================== | |
281 |
|
282 | |||
282 | # try to auth based on environ, container auth methods |
|
283 | # try to auth based on environ, container auth methods | |
283 | log.debug('Running PRE-AUTH for container based authentication') |
|
284 | log.debug('Running PRE-AUTH for container based authentication') | |
284 | pre_auth = authenticate('', '', environ,VCS_TYPE) |
|
285 | pre_auth = authenticate('', '', environ,VCS_TYPE) | |
285 | if pre_auth and pre_auth.get('username'): |
|
286 | if pre_auth and pre_auth.get('username'): | |
286 | username = pre_auth['username'] |
|
287 | username = pre_auth['username'] | |
287 | log.debug('PRE-AUTH got %s as username', username) |
|
288 | log.debug('PRE-AUTH got %s as username', username) | |
288 |
|
289 | |||
289 | # If not authenticated by the container, running basic auth |
|
290 | # If not authenticated by the container, running basic auth | |
290 | if not username: |
|
291 | if not username: | |
291 | self.authenticate.realm = \ |
|
292 | self.authenticate.realm = \ | |
292 | safe_str(self.config['rhodecode_realm']) |
|
293 | safe_str(self.config['rhodecode_realm']) | |
293 |
|
294 | |||
294 | try: |
|
295 | try: | |
295 | result = self.authenticate(environ) |
|
296 | result = self.authenticate(environ) | |
296 | except (UserCreationError, NotAllowedToCreateUserError) as e: |
|
297 | except (UserCreationError, NotAllowedToCreateUserError) as e: | |
297 | log.error(e) |
|
298 | log.error(e) | |
298 | reason = safe_str(e) |
|
299 | reason = safe_str(e) | |
299 | return HTTPNotAcceptable(reason)(environ, start_response) |
|
300 | return HTTPNotAcceptable(reason)(environ, start_response) | |
300 |
|
301 | |||
301 | if isinstance(result, str): |
|
302 | if isinstance(result, str): | |
302 | AUTH_TYPE.update(environ, 'basic') |
|
303 | AUTH_TYPE.update(environ, 'basic') | |
303 | REMOTE_USER.update(environ, result) |
|
304 | REMOTE_USER.update(environ, result) | |
304 | username = result |
|
305 | username = result | |
305 | else: |
|
306 | else: | |
306 | return result.wsgi_application(environ, start_response) |
|
307 | return result.wsgi_application(environ, start_response) | |
307 |
|
308 | |||
308 | # ============================================================== |
|
309 | # ============================================================== | |
309 | # CHECK PERMISSIONS FOR THIS REQUEST USING GIVEN USERNAME |
|
310 | # CHECK PERMISSIONS FOR THIS REQUEST USING GIVEN USERNAME | |
310 | # ============================================================== |
|
311 | # ============================================================== | |
311 | user = User.get_by_username(username) |
|
312 | user = User.get_by_username(username) | |
312 | if not self.valid_and_active_user(user): |
|
313 | if not self.valid_and_active_user(user): | |
313 | return HTTPForbidden()(environ, start_response) |
|
314 | return HTTPForbidden()(environ, start_response) | |
314 | username = user.username |
|
315 | username = user.username | |
315 | user.update_lastactivity() |
|
316 | user.update_lastactivity() | |
316 | meta.Session().commit() |
|
317 | meta.Session().commit() | |
317 |
|
318 | |||
318 | # check user attributes for password change flag |
|
319 | # check user attributes for password change flag | |
319 | user_obj = user |
|
320 | user_obj = user | |
320 | if user_obj and user_obj.username != User.DEFAULT_USER and \ |
|
321 | if user_obj and user_obj.username != User.DEFAULT_USER and \ | |
321 | user_obj.user_data.get('force_password_change'): |
|
322 | user_obj.user_data.get('force_password_change'): | |
322 | reason = 'password change required' |
|
323 | reason = 'password change required' | |
323 | log.debug('User not allowed to authenticate, %s', reason) |
|
324 | log.debug('User not allowed to authenticate, %s', reason) | |
324 | return HTTPNotAcceptable(reason)(environ, start_response) |
|
325 | return HTTPNotAcceptable(reason)(environ, start_response) | |
325 |
|
326 | |||
326 | # check permissions for this repository |
|
327 | # check permissions for this repository | |
327 | perm = self._check_permission(action, user, repo_name, ip_addr) |
|
328 | perm = self._check_permission(action, user, repo_name, ip_addr) | |
328 | if not perm: |
|
329 | if not perm: | |
329 | return HTTPForbidden()(environ, start_response) |
|
330 | return HTTPForbidden()(environ, start_response) | |
330 |
|
331 | |||
331 | # extras are injected into UI object and later available |
|
332 | # extras are injected into UI object and later available | |
332 | # in hooks executed by rhodecode |
|
333 | # in hooks executed by rhodecode | |
333 | check_locking = _should_check_locking(environ.get('QUERY_STRING')) |
|
334 | check_locking = _should_check_locking(environ.get('QUERY_STRING')) | |
334 | extras = vcs_operation_context( |
|
335 | extras = vcs_operation_context( | |
335 | environ, repo_name=repo_name, username=username, |
|
336 | environ, repo_name=repo_name, username=username, | |
336 | action=action, scm=self.SCM, |
|
337 | action=action, scm=self.SCM, | |
337 | check_locking=check_locking) |
|
338 | check_locking=check_locking) | |
338 |
|
339 | |||
339 | # ====================================================================== |
|
340 | # ====================================================================== | |
340 | # REQUEST HANDLING |
|
341 | # REQUEST HANDLING | |
341 | # ====================================================================== |
|
342 | # ====================================================================== | |
342 | str_repo_name = safe_str(repo_name) |
|
343 | str_repo_name = safe_str(repo_name) | |
343 | repo_path = os.path.join(safe_str(self.basepath), str_repo_name) |
|
344 | repo_path = os.path.join(safe_str(self.basepath), str_repo_name) | |
344 | log.debug('Repository path is %s', repo_path) |
|
345 | log.debug('Repository path is %s', repo_path) | |
345 |
|
346 | |||
346 | fix_PATH() |
|
347 | fix_PATH() | |
347 |
|
348 | |||
348 | log.info( |
|
349 | log.info( | |
349 | '%s action on %s repo "%s" by "%s" from %s', |
|
350 | '%s action on %s repo "%s" by "%s" from %s', | |
350 | action, self.SCM, str_repo_name, safe_str(username), ip_addr) |
|
351 | action, self.SCM, str_repo_name, safe_str(username), ip_addr) | |
351 | return self._generate_vcs_response( |
|
352 | return self._generate_vcs_response( | |
352 | environ, start_response, repo_path, repo_name, extras, action) |
|
353 | environ, start_response, repo_path, repo_name, extras, action) | |
353 |
|
354 | |||
354 | @initialize_generator |
|
355 | @initialize_generator | |
355 | def _generate_vcs_response( |
|
356 | def _generate_vcs_response( | |
356 | self, environ, start_response, repo_path, repo_name, extras, |
|
357 | self, environ, start_response, repo_path, repo_name, extras, | |
357 | action): |
|
358 | action): | |
358 | """ |
|
359 | """ | |
359 | Returns a generator for the response content. |
|
360 | Returns a generator for the response content. | |
360 |
|
361 | |||
361 | This method is implemented as a generator, so that it can trigger |
|
362 | This method is implemented as a generator, so that it can trigger | |
362 | the cache validation after all content sent back to the client. It |
|
363 | the cache validation after all content sent back to the client. It | |
363 | also handles the locking exceptions which will be triggered when |
|
364 | also handles the locking exceptions which will be triggered when | |
364 | the first chunk is produced by the underlying WSGI application. |
|
365 | the first chunk is produced by the underlying WSGI application. | |
365 | """ |
|
366 | """ | |
366 | callback_daemon, extras = self._prepare_callback_daemon(extras) |
|
367 | callback_daemon, extras = self._prepare_callback_daemon(extras) | |
367 | config = self._create_config(extras, repo_name) |
|
368 | config = self._create_config(extras, repo_name) | |
368 | log.debug('HOOKS extras is %s', extras) |
|
369 | log.debug('HOOKS extras is %s', extras) | |
369 | app = self._create_wsgi_app(repo_path, repo_name, config) |
|
370 | app = self._create_wsgi_app(repo_path, repo_name, config) | |
370 |
|
371 | |||
371 | try: |
|
372 | try: | |
372 | with callback_daemon: |
|
373 | with callback_daemon: | |
373 | try: |
|
374 | try: | |
374 | response = app(environ, start_response) |
|
375 | response = app(environ, start_response) | |
375 | finally: |
|
376 | finally: | |
376 | # This statement works together with the decorator |
|
377 | # This statement works together with the decorator | |
377 | # "initialize_generator" above. The decorator ensures that |
|
378 | # "initialize_generator" above. The decorator ensures that | |
378 | # we hit the first yield statement before the generator is |
|
379 | # we hit the first yield statement before the generator is | |
379 | # returned back to the WSGI server. This is needed to |
|
380 | # returned back to the WSGI server. This is needed to | |
380 | # ensure that the call to "app" above triggers the |
|
381 | # ensure that the call to "app" above triggers the | |
381 | # needed callback to "start_response" before the |
|
382 | # needed callback to "start_response" before the | |
382 | # generator is actually used. |
|
383 | # generator is actually used. | |
383 | yield "__init__" |
|
384 | yield "__init__" | |
384 |
|
385 | |||
385 | for chunk in response: |
|
386 | for chunk in response: | |
386 | yield chunk |
|
387 | yield chunk | |
387 | except Exception as exc: |
|
388 | except Exception as exc: | |
388 | # TODO: johbo: Improve "translating" back the exception. |
|
389 | # TODO: johbo: Improve "translating" back the exception. | |
389 | if getattr(exc, '_vcs_kind', None) == 'repo_locked': |
|
390 | if getattr(exc, '_vcs_kind', None) == 'repo_locked': | |
390 | exc = HTTPLockedRC(*exc.args) |
|
391 | exc = HTTPLockedRC(*exc.args) | |
391 | _code = rhodecode.CONFIG.get('lock_ret_code') |
|
392 | _code = rhodecode.CONFIG.get('lock_ret_code') | |
392 | log.debug('Repository LOCKED ret code %s!', (_code,)) |
|
393 | log.debug('Repository LOCKED ret code %s!', (_code,)) | |
393 | elif getattr(exc, '_vcs_kind', None) == 'requirement': |
|
394 | elif getattr(exc, '_vcs_kind', None) == 'requirement': | |
394 | log.debug( |
|
395 | log.debug( | |
395 | 'Repository requires features unknown to this Mercurial') |
|
396 | 'Repository requires features unknown to this Mercurial') | |
396 | exc = HTTPRequirementError(*exc.args) |
|
397 | exc = HTTPRequirementError(*exc.args) | |
397 | else: |
|
398 | else: | |
398 | raise |
|
399 | raise | |
399 |
|
400 | |||
400 | for chunk in exc(environ, start_response): |
|
401 | for chunk in exc(environ, start_response): | |
401 | yield chunk |
|
402 | yield chunk | |
402 | finally: |
|
403 | finally: | |
403 | # invalidate cache on push |
|
404 | # invalidate cache on push | |
404 | if action == 'push': |
|
405 | if action == 'push': | |
405 | self._invalidate_cache(repo_name) |
|
406 | self._invalidate_cache(repo_name) | |
406 |
|
407 | |||
407 | def _get_repository_name(self, environ): |
|
408 | def _get_repository_name(self, environ): | |
408 | """Get repository name out of the environmnent |
|
409 | """Get repository name out of the environmnent | |
409 |
|
410 | |||
410 | :param environ: WSGI environment |
|
411 | :param environ: WSGI environment | |
411 | """ |
|
412 | """ | |
412 | raise NotImplementedError() |
|
413 | raise NotImplementedError() | |
413 |
|
414 | |||
414 | def _get_action(self, environ): |
|
415 | def _get_action(self, environ): | |
415 | """Map request commands into a pull or push command. |
|
416 | """Map request commands into a pull or push command. | |
416 |
|
417 | |||
417 | :param environ: WSGI environment |
|
418 | :param environ: WSGI environment | |
418 | """ |
|
419 | """ | |
419 | raise NotImplementedError() |
|
420 | raise NotImplementedError() | |
420 |
|
421 | |||
421 | def _create_wsgi_app(self, repo_path, repo_name, config): |
|
422 | def _create_wsgi_app(self, repo_path, repo_name, config): | |
422 | """Return the WSGI app that will finally handle the request.""" |
|
423 | """Return the WSGI app that will finally handle the request.""" | |
423 | raise NotImplementedError() |
|
424 | raise NotImplementedError() | |
424 |
|
425 | |||
425 | def _create_config(self, extras, repo_name): |
|
426 | def _create_config(self, extras, repo_name): | |
426 | """Create a Pyro safe config representation.""" |
|
427 | """Create a Pyro safe config representation.""" | |
427 | raise NotImplementedError() |
|
428 | raise NotImplementedError() | |
428 |
|
429 | |||
429 | def _prepare_callback_daemon(self, extras): |
|
430 | def _prepare_callback_daemon(self, extras): | |
430 | return prepare_callback_daemon( |
|
431 | return prepare_callback_daemon( | |
431 | extras, protocol=self.config.get('vcs.hooks.protocol'), |
|
432 | extras, protocol=self.config.get('vcs.hooks.protocol'), | |
432 | use_direct_calls=self.config.get('vcs.hooks.direct_calls')) |
|
433 | use_direct_calls=self.config.get('vcs.hooks.direct_calls')) | |
433 |
|
434 | |||
434 |
|
435 | |||
435 | def _should_check_locking(query_string): |
|
436 | def _should_check_locking(query_string): | |
436 | # this is kind of hacky, but due to how mercurial handles client-server |
|
437 | # this is kind of hacky, but due to how mercurial handles client-server | |
437 | # server see all operation on commit; bookmarks, phases and |
|
438 | # server see all operation on commit; bookmarks, phases and | |
438 | # obsolescence marker in different transaction, we don't want to check |
|
439 | # obsolescence marker in different transaction, we don't want to check | |
439 | # locking on those |
|
440 | # locking on those | |
440 | return query_string not in ['cmd=listkeys'] |
|
441 | return query_string not in ['cmd=listkeys'] |
@@ -1,1128 +1,1130 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 | # Copyright (C) 2012-2016 RhodeCode GmbH |
|
3 | # Copyright (C) 2012-2016 RhodeCode GmbH | |
4 | # |
|
4 | # | |
5 | # This program is free software: you can redistribute it and/or modify |
|
5 | # This program is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
6 | # it under the terms of the GNU Affero General Public License, version 3 | |
7 | # (only), as published by the Free Software Foundation. |
|
7 | # (only), as published by the Free Software Foundation. | |
8 | # |
|
8 | # | |
9 | # This program is distributed in the hope that it will be useful, |
|
9 | # This program is distributed in the hope that it will be useful, | |
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | # GNU General Public License for more details. |
|
12 | # GNU General Public License for more details. | |
13 | # |
|
13 | # | |
14 | # You should have received a copy of the GNU Affero General Public License |
|
14 | # You should have received a copy of the GNU Affero General Public License | |
15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | |
16 | # |
|
16 | # | |
17 | # This program is dual-licensed. If you wish to learn more about the |
|
17 | # This program is dual-licensed. If you wish to learn more about the | |
18 | # RhodeCode Enterprise Edition, including its added features, Support services, |
|
18 | # RhodeCode Enterprise Edition, including its added features, Support services, | |
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ |
|
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |
20 |
|
20 | |||
21 |
|
21 | |||
22 | """ |
|
22 | """ | |
23 | pull request model for RhodeCode |
|
23 | pull request model for RhodeCode | |
24 | """ |
|
24 | """ | |
25 |
|
25 | |||
26 | from collections import namedtuple |
|
26 | from collections import namedtuple | |
27 | import json |
|
27 | import json | |
28 | import logging |
|
28 | import logging | |
29 | import datetime |
|
29 | import datetime | |
30 |
|
30 | |||
31 | from pylons.i18n.translation import _ |
|
31 | from pylons.i18n.translation import _ | |
32 | from pylons.i18n.translation import lazy_ugettext |
|
32 | from pylons.i18n.translation import lazy_ugettext | |
33 |
|
33 | |||
34 | import rhodecode |
|
34 | import rhodecode | |
35 | from rhodecode.lib import helpers as h, hooks_utils, diffs |
|
35 | from rhodecode.lib import helpers as h, hooks_utils, diffs | |
36 | from rhodecode.lib.compat import OrderedDict |
|
36 | from rhodecode.lib.compat import OrderedDict | |
37 | from rhodecode.lib.hooks_daemon import prepare_callback_daemon |
|
37 | from rhodecode.lib.hooks_daemon import prepare_callback_daemon | |
38 | from rhodecode.lib.markup_renderer import ( |
|
38 | from rhodecode.lib.markup_renderer import ( | |
39 | DEFAULT_COMMENTS_RENDERER, RstTemplateRenderer) |
|
39 | DEFAULT_COMMENTS_RENDERER, RstTemplateRenderer) | |
40 | from rhodecode.lib.utils import action_logger |
|
40 | from rhodecode.lib.utils import action_logger | |
41 | from rhodecode.lib.utils2 import safe_unicode, safe_str, md5_safe |
|
41 | from rhodecode.lib.utils2 import safe_unicode, safe_str, md5_safe | |
42 | from rhodecode.lib.vcs.backends.base import ( |
|
42 | from rhodecode.lib.vcs.backends.base import ( | |
43 | Reference, MergeResponse, MergeFailureReason) |
|
43 | Reference, MergeResponse, MergeFailureReason) | |
44 | from rhodecode.lib.vcs.exceptions import ( |
|
44 | from rhodecode.lib.vcs.exceptions import ( | |
45 | CommitDoesNotExistError, EmptyRepositoryError) |
|
45 | CommitDoesNotExistError, EmptyRepositoryError) | |
46 | from rhodecode.model import BaseModel |
|
46 | from rhodecode.model import BaseModel | |
47 | from rhodecode.model.changeset_status import ChangesetStatusModel |
|
47 | from rhodecode.model.changeset_status import ChangesetStatusModel | |
48 | from rhodecode.model.comment import ChangesetCommentsModel |
|
48 | from rhodecode.model.comment import ChangesetCommentsModel | |
49 | from rhodecode.model.db import ( |
|
49 | from rhodecode.model.db import ( | |
50 | PullRequest, PullRequestReviewers, Notification, ChangesetStatus, |
|
50 | PullRequest, PullRequestReviewers, Notification, ChangesetStatus, | |
51 | PullRequestVersion, ChangesetComment) |
|
51 | PullRequestVersion, ChangesetComment) | |
52 | from rhodecode.model.meta import Session |
|
52 | from rhodecode.model.meta import Session | |
53 | from rhodecode.model.notification import NotificationModel, \ |
|
53 | from rhodecode.model.notification import NotificationModel, \ | |
54 | EmailNotificationModel |
|
54 | EmailNotificationModel | |
55 | from rhodecode.model.scm import ScmModel |
|
55 | from rhodecode.model.scm import ScmModel | |
56 | from rhodecode.model.settings import VcsSettingsModel |
|
56 | from rhodecode.model.settings import VcsSettingsModel | |
57 |
|
57 | |||
58 |
|
58 | |||
59 | log = logging.getLogger(__name__) |
|
59 | log = logging.getLogger(__name__) | |
60 |
|
60 | |||
61 |
|
61 | |||
62 | class PullRequestModel(BaseModel): |
|
62 | class PullRequestModel(BaseModel): | |
63 |
|
63 | |||
64 | cls = PullRequest |
|
64 | cls = PullRequest | |
65 |
|
65 | |||
66 | DIFF_CONTEXT = 3 |
|
66 | DIFF_CONTEXT = 3 | |
67 |
|
67 | |||
68 | MERGE_STATUS_MESSAGES = { |
|
68 | MERGE_STATUS_MESSAGES = { | |
69 | MergeFailureReason.NONE: lazy_ugettext( |
|
69 | MergeFailureReason.NONE: lazy_ugettext( | |
70 | 'This pull request can be automatically merged.'), |
|
70 | 'This pull request can be automatically merged.'), | |
71 | MergeFailureReason.UNKNOWN: lazy_ugettext( |
|
71 | MergeFailureReason.UNKNOWN: lazy_ugettext( | |
72 | 'This pull request cannot be merged because of an unhandled' |
|
72 | 'This pull request cannot be merged because of an unhandled' | |
73 | ' exception.'), |
|
73 | ' exception.'), | |
74 | MergeFailureReason.MERGE_FAILED: lazy_ugettext( |
|
74 | MergeFailureReason.MERGE_FAILED: lazy_ugettext( | |
75 | 'This pull request cannot be merged because of conflicts.'), |
|
75 | 'This pull request cannot be merged because of conflicts.'), | |
76 | MergeFailureReason.PUSH_FAILED: lazy_ugettext( |
|
76 | MergeFailureReason.PUSH_FAILED: lazy_ugettext( | |
77 | 'This pull request could not be merged because push to target' |
|
77 | 'This pull request could not be merged because push to target' | |
78 | ' failed.'), |
|
78 | ' failed.'), | |
79 | MergeFailureReason.TARGET_IS_NOT_HEAD: lazy_ugettext( |
|
79 | MergeFailureReason.TARGET_IS_NOT_HEAD: lazy_ugettext( | |
80 | 'This pull request cannot be merged because the target is not a' |
|
80 | 'This pull request cannot be merged because the target is not a' | |
81 | ' head.'), |
|
81 | ' head.'), | |
82 | MergeFailureReason.HG_SOURCE_HAS_MORE_BRANCHES: lazy_ugettext( |
|
82 | MergeFailureReason.HG_SOURCE_HAS_MORE_BRANCHES: lazy_ugettext( | |
83 | 'This pull request cannot be merged because the source contains' |
|
83 | 'This pull request cannot be merged because the source contains' | |
84 | ' more branches than the target.'), |
|
84 | ' more branches than the target.'), | |
85 | MergeFailureReason.HG_TARGET_HAS_MULTIPLE_HEADS: lazy_ugettext( |
|
85 | MergeFailureReason.HG_TARGET_HAS_MULTIPLE_HEADS: lazy_ugettext( | |
86 | 'This pull request cannot be merged because the target has' |
|
86 | 'This pull request cannot be merged because the target has' | |
87 | ' multiple heads.'), |
|
87 | ' multiple heads.'), | |
88 | MergeFailureReason.TARGET_IS_LOCKED: lazy_ugettext( |
|
88 | MergeFailureReason.TARGET_IS_LOCKED: lazy_ugettext( | |
89 | 'This pull request cannot be merged because the target repository' |
|
89 | 'This pull request cannot be merged because the target repository' | |
90 | ' is locked.'), |
|
90 | ' is locked.'), | |
91 | MergeFailureReason.MISSING_COMMIT: lazy_ugettext( |
|
91 | MergeFailureReason.MISSING_COMMIT: lazy_ugettext( | |
92 | 'This pull request cannot be merged because the target or the ' |
|
92 | 'This pull request cannot be merged because the target or the ' | |
93 | 'source reference is missing.'), |
|
93 | 'source reference is missing.'), | |
94 | } |
|
94 | } | |
95 |
|
95 | |||
96 | def __get_pull_request(self, pull_request): |
|
96 | def __get_pull_request(self, pull_request): | |
97 | return self._get_instance(PullRequest, pull_request) |
|
97 | return self._get_instance(PullRequest, pull_request) | |
98 |
|
98 | |||
99 | def _check_perms(self, perms, pull_request, user, api=False): |
|
99 | def _check_perms(self, perms, pull_request, user, api=False): | |
100 | if not api: |
|
100 | if not api: | |
101 | return h.HasRepoPermissionAny(*perms)( |
|
101 | return h.HasRepoPermissionAny(*perms)( | |
102 | user=user, repo_name=pull_request.target_repo.repo_name) |
|
102 | user=user, repo_name=pull_request.target_repo.repo_name) | |
103 | else: |
|
103 | else: | |
104 | return h.HasRepoPermissionAnyApi(*perms)( |
|
104 | return h.HasRepoPermissionAnyApi(*perms)( | |
105 | user=user, repo_name=pull_request.target_repo.repo_name) |
|
105 | user=user, repo_name=pull_request.target_repo.repo_name) | |
106 |
|
106 | |||
107 | def check_user_read(self, pull_request, user, api=False): |
|
107 | def check_user_read(self, pull_request, user, api=False): | |
108 | _perms = ('repository.admin', 'repository.write', 'repository.read',) |
|
108 | _perms = ('repository.admin', 'repository.write', 'repository.read',) | |
109 | return self._check_perms(_perms, pull_request, user, api) |
|
109 | return self._check_perms(_perms, pull_request, user, api) | |
110 |
|
110 | |||
111 | def check_user_merge(self, pull_request, user, api=False): |
|
111 | def check_user_merge(self, pull_request, user, api=False): | |
112 | _perms = ('repository.admin', 'repository.write', 'hg.admin',) |
|
112 | _perms = ('repository.admin', 'repository.write', 'hg.admin',) | |
113 | return self._check_perms(_perms, pull_request, user, api) |
|
113 | return self._check_perms(_perms, pull_request, user, api) | |
114 |
|
114 | |||
115 | def check_user_update(self, pull_request, user, api=False): |
|
115 | def check_user_update(self, pull_request, user, api=False): | |
116 | owner = user.user_id == pull_request.user_id |
|
116 | owner = user.user_id == pull_request.user_id | |
117 | return self.check_user_merge(pull_request, user, api) or owner |
|
117 | return self.check_user_merge(pull_request, user, api) or owner | |
118 |
|
118 | |||
119 | def check_user_change_status(self, pull_request, user, api=False): |
|
119 | def check_user_change_status(self, pull_request, user, api=False): | |
120 | reviewer = user.user_id in [x.user_id for x in |
|
120 | reviewer = user.user_id in [x.user_id for x in | |
121 | pull_request.reviewers] |
|
121 | pull_request.reviewers] | |
122 | return self.check_user_update(pull_request, user, api) or reviewer |
|
122 | return self.check_user_update(pull_request, user, api) or reviewer | |
123 |
|
123 | |||
124 | def get(self, pull_request): |
|
124 | def get(self, pull_request): | |
125 | return self.__get_pull_request(pull_request) |
|
125 | return self.__get_pull_request(pull_request) | |
126 |
|
126 | |||
127 | def _prepare_get_all_query(self, repo_name, source=False, statuses=None, |
|
127 | def _prepare_get_all_query(self, repo_name, source=False, statuses=None, | |
128 | opened_by=None, order_by=None, |
|
128 | opened_by=None, order_by=None, | |
129 | order_dir='desc'): |
|
129 | order_dir='desc'): | |
130 | repo = self._get_repo(repo_name) |
|
130 | repo = self._get_repo(repo_name) | |
131 | q = PullRequest.query() |
|
131 | q = PullRequest.query() | |
132 | # source or target |
|
132 | # source or target | |
133 | if source: |
|
133 | if source: | |
134 | q = q.filter(PullRequest.source_repo == repo) |
|
134 | q = q.filter(PullRequest.source_repo == repo) | |
135 | else: |
|
135 | else: | |
136 | q = q.filter(PullRequest.target_repo == repo) |
|
136 | q = q.filter(PullRequest.target_repo == repo) | |
137 |
|
137 | |||
138 | # closed,opened |
|
138 | # closed,opened | |
139 | if statuses: |
|
139 | if statuses: | |
140 | q = q.filter(PullRequest.status.in_(statuses)) |
|
140 | q = q.filter(PullRequest.status.in_(statuses)) | |
141 |
|
141 | |||
142 | # opened by filter |
|
142 | # opened by filter | |
143 | if opened_by: |
|
143 | if opened_by: | |
144 | q = q.filter(PullRequest.user_id.in_(opened_by)) |
|
144 | q = q.filter(PullRequest.user_id.in_(opened_by)) | |
145 |
|
145 | |||
146 | if order_by: |
|
146 | if order_by: | |
147 | order_map = { |
|
147 | order_map = { | |
148 | 'name_raw': PullRequest.pull_request_id, |
|
148 | 'name_raw': PullRequest.pull_request_id, | |
149 | 'title': PullRequest.title, |
|
149 | 'title': PullRequest.title, | |
150 | 'updated_on_raw': PullRequest.updated_on |
|
150 | 'updated_on_raw': PullRequest.updated_on | |
151 | } |
|
151 | } | |
152 | if order_dir == 'asc': |
|
152 | if order_dir == 'asc': | |
153 | q = q.order_by(order_map[order_by].asc()) |
|
153 | q = q.order_by(order_map[order_by].asc()) | |
154 | else: |
|
154 | else: | |
155 | q = q.order_by(order_map[order_by].desc()) |
|
155 | q = q.order_by(order_map[order_by].desc()) | |
156 |
|
156 | |||
157 | return q |
|
157 | return q | |
158 |
|
158 | |||
159 | def count_all(self, repo_name, source=False, statuses=None, |
|
159 | def count_all(self, repo_name, source=False, statuses=None, | |
160 | opened_by=None): |
|
160 | opened_by=None): | |
161 | """ |
|
161 | """ | |
162 | Count the number of pull requests for a specific repository. |
|
162 | Count the number of pull requests for a specific repository. | |
163 |
|
163 | |||
164 | :param repo_name: target or source repo |
|
164 | :param repo_name: target or source repo | |
165 | :param source: boolean flag to specify if repo_name refers to source |
|
165 | :param source: boolean flag to specify if repo_name refers to source | |
166 | :param statuses: list of pull request statuses |
|
166 | :param statuses: list of pull request statuses | |
167 | :param opened_by: author user of the pull request |
|
167 | :param opened_by: author user of the pull request | |
168 | :returns: int number of pull requests |
|
168 | :returns: int number of pull requests | |
169 | """ |
|
169 | """ | |
170 | q = self._prepare_get_all_query( |
|
170 | q = self._prepare_get_all_query( | |
171 | repo_name, source=source, statuses=statuses, opened_by=opened_by) |
|
171 | repo_name, source=source, statuses=statuses, opened_by=opened_by) | |
172 |
|
172 | |||
173 | return q.count() |
|
173 | return q.count() | |
174 |
|
174 | |||
175 | def get_all(self, repo_name, source=False, statuses=None, opened_by=None, |
|
175 | def get_all(self, repo_name, source=False, statuses=None, opened_by=None, | |
176 | offset=0, length=None, order_by=None, order_dir='desc'): |
|
176 | offset=0, length=None, order_by=None, order_dir='desc'): | |
177 | """ |
|
177 | """ | |
178 | Get all pull requests for a specific repository. |
|
178 | Get all pull requests for a specific repository. | |
179 |
|
179 | |||
180 | :param repo_name: target or source repo |
|
180 | :param repo_name: target or source repo | |
181 | :param source: boolean flag to specify if repo_name refers to source |
|
181 | :param source: boolean flag to specify if repo_name refers to source | |
182 | :param statuses: list of pull request statuses |
|
182 | :param statuses: list of pull request statuses | |
183 | :param opened_by: author user of the pull request |
|
183 | :param opened_by: author user of the pull request | |
184 | :param offset: pagination offset |
|
184 | :param offset: pagination offset | |
185 | :param length: length of returned list |
|
185 | :param length: length of returned list | |
186 | :param order_by: order of the returned list |
|
186 | :param order_by: order of the returned list | |
187 | :param order_dir: 'asc' or 'desc' ordering direction |
|
187 | :param order_dir: 'asc' or 'desc' ordering direction | |
188 | :returns: list of pull requests |
|
188 | :returns: list of pull requests | |
189 | """ |
|
189 | """ | |
190 | q = self._prepare_get_all_query( |
|
190 | q = self._prepare_get_all_query( | |
191 | repo_name, source=source, statuses=statuses, opened_by=opened_by, |
|
191 | repo_name, source=source, statuses=statuses, opened_by=opened_by, | |
192 | order_by=order_by, order_dir=order_dir) |
|
192 | order_by=order_by, order_dir=order_dir) | |
193 |
|
193 | |||
194 | if length: |
|
194 | if length: | |
195 | pull_requests = q.limit(length).offset(offset).all() |
|
195 | pull_requests = q.limit(length).offset(offset).all() | |
196 | else: |
|
196 | else: | |
197 | pull_requests = q.all() |
|
197 | pull_requests = q.all() | |
198 |
|
198 | |||
199 | return pull_requests |
|
199 | return pull_requests | |
200 |
|
200 | |||
201 | def count_awaiting_review(self, repo_name, source=False, statuses=None, |
|
201 | def count_awaiting_review(self, repo_name, source=False, statuses=None, | |
202 | opened_by=None): |
|
202 | opened_by=None): | |
203 | """ |
|
203 | """ | |
204 | Count the number of pull requests for a specific repository that are |
|
204 | Count the number of pull requests for a specific repository that are | |
205 | awaiting review. |
|
205 | awaiting review. | |
206 |
|
206 | |||
207 | :param repo_name: target or source repo |
|
207 | :param repo_name: target or source repo | |
208 | :param source: boolean flag to specify if repo_name refers to source |
|
208 | :param source: boolean flag to specify if repo_name refers to source | |
209 | :param statuses: list of pull request statuses |
|
209 | :param statuses: list of pull request statuses | |
210 | :param opened_by: author user of the pull request |
|
210 | :param opened_by: author user of the pull request | |
211 | :returns: int number of pull requests |
|
211 | :returns: int number of pull requests | |
212 | """ |
|
212 | """ | |
213 | pull_requests = self.get_awaiting_review( |
|
213 | pull_requests = self.get_awaiting_review( | |
214 | repo_name, source=source, statuses=statuses, opened_by=opened_by) |
|
214 | repo_name, source=source, statuses=statuses, opened_by=opened_by) | |
215 |
|
215 | |||
216 | return len(pull_requests) |
|
216 | return len(pull_requests) | |
217 |
|
217 | |||
218 | def get_awaiting_review(self, repo_name, source=False, statuses=None, |
|
218 | def get_awaiting_review(self, repo_name, source=False, statuses=None, | |
219 | opened_by=None, offset=0, length=None, |
|
219 | opened_by=None, offset=0, length=None, | |
220 | order_by=None, order_dir='desc'): |
|
220 | order_by=None, order_dir='desc'): | |
221 | """ |
|
221 | """ | |
222 | Get all pull requests for a specific repository that are awaiting |
|
222 | Get all pull requests for a specific repository that are awaiting | |
223 | review. |
|
223 | review. | |
224 |
|
224 | |||
225 | :param repo_name: target or source repo |
|
225 | :param repo_name: target or source repo | |
226 | :param source: boolean flag to specify if repo_name refers to source |
|
226 | :param source: boolean flag to specify if repo_name refers to source | |
227 | :param statuses: list of pull request statuses |
|
227 | :param statuses: list of pull request statuses | |
228 | :param opened_by: author user of the pull request |
|
228 | :param opened_by: author user of the pull request | |
229 | :param offset: pagination offset |
|
229 | :param offset: pagination offset | |
230 | :param length: length of returned list |
|
230 | :param length: length of returned list | |
231 | :param order_by: order of the returned list |
|
231 | :param order_by: order of the returned list | |
232 | :param order_dir: 'asc' or 'desc' ordering direction |
|
232 | :param order_dir: 'asc' or 'desc' ordering direction | |
233 | :returns: list of pull requests |
|
233 | :returns: list of pull requests | |
234 | """ |
|
234 | """ | |
235 | pull_requests = self.get_all( |
|
235 | pull_requests = self.get_all( | |
236 | repo_name, source=source, statuses=statuses, opened_by=opened_by, |
|
236 | repo_name, source=source, statuses=statuses, opened_by=opened_by, | |
237 | order_by=order_by, order_dir=order_dir) |
|
237 | order_by=order_by, order_dir=order_dir) | |
238 |
|
238 | |||
239 | _filtered_pull_requests = [] |
|
239 | _filtered_pull_requests = [] | |
240 | for pr in pull_requests: |
|
240 | for pr in pull_requests: | |
241 | status = pr.calculated_review_status() |
|
241 | status = pr.calculated_review_status() | |
242 | if status in [ChangesetStatus.STATUS_NOT_REVIEWED, |
|
242 | if status in [ChangesetStatus.STATUS_NOT_REVIEWED, | |
243 | ChangesetStatus.STATUS_UNDER_REVIEW]: |
|
243 | ChangesetStatus.STATUS_UNDER_REVIEW]: | |
244 | _filtered_pull_requests.append(pr) |
|
244 | _filtered_pull_requests.append(pr) | |
245 | if length: |
|
245 | if length: | |
246 | return _filtered_pull_requests[offset:offset+length] |
|
246 | return _filtered_pull_requests[offset:offset+length] | |
247 | else: |
|
247 | else: | |
248 | return _filtered_pull_requests |
|
248 | return _filtered_pull_requests | |
249 |
|
249 | |||
250 | def count_awaiting_my_review(self, repo_name, source=False, statuses=None, |
|
250 | def count_awaiting_my_review(self, repo_name, source=False, statuses=None, | |
251 | opened_by=None, user_id=None): |
|
251 | opened_by=None, user_id=None): | |
252 | """ |
|
252 | """ | |
253 | Count the number of pull requests for a specific repository that are |
|
253 | Count the number of pull requests for a specific repository that are | |
254 | awaiting review from a specific user. |
|
254 | awaiting review from a specific user. | |
255 |
|
255 | |||
256 | :param repo_name: target or source repo |
|
256 | :param repo_name: target or source repo | |
257 | :param source: boolean flag to specify if repo_name refers to source |
|
257 | :param source: boolean flag to specify if repo_name refers to source | |
258 | :param statuses: list of pull request statuses |
|
258 | :param statuses: list of pull request statuses | |
259 | :param opened_by: author user of the pull request |
|
259 | :param opened_by: author user of the pull request | |
260 | :param user_id: reviewer user of the pull request |
|
260 | :param user_id: reviewer user of the pull request | |
261 | :returns: int number of pull requests |
|
261 | :returns: int number of pull requests | |
262 | """ |
|
262 | """ | |
263 | pull_requests = self.get_awaiting_my_review( |
|
263 | pull_requests = self.get_awaiting_my_review( | |
264 | repo_name, source=source, statuses=statuses, opened_by=opened_by, |
|
264 | repo_name, source=source, statuses=statuses, opened_by=opened_by, | |
265 | user_id=user_id) |
|
265 | user_id=user_id) | |
266 |
|
266 | |||
267 | return len(pull_requests) |
|
267 | return len(pull_requests) | |
268 |
|
268 | |||
269 | def get_awaiting_my_review(self, repo_name, source=False, statuses=None, |
|
269 | def get_awaiting_my_review(self, repo_name, source=False, statuses=None, | |
270 | opened_by=None, user_id=None, offset=0, |
|
270 | opened_by=None, user_id=None, offset=0, | |
271 | length=None, order_by=None, order_dir='desc'): |
|
271 | length=None, order_by=None, order_dir='desc'): | |
272 | """ |
|
272 | """ | |
273 | Get all pull requests for a specific repository that are awaiting |
|
273 | Get all pull requests for a specific repository that are awaiting | |
274 | review from a specific user. |
|
274 | review from a specific user. | |
275 |
|
275 | |||
276 | :param repo_name: target or source repo |
|
276 | :param repo_name: target or source repo | |
277 | :param source: boolean flag to specify if repo_name refers to source |
|
277 | :param source: boolean flag to specify if repo_name refers to source | |
278 | :param statuses: list of pull request statuses |
|
278 | :param statuses: list of pull request statuses | |
279 | :param opened_by: author user of the pull request |
|
279 | :param opened_by: author user of the pull request | |
280 | :param user_id: reviewer user of the pull request |
|
280 | :param user_id: reviewer user of the pull request | |
281 | :param offset: pagination offset |
|
281 | :param offset: pagination offset | |
282 | :param length: length of returned list |
|
282 | :param length: length of returned list | |
283 | :param order_by: order of the returned list |
|
283 | :param order_by: order of the returned list | |
284 | :param order_dir: 'asc' or 'desc' ordering direction |
|
284 | :param order_dir: 'asc' or 'desc' ordering direction | |
285 | :returns: list of pull requests |
|
285 | :returns: list of pull requests | |
286 | """ |
|
286 | """ | |
287 | pull_requests = self.get_all( |
|
287 | pull_requests = self.get_all( | |
288 | repo_name, source=source, statuses=statuses, opened_by=opened_by, |
|
288 | repo_name, source=source, statuses=statuses, opened_by=opened_by, | |
289 | order_by=order_by, order_dir=order_dir) |
|
289 | order_by=order_by, order_dir=order_dir) | |
290 |
|
290 | |||
291 | _my = PullRequestModel().get_not_reviewed(user_id) |
|
291 | _my = PullRequestModel().get_not_reviewed(user_id) | |
292 | my_participation = [] |
|
292 | my_participation = [] | |
293 | for pr in pull_requests: |
|
293 | for pr in pull_requests: | |
294 | if pr in _my: |
|
294 | if pr in _my: | |
295 | my_participation.append(pr) |
|
295 | my_participation.append(pr) | |
296 | _filtered_pull_requests = my_participation |
|
296 | _filtered_pull_requests = my_participation | |
297 | if length: |
|
297 | if length: | |
298 | return _filtered_pull_requests[offset:offset+length] |
|
298 | return _filtered_pull_requests[offset:offset+length] | |
299 | else: |
|
299 | else: | |
300 | return _filtered_pull_requests |
|
300 | return _filtered_pull_requests | |
301 |
|
301 | |||
302 | def get_not_reviewed(self, user_id): |
|
302 | def get_not_reviewed(self, user_id): | |
303 | return [ |
|
303 | return [ | |
304 | x.pull_request for x in PullRequestReviewers.query().filter( |
|
304 | x.pull_request for x in PullRequestReviewers.query().filter( | |
305 | PullRequestReviewers.user_id == user_id).all() |
|
305 | PullRequestReviewers.user_id == user_id).all() | |
306 | ] |
|
306 | ] | |
307 |
|
307 | |||
308 | def get_versions(self, pull_request): |
|
308 | def get_versions(self, pull_request): | |
309 | """ |
|
309 | """ | |
310 | returns version of pull request sorted by ID descending |
|
310 | returns version of pull request sorted by ID descending | |
311 | """ |
|
311 | """ | |
312 | return PullRequestVersion.query()\ |
|
312 | return PullRequestVersion.query()\ | |
313 | .filter(PullRequestVersion.pull_request == pull_request)\ |
|
313 | .filter(PullRequestVersion.pull_request == pull_request)\ | |
314 | .order_by(PullRequestVersion.pull_request_version_id.asc())\ |
|
314 | .order_by(PullRequestVersion.pull_request_version_id.asc())\ | |
315 | .all() |
|
315 | .all() | |
316 |
|
316 | |||
317 | def create(self, created_by, source_repo, source_ref, target_repo, |
|
317 | def create(self, created_by, source_repo, source_ref, target_repo, | |
318 | target_ref, revisions, reviewers, title, description=None): |
|
318 | target_ref, revisions, reviewers, title, description=None): | |
319 | created_by_user = self._get_user(created_by) |
|
319 | created_by_user = self._get_user(created_by) | |
320 | source_repo = self._get_repo(source_repo) |
|
320 | source_repo = self._get_repo(source_repo) | |
321 | target_repo = self._get_repo(target_repo) |
|
321 | target_repo = self._get_repo(target_repo) | |
322 |
|
322 | |||
323 | pull_request = PullRequest() |
|
323 | pull_request = PullRequest() | |
324 | pull_request.source_repo = source_repo |
|
324 | pull_request.source_repo = source_repo | |
325 | pull_request.source_ref = source_ref |
|
325 | pull_request.source_ref = source_ref | |
326 | pull_request.target_repo = target_repo |
|
326 | pull_request.target_repo = target_repo | |
327 | pull_request.target_ref = target_ref |
|
327 | pull_request.target_ref = target_ref | |
328 | pull_request.revisions = revisions |
|
328 | pull_request.revisions = revisions | |
329 | pull_request.title = title |
|
329 | pull_request.title = title | |
330 | pull_request.description = description |
|
330 | pull_request.description = description | |
331 | pull_request.author = created_by_user |
|
331 | pull_request.author = created_by_user | |
332 |
|
332 | |||
333 | Session().add(pull_request) |
|
333 | Session().add(pull_request) | |
334 | Session().flush() |
|
334 | Session().flush() | |
335 |
|
335 | |||
336 | # members / reviewers |
|
336 | # members / reviewers | |
337 | for user_id in set(reviewers): |
|
337 | for user_id in set(reviewers): | |
338 | user = self._get_user(user_id) |
|
338 | user = self._get_user(user_id) | |
339 | reviewer = PullRequestReviewers(user, pull_request) |
|
339 | reviewer = PullRequestReviewers(user, pull_request) | |
340 | Session().add(reviewer) |
|
340 | Session().add(reviewer) | |
341 |
|
341 | |||
342 | # Set approval status to "Under Review" for all commits which are |
|
342 | # Set approval status to "Under Review" for all commits which are | |
343 | # part of this pull request. |
|
343 | # part of this pull request. | |
344 | ChangesetStatusModel().set_status( |
|
344 | ChangesetStatusModel().set_status( | |
345 | repo=target_repo, |
|
345 | repo=target_repo, | |
346 | status=ChangesetStatus.STATUS_UNDER_REVIEW, |
|
346 | status=ChangesetStatus.STATUS_UNDER_REVIEW, | |
347 | user=created_by_user, |
|
347 | user=created_by_user, | |
348 | pull_request=pull_request |
|
348 | pull_request=pull_request | |
349 | ) |
|
349 | ) | |
350 |
|
350 | |||
351 | self.notify_reviewers(pull_request, reviewers) |
|
351 | self.notify_reviewers(pull_request, reviewers) | |
352 | self._trigger_pull_request_hook( |
|
352 | self._trigger_pull_request_hook( | |
353 | pull_request, created_by_user, 'create') |
|
353 | pull_request, created_by_user, 'create') | |
354 |
|
354 | |||
355 | return pull_request |
|
355 | return pull_request | |
356 |
|
356 | |||
357 | def _trigger_pull_request_hook(self, pull_request, user, action): |
|
357 | def _trigger_pull_request_hook(self, pull_request, user, action): | |
358 | pull_request = self.__get_pull_request(pull_request) |
|
358 | pull_request = self.__get_pull_request(pull_request) | |
359 | target_scm = pull_request.target_repo.scm_instance() |
|
359 | target_scm = pull_request.target_repo.scm_instance() | |
360 | if action == 'create': |
|
360 | if action == 'create': | |
361 | trigger_hook = hooks_utils.trigger_log_create_pull_request_hook |
|
361 | trigger_hook = hooks_utils.trigger_log_create_pull_request_hook | |
362 | elif action == 'merge': |
|
362 | elif action == 'merge': | |
363 | trigger_hook = hooks_utils.trigger_log_merge_pull_request_hook |
|
363 | trigger_hook = hooks_utils.trigger_log_merge_pull_request_hook | |
364 | elif action == 'close': |
|
364 | elif action == 'close': | |
365 | trigger_hook = hooks_utils.trigger_log_close_pull_request_hook |
|
365 | trigger_hook = hooks_utils.trigger_log_close_pull_request_hook | |
366 | elif action == 'review_status_change': |
|
366 | elif action == 'review_status_change': | |
367 | trigger_hook = hooks_utils.trigger_log_review_pull_request_hook |
|
367 | trigger_hook = hooks_utils.trigger_log_review_pull_request_hook | |
368 | elif action == 'update': |
|
368 | elif action == 'update': | |
369 | trigger_hook = hooks_utils.trigger_log_update_pull_request_hook |
|
369 | trigger_hook = hooks_utils.trigger_log_update_pull_request_hook | |
370 | else: |
|
370 | else: | |
371 | return |
|
371 | return | |
372 |
|
372 | |||
373 | trigger_hook( |
|
373 | trigger_hook( | |
374 | username=user.username, |
|
374 | username=user.username, | |
375 | repo_name=pull_request.target_repo.repo_name, |
|
375 | repo_name=pull_request.target_repo.repo_name, | |
376 | repo_alias=target_scm.alias, |
|
376 | repo_alias=target_scm.alias, | |
377 | pull_request=pull_request) |
|
377 | pull_request=pull_request) | |
378 |
|
378 | |||
379 | def _get_commit_ids(self, pull_request): |
|
379 | def _get_commit_ids(self, pull_request): | |
380 | """ |
|
380 | """ | |
381 | Return the commit ids of the merged pull request. |
|
381 | Return the commit ids of the merged pull request. | |
382 |
|
382 | |||
383 | This method is not dealing correctly yet with the lack of autoupdates |
|
383 | This method is not dealing correctly yet with the lack of autoupdates | |
384 | nor with the implicit target updates. |
|
384 | nor with the implicit target updates. | |
385 | For example: if a commit in the source repo is already in the target it |
|
385 | For example: if a commit in the source repo is already in the target it | |
386 | will be reported anyways. |
|
386 | will be reported anyways. | |
387 | """ |
|
387 | """ | |
388 | merge_rev = pull_request.merge_rev |
|
388 | merge_rev = pull_request.merge_rev | |
389 | if merge_rev is None: |
|
389 | if merge_rev is None: | |
390 | raise ValueError('This pull request was not merged yet') |
|
390 | raise ValueError('This pull request was not merged yet') | |
391 |
|
391 | |||
392 | commit_ids = list(pull_request.revisions) |
|
392 | commit_ids = list(pull_request.revisions) | |
393 | if merge_rev not in commit_ids: |
|
393 | if merge_rev not in commit_ids: | |
394 | commit_ids.append(merge_rev) |
|
394 | commit_ids.append(merge_rev) | |
395 |
|
395 | |||
396 | return commit_ids |
|
396 | return commit_ids | |
397 |
|
397 | |||
398 | def merge(self, pull_request, user, extras): |
|
398 | def merge(self, pull_request, user, extras): | |
399 | merge_state = self._merge_pull_request(pull_request, user, extras) |
|
399 | merge_state = self._merge_pull_request(pull_request, user, extras) | |
400 | if merge_state.executed: |
|
400 | if merge_state.executed: | |
401 | self._comment_and_close_pr(pull_request, user, merge_state) |
|
401 | self._comment_and_close_pr(pull_request, user, merge_state) | |
402 | self._log_action('user_merged_pull_request', user, pull_request) |
|
402 | self._log_action('user_merged_pull_request', user, pull_request) | |
403 | return merge_state |
|
403 | return merge_state | |
404 |
|
404 | |||
405 | def _merge_pull_request(self, pull_request, user, extras): |
|
405 | def _merge_pull_request(self, pull_request, user, extras): | |
406 | target_vcs = pull_request.target_repo.scm_instance() |
|
406 | target_vcs = pull_request.target_repo.scm_instance() | |
407 | source_vcs = pull_request.source_repo.scm_instance() |
|
407 | source_vcs = pull_request.source_repo.scm_instance() | |
408 | target_ref = self._refresh_reference( |
|
408 | target_ref = self._refresh_reference( | |
409 | pull_request.target_ref_parts, target_vcs) |
|
409 | pull_request.target_ref_parts, target_vcs) | |
410 |
|
410 | |||
411 | message = _( |
|
411 | message = _( | |
412 | 'Merge pull request #%(pr_id)s from ' |
|
412 | 'Merge pull request #%(pr_id)s from ' | |
413 | '%(source_repo)s %(source_ref_name)s\n\n %(pr_title)s') % { |
|
413 | '%(source_repo)s %(source_ref_name)s\n\n %(pr_title)s') % { | |
414 | 'pr_id': pull_request.pull_request_id, |
|
414 | 'pr_id': pull_request.pull_request_id, | |
415 | 'source_repo': source_vcs.name, |
|
415 | 'source_repo': source_vcs.name, | |
416 | 'source_ref_name': pull_request.source_ref_parts.name, |
|
416 | 'source_ref_name': pull_request.source_ref_parts.name, | |
417 | 'pr_title': pull_request.title |
|
417 | 'pr_title': pull_request.title | |
418 | } |
|
418 | } | |
419 |
|
419 | |||
420 | workspace_id = self._workspace_id(pull_request) |
|
420 | workspace_id = self._workspace_id(pull_request) | |
421 | protocol = rhodecode.CONFIG.get('vcs.hooks.protocol') |
|
421 | protocol = rhodecode.CONFIG.get('vcs.hooks.protocol') | |
422 | use_direct_calls = rhodecode.CONFIG.get('vcs.hooks.direct_calls') |
|
422 | use_direct_calls = rhodecode.CONFIG.get('vcs.hooks.direct_calls') | |
423 |
|
423 | |||
424 | callback_daemon, extras = prepare_callback_daemon( |
|
424 | callback_daemon, extras = prepare_callback_daemon( | |
425 | extras, protocol=protocol, use_direct_calls=use_direct_calls) |
|
425 | extras, protocol=protocol, use_direct_calls=use_direct_calls) | |
426 |
|
426 | |||
427 | with callback_daemon: |
|
427 | with callback_daemon: | |
428 | # TODO: johbo: Implement a clean way to run a config_override |
|
428 | # TODO: johbo: Implement a clean way to run a config_override | |
429 | # for a single call. |
|
429 | # for a single call. | |
430 | target_vcs.config.set( |
|
430 | target_vcs.config.set( | |
431 | 'rhodecode', 'RC_SCM_DATA', json.dumps(extras)) |
|
431 | 'rhodecode', 'RC_SCM_DATA', json.dumps(extras)) | |
432 | merge_state = target_vcs.merge( |
|
432 | merge_state = target_vcs.merge( | |
433 | target_ref, source_vcs, pull_request.source_ref_parts, |
|
433 | target_ref, source_vcs, pull_request.source_ref_parts, | |
434 | workspace_id, user_name=user.username, |
|
434 | workspace_id, user_name=user.username, | |
435 | user_email=user.email, message=message) |
|
435 | user_email=user.email, message=message) | |
436 | return merge_state |
|
436 | return merge_state | |
437 |
|
437 | |||
438 | def _comment_and_close_pr(self, pull_request, user, merge_state): |
|
438 | def _comment_and_close_pr(self, pull_request, user, merge_state): | |
439 | pull_request.merge_rev = merge_state.merge_commit_id |
|
439 | pull_request.merge_rev = merge_state.merge_commit_id | |
440 | pull_request.updated_on = datetime.datetime.now() |
|
440 | pull_request.updated_on = datetime.datetime.now() | |
441 |
|
441 | |||
442 | ChangesetCommentsModel().create( |
|
442 | ChangesetCommentsModel().create( | |
443 | text=unicode(_('Pull request merged and closed')), |
|
443 | text=unicode(_('Pull request merged and closed')), | |
444 | repo=pull_request.target_repo.repo_id, |
|
444 | repo=pull_request.target_repo.repo_id, | |
445 | user=user.user_id, |
|
445 | user=user.user_id, | |
446 | pull_request=pull_request.pull_request_id, |
|
446 | pull_request=pull_request.pull_request_id, | |
447 | f_path=None, |
|
447 | f_path=None, | |
448 | line_no=None, |
|
448 | line_no=None, | |
449 | closing_pr=True |
|
449 | closing_pr=True | |
450 | ) |
|
450 | ) | |
451 |
|
451 | |||
452 | Session().add(pull_request) |
|
452 | Session().add(pull_request) | |
453 | Session().flush() |
|
453 | Session().flush() | |
454 | # TODO: paris: replace invalidation with less radical solution |
|
454 | # TODO: paris: replace invalidation with less radical solution | |
455 | ScmModel().mark_for_invalidation( |
|
455 | ScmModel().mark_for_invalidation( | |
456 | pull_request.target_repo.repo_name) |
|
456 | pull_request.target_repo.repo_name) | |
457 | self._trigger_pull_request_hook(pull_request, user, 'merge') |
|
457 | self._trigger_pull_request_hook(pull_request, user, 'merge') | |
458 |
|
458 | |||
459 | def has_valid_update_type(self, pull_request): |
|
459 | def has_valid_update_type(self, pull_request): | |
460 | source_ref_type = pull_request.source_ref_parts.type |
|
460 | source_ref_type = pull_request.source_ref_parts.type | |
461 | return source_ref_type in ['book', 'branch', 'tag'] |
|
461 | return source_ref_type in ['book', 'branch', 'tag'] | |
462 |
|
462 | |||
463 | def update_commits(self, pull_request): |
|
463 | def update_commits(self, pull_request): | |
464 | """ |
|
464 | """ | |
465 | Get the updated list of commits for the pull request |
|
465 | Get the updated list of commits for the pull request | |
466 | and return the new pull request version and the list |
|
466 | and return the new pull request version and the list | |
467 | of commits processed by this update action |
|
467 | of commits processed by this update action | |
468 | """ |
|
468 | """ | |
469 |
|
469 | |||
470 | pull_request = self.__get_pull_request(pull_request) |
|
470 | pull_request = self.__get_pull_request(pull_request) | |
471 | source_ref_type = pull_request.source_ref_parts.type |
|
471 | source_ref_type = pull_request.source_ref_parts.type | |
472 | source_ref_name = pull_request.source_ref_parts.name |
|
472 | source_ref_name = pull_request.source_ref_parts.name | |
473 | source_ref_id = pull_request.source_ref_parts.commit_id |
|
473 | source_ref_id = pull_request.source_ref_parts.commit_id | |
474 |
|
474 | |||
475 | if not self.has_valid_update_type(pull_request): |
|
475 | if not self.has_valid_update_type(pull_request): | |
476 | log.debug( |
|
476 | log.debug( | |
477 | "Skipping update of pull request %s due to ref type: %s", |
|
477 | "Skipping update of pull request %s due to ref type: %s", | |
478 | pull_request, source_ref_type) |
|
478 | pull_request, source_ref_type) | |
479 | return (None, None) |
|
479 | return (None, None) | |
480 |
|
480 | |||
481 | source_repo = pull_request.source_repo.scm_instance() |
|
481 | source_repo = pull_request.source_repo.scm_instance() | |
482 | source_commit = source_repo.get_commit(commit_id=source_ref_name) |
|
482 | source_commit = source_repo.get_commit(commit_id=source_ref_name) | |
483 | if source_ref_id == source_commit.raw_id: |
|
483 | if source_ref_id == source_commit.raw_id: | |
484 | log.debug("Nothing changed in pull request %s", pull_request) |
|
484 | log.debug("Nothing changed in pull request %s", pull_request) | |
485 | return (None, None) |
|
485 | return (None, None) | |
486 |
|
486 | |||
487 | # Finally there is a need for an update |
|
487 | # Finally there is a need for an update | |
488 | pull_request_version = self._create_version_from_snapshot(pull_request) |
|
488 | pull_request_version = self._create_version_from_snapshot(pull_request) | |
489 | self._link_comments_to_version(pull_request_version) |
|
489 | self._link_comments_to_version(pull_request_version) | |
490 |
|
490 | |||
491 | target_ref_type = pull_request.target_ref_parts.type |
|
491 | target_ref_type = pull_request.target_ref_parts.type | |
492 | target_ref_name = pull_request.target_ref_parts.name |
|
492 | target_ref_name = pull_request.target_ref_parts.name | |
493 | target_ref_id = pull_request.target_ref_parts.commit_id |
|
493 | target_ref_id = pull_request.target_ref_parts.commit_id | |
494 | target_repo = pull_request.target_repo.scm_instance() |
|
494 | target_repo = pull_request.target_repo.scm_instance() | |
495 |
|
495 | |||
496 | if target_ref_type in ('tag', 'branch', 'book'): |
|
496 | if target_ref_type in ('tag', 'branch', 'book'): | |
497 | target_commit = target_repo.get_commit(target_ref_name) |
|
497 | target_commit = target_repo.get_commit(target_ref_name) | |
498 | else: |
|
498 | else: | |
499 | target_commit = target_repo.get_commit(target_ref_id) |
|
499 | target_commit = target_repo.get_commit(target_ref_id) | |
500 |
|
500 | |||
501 | # re-compute commit ids |
|
501 | # re-compute commit ids | |
502 | old_commit_ids = set(pull_request.revisions) |
|
502 | old_commit_ids = set(pull_request.revisions) | |
503 | pre_load = ["author", "branch", "date", "message"] |
|
503 | pre_load = ["author", "branch", "date", "message"] | |
504 | commit_ranges = target_repo.compare( |
|
504 | commit_ranges = target_repo.compare( | |
505 | target_commit.raw_id, source_commit.raw_id, source_repo, merge=True, |
|
505 | target_commit.raw_id, source_commit.raw_id, source_repo, merge=True, | |
506 | pre_load=pre_load) |
|
506 | pre_load=pre_load) | |
507 |
|
507 | |||
508 | ancestor = target_repo.get_common_ancestor( |
|
508 | ancestor = target_repo.get_common_ancestor( | |
509 | target_commit.raw_id, source_commit.raw_id, source_repo) |
|
509 | target_commit.raw_id, source_commit.raw_id, source_repo) | |
510 |
|
510 | |||
511 | pull_request.source_ref = '%s:%s:%s' % ( |
|
511 | pull_request.source_ref = '%s:%s:%s' % ( | |
512 | source_ref_type, source_ref_name, source_commit.raw_id) |
|
512 | source_ref_type, source_ref_name, source_commit.raw_id) | |
513 | pull_request.target_ref = '%s:%s:%s' % ( |
|
513 | pull_request.target_ref = '%s:%s:%s' % ( | |
514 | target_ref_type, target_ref_name, ancestor) |
|
514 | target_ref_type, target_ref_name, ancestor) | |
515 | pull_request.revisions = [ |
|
515 | pull_request.revisions = [ | |
516 | commit.raw_id for commit in reversed(commit_ranges)] |
|
516 | commit.raw_id for commit in reversed(commit_ranges)] | |
517 | pull_request.updated_on = datetime.datetime.now() |
|
517 | pull_request.updated_on = datetime.datetime.now() | |
518 | Session().add(pull_request) |
|
518 | Session().add(pull_request) | |
519 | new_commit_ids = set(pull_request.revisions) |
|
519 | new_commit_ids = set(pull_request.revisions) | |
520 |
|
520 | |||
521 | changes = self._calculate_commit_id_changes( |
|
521 | changes = self._calculate_commit_id_changes( | |
522 | old_commit_ids, new_commit_ids) |
|
522 | old_commit_ids, new_commit_ids) | |
523 |
|
523 | |||
524 | old_diff_data, new_diff_data = self._generate_update_diffs( |
|
524 | old_diff_data, new_diff_data = self._generate_update_diffs( | |
525 | pull_request, pull_request_version) |
|
525 | pull_request, pull_request_version) | |
526 |
|
526 | |||
527 | ChangesetCommentsModel().outdate_comments( |
|
527 | ChangesetCommentsModel().outdate_comments( | |
528 | pull_request, old_diff_data=old_diff_data, |
|
528 | pull_request, old_diff_data=old_diff_data, | |
529 | new_diff_data=new_diff_data) |
|
529 | new_diff_data=new_diff_data) | |
530 |
|
530 | |||
531 | file_changes = self._calculate_file_changes( |
|
531 | file_changes = self._calculate_file_changes( | |
532 | old_diff_data, new_diff_data) |
|
532 | old_diff_data, new_diff_data) | |
533 |
|
533 | |||
534 | # Add an automatic comment to the pull request |
|
534 | # Add an automatic comment to the pull request | |
535 | update_comment = ChangesetCommentsModel().create( |
|
535 | update_comment = ChangesetCommentsModel().create( | |
536 | text=self._render_update_message(changes, file_changes), |
|
536 | text=self._render_update_message(changes, file_changes), | |
537 | repo=pull_request.target_repo, |
|
537 | repo=pull_request.target_repo, | |
538 | user=pull_request.author, |
|
538 | user=pull_request.author, | |
539 | pull_request=pull_request, |
|
539 | pull_request=pull_request, | |
540 | send_email=False, renderer=DEFAULT_COMMENTS_RENDERER) |
|
540 | send_email=False, renderer=DEFAULT_COMMENTS_RENDERER) | |
541 |
|
541 | |||
542 | # Update status to "Under Review" for added commits |
|
542 | # Update status to "Under Review" for added commits | |
543 | for commit_id in changes.added: |
|
543 | for commit_id in changes.added: | |
544 | ChangesetStatusModel().set_status( |
|
544 | ChangesetStatusModel().set_status( | |
545 | repo=pull_request.source_repo, |
|
545 | repo=pull_request.source_repo, | |
546 | status=ChangesetStatus.STATUS_UNDER_REVIEW, |
|
546 | status=ChangesetStatus.STATUS_UNDER_REVIEW, | |
547 | comment=update_comment, |
|
547 | comment=update_comment, | |
548 | user=pull_request.author, |
|
548 | user=pull_request.author, | |
549 | pull_request=pull_request, |
|
549 | pull_request=pull_request, | |
550 | revision=commit_id) |
|
550 | revision=commit_id) | |
551 |
|
551 | |||
552 | log.debug( |
|
552 | log.debug( | |
553 | 'Updated pull request %s, added_ids: %s, common_ids: %s, ' |
|
553 | 'Updated pull request %s, added_ids: %s, common_ids: %s, ' | |
554 | 'removed_ids: %s', pull_request.pull_request_id, |
|
554 | 'removed_ids: %s', pull_request.pull_request_id, | |
555 | changes.added, changes.common, changes.removed) |
|
555 | changes.added, changes.common, changes.removed) | |
556 | log.debug('Updated pull request with the following file changes: %s', |
|
556 | log.debug('Updated pull request with the following file changes: %s', | |
557 | file_changes) |
|
557 | file_changes) | |
558 |
|
558 | |||
559 | log.info( |
|
559 | log.info( | |
560 | "Updated pull request %s from commit %s to commit %s, " |
|
560 | "Updated pull request %s from commit %s to commit %s, " | |
561 | "stored new version %s of this pull request.", |
|
561 | "stored new version %s of this pull request.", | |
562 | pull_request.pull_request_id, source_ref_id, |
|
562 | pull_request.pull_request_id, source_ref_id, | |
563 | pull_request.source_ref_parts.commit_id, |
|
563 | pull_request.source_ref_parts.commit_id, | |
564 | pull_request_version.pull_request_version_id) |
|
564 | pull_request_version.pull_request_version_id) | |
565 | Session().commit() |
|
565 | Session().commit() | |
566 | self._trigger_pull_request_hook(pull_request, pull_request.author, |
|
566 | self._trigger_pull_request_hook(pull_request, pull_request.author, | |
567 | 'update') |
|
567 | 'update') | |
568 | return (pull_request_version, changes) |
|
568 | return (pull_request_version, changes) | |
569 |
|
569 | |||
570 | def _create_version_from_snapshot(self, pull_request): |
|
570 | def _create_version_from_snapshot(self, pull_request): | |
571 | version = PullRequestVersion() |
|
571 | version = PullRequestVersion() | |
572 | version.title = pull_request.title |
|
572 | version.title = pull_request.title | |
573 | version.description = pull_request.description |
|
573 | version.description = pull_request.description | |
574 | version.status = pull_request.status |
|
574 | version.status = pull_request.status | |
575 | version.created_on = pull_request.created_on |
|
575 | version.created_on = pull_request.created_on | |
576 | version.updated_on = pull_request.updated_on |
|
576 | version.updated_on = pull_request.updated_on | |
577 | version.user_id = pull_request.user_id |
|
577 | version.user_id = pull_request.user_id | |
578 | version.source_repo = pull_request.source_repo |
|
578 | version.source_repo = pull_request.source_repo | |
579 | version.source_ref = pull_request.source_ref |
|
579 | version.source_ref = pull_request.source_ref | |
580 | version.target_repo = pull_request.target_repo |
|
580 | version.target_repo = pull_request.target_repo | |
581 | version.target_ref = pull_request.target_ref |
|
581 | version.target_ref = pull_request.target_ref | |
582 |
|
582 | |||
583 | version._last_merge_source_rev = pull_request._last_merge_source_rev |
|
583 | version._last_merge_source_rev = pull_request._last_merge_source_rev | |
584 | version._last_merge_target_rev = pull_request._last_merge_target_rev |
|
584 | version._last_merge_target_rev = pull_request._last_merge_target_rev | |
585 | version._last_merge_status = pull_request._last_merge_status |
|
585 | version._last_merge_status = pull_request._last_merge_status | |
586 | version.merge_rev = pull_request.merge_rev |
|
586 | version.merge_rev = pull_request.merge_rev | |
587 |
|
587 | |||
588 | version.revisions = pull_request.revisions |
|
588 | version.revisions = pull_request.revisions | |
589 | version.pull_request = pull_request |
|
589 | version.pull_request = pull_request | |
590 | Session().add(version) |
|
590 | Session().add(version) | |
591 | Session().flush() |
|
591 | Session().flush() | |
592 |
|
592 | |||
593 | return version |
|
593 | return version | |
594 |
|
594 | |||
595 | def _generate_update_diffs(self, pull_request, pull_request_version): |
|
595 | def _generate_update_diffs(self, pull_request, pull_request_version): | |
596 | diff_context = ( |
|
596 | diff_context = ( | |
597 | self.DIFF_CONTEXT + |
|
597 | self.DIFF_CONTEXT + | |
598 | ChangesetCommentsModel.needed_extra_diff_context()) |
|
598 | ChangesetCommentsModel.needed_extra_diff_context()) | |
599 | old_diff = self._get_diff_from_pr_or_version( |
|
599 | old_diff = self._get_diff_from_pr_or_version( | |
600 | pull_request_version, context=diff_context) |
|
600 | pull_request_version, context=diff_context) | |
601 | new_diff = self._get_diff_from_pr_or_version( |
|
601 | new_diff = self._get_diff_from_pr_or_version( | |
602 | pull_request, context=diff_context) |
|
602 | pull_request, context=diff_context) | |
603 |
|
603 | |||
604 | old_diff_data = diffs.DiffProcessor(old_diff) |
|
604 | old_diff_data = diffs.DiffProcessor(old_diff) | |
605 | old_diff_data.prepare() |
|
605 | old_diff_data.prepare() | |
606 | new_diff_data = diffs.DiffProcessor(new_diff) |
|
606 | new_diff_data = diffs.DiffProcessor(new_diff) | |
607 | new_diff_data.prepare() |
|
607 | new_diff_data.prepare() | |
608 |
|
608 | |||
609 | return old_diff_data, new_diff_data |
|
609 | return old_diff_data, new_diff_data | |
610 |
|
610 | |||
611 | def _link_comments_to_version(self, pull_request_version): |
|
611 | def _link_comments_to_version(self, pull_request_version): | |
612 | """ |
|
612 | """ | |
613 | Link all unlinked comments of this pull request to the given version. |
|
613 | Link all unlinked comments of this pull request to the given version. | |
614 |
|
614 | |||
615 | :param pull_request_version: The `PullRequestVersion` to which |
|
615 | :param pull_request_version: The `PullRequestVersion` to which | |
616 | the comments shall be linked. |
|
616 | the comments shall be linked. | |
617 |
|
617 | |||
618 | """ |
|
618 | """ | |
619 | pull_request = pull_request_version.pull_request |
|
619 | pull_request = pull_request_version.pull_request | |
620 | comments = ChangesetComment.query().filter( |
|
620 | comments = ChangesetComment.query().filter( | |
621 | # TODO: johbo: Should we query for the repo at all here? |
|
621 | # TODO: johbo: Should we query for the repo at all here? | |
622 | # Pending decision on how comments of PRs are to be related |
|
622 | # Pending decision on how comments of PRs are to be related | |
623 | # to either the source repo, the target repo or no repo at all. |
|
623 | # to either the source repo, the target repo or no repo at all. | |
624 | ChangesetComment.repo_id == pull_request.target_repo.repo_id, |
|
624 | ChangesetComment.repo_id == pull_request.target_repo.repo_id, | |
625 | ChangesetComment.pull_request == pull_request, |
|
625 | ChangesetComment.pull_request == pull_request, | |
626 | ChangesetComment.pull_request_version == None) |
|
626 | ChangesetComment.pull_request_version == None) | |
627 |
|
627 | |||
628 | # TODO: johbo: Find out why this breaks if it is done in a bulk |
|
628 | # TODO: johbo: Find out why this breaks if it is done in a bulk | |
629 | # operation. |
|
629 | # operation. | |
630 | for comment in comments: |
|
630 | for comment in comments: | |
631 | comment.pull_request_version_id = ( |
|
631 | comment.pull_request_version_id = ( | |
632 | pull_request_version.pull_request_version_id) |
|
632 | pull_request_version.pull_request_version_id) | |
633 | Session().add(comment) |
|
633 | Session().add(comment) | |
634 |
|
634 | |||
635 | def _calculate_commit_id_changes(self, old_ids, new_ids): |
|
635 | def _calculate_commit_id_changes(self, old_ids, new_ids): | |
636 | added = new_ids.difference(old_ids) |
|
636 | added = new_ids.difference(old_ids) | |
637 | common = old_ids.intersection(new_ids) |
|
637 | common = old_ids.intersection(new_ids) | |
638 | removed = old_ids.difference(new_ids) |
|
638 | removed = old_ids.difference(new_ids) | |
639 | return ChangeTuple(added, common, removed) |
|
639 | return ChangeTuple(added, common, removed) | |
640 |
|
640 | |||
641 | def _calculate_file_changes(self, old_diff_data, new_diff_data): |
|
641 | def _calculate_file_changes(self, old_diff_data, new_diff_data): | |
642 |
|
642 | |||
643 | old_files = OrderedDict() |
|
643 | old_files = OrderedDict() | |
644 | for diff_data in old_diff_data.parsed_diff: |
|
644 | for diff_data in old_diff_data.parsed_diff: | |
645 | old_files[diff_data['filename']] = md5_safe(diff_data['raw_diff']) |
|
645 | old_files[diff_data['filename']] = md5_safe(diff_data['raw_diff']) | |
646 |
|
646 | |||
647 | added_files = [] |
|
647 | added_files = [] | |
648 | modified_files = [] |
|
648 | modified_files = [] | |
649 | removed_files = [] |
|
649 | removed_files = [] | |
650 | for diff_data in new_diff_data.parsed_diff: |
|
650 | for diff_data in new_diff_data.parsed_diff: | |
651 | new_filename = diff_data['filename'] |
|
651 | new_filename = diff_data['filename'] | |
652 | new_hash = md5_safe(diff_data['raw_diff']) |
|
652 | new_hash = md5_safe(diff_data['raw_diff']) | |
653 |
|
653 | |||
654 | old_hash = old_files.get(new_filename) |
|
654 | old_hash = old_files.get(new_filename) | |
655 | if not old_hash: |
|
655 | if not old_hash: | |
656 | # file is not present in old diff, means it's added |
|
656 | # file is not present in old diff, means it's added | |
657 | added_files.append(new_filename) |
|
657 | added_files.append(new_filename) | |
658 | else: |
|
658 | else: | |
659 | if new_hash != old_hash: |
|
659 | if new_hash != old_hash: | |
660 | modified_files.append(new_filename) |
|
660 | modified_files.append(new_filename) | |
661 | # now remove a file from old, since we have seen it already |
|
661 | # now remove a file from old, since we have seen it already | |
662 | del old_files[new_filename] |
|
662 | del old_files[new_filename] | |
663 |
|
663 | |||
664 | # removed files is when there are present in old, but not in NEW, |
|
664 | # removed files is when there are present in old, but not in NEW, | |
665 | # since we remove old files that are present in new diff, left-overs |
|
665 | # since we remove old files that are present in new diff, left-overs | |
666 | # if any should be the removed files |
|
666 | # if any should be the removed files | |
667 | removed_files.extend(old_files.keys()) |
|
667 | removed_files.extend(old_files.keys()) | |
668 |
|
668 | |||
669 | return FileChangeTuple(added_files, modified_files, removed_files) |
|
669 | return FileChangeTuple(added_files, modified_files, removed_files) | |
670 |
|
670 | |||
671 | def _render_update_message(self, changes, file_changes): |
|
671 | def _render_update_message(self, changes, file_changes): | |
672 | """ |
|
672 | """ | |
673 | render the message using DEFAULT_COMMENTS_RENDERER (RST renderer), |
|
673 | render the message using DEFAULT_COMMENTS_RENDERER (RST renderer), | |
674 | so it's always looking the same disregarding on which default |
|
674 | so it's always looking the same disregarding on which default | |
675 | renderer system is using. |
|
675 | renderer system is using. | |
676 |
|
676 | |||
677 | :param changes: changes named tuple |
|
677 | :param changes: changes named tuple | |
678 | :param file_changes: file changes named tuple |
|
678 | :param file_changes: file changes named tuple | |
679 |
|
679 | |||
680 | """ |
|
680 | """ | |
681 | new_status = ChangesetStatus.get_status_lbl( |
|
681 | new_status = ChangesetStatus.get_status_lbl( | |
682 | ChangesetStatus.STATUS_UNDER_REVIEW) |
|
682 | ChangesetStatus.STATUS_UNDER_REVIEW) | |
683 |
|
683 | |||
684 | changed_files = ( |
|
684 | changed_files = ( | |
685 | file_changes.added + file_changes.modified + file_changes.removed) |
|
685 | file_changes.added + file_changes.modified + file_changes.removed) | |
686 |
|
686 | |||
687 | params = { |
|
687 | params = { | |
688 | 'under_review_label': new_status, |
|
688 | 'under_review_label': new_status, | |
689 | 'added_commits': changes.added, |
|
689 | 'added_commits': changes.added, | |
690 | 'removed_commits': changes.removed, |
|
690 | 'removed_commits': changes.removed, | |
691 | 'changed_files': changed_files, |
|
691 | 'changed_files': changed_files, | |
692 | 'added_files': file_changes.added, |
|
692 | 'added_files': file_changes.added, | |
693 | 'modified_files': file_changes.modified, |
|
693 | 'modified_files': file_changes.modified, | |
694 | 'removed_files': file_changes.removed, |
|
694 | 'removed_files': file_changes.removed, | |
695 | } |
|
695 | } | |
696 | renderer = RstTemplateRenderer() |
|
696 | renderer = RstTemplateRenderer() | |
697 | return renderer.render('pull_request_update.mako', **params) |
|
697 | return renderer.render('pull_request_update.mako', **params) | |
698 |
|
698 | |||
699 | def edit(self, pull_request, title, description): |
|
699 | def edit(self, pull_request, title, description): | |
700 | pull_request = self.__get_pull_request(pull_request) |
|
700 | pull_request = self.__get_pull_request(pull_request) | |
701 | if pull_request.is_closed(): |
|
701 | if pull_request.is_closed(): | |
702 | raise ValueError('This pull request is closed') |
|
702 | raise ValueError('This pull request is closed') | |
703 | if title: |
|
703 | if title: | |
704 | pull_request.title = title |
|
704 | pull_request.title = title | |
705 | pull_request.description = description |
|
705 | pull_request.description = description | |
706 | pull_request.updated_on = datetime.datetime.now() |
|
706 | pull_request.updated_on = datetime.datetime.now() | |
707 | Session().add(pull_request) |
|
707 | Session().add(pull_request) | |
708 |
|
708 | |||
709 | def update_reviewers(self, pull_request, reviewers_ids): |
|
709 | def update_reviewers(self, pull_request, reviewers_ids): | |
710 | reviewers_ids = set(reviewers_ids) |
|
710 | reviewers_ids = set(reviewers_ids) | |
711 | pull_request = self.__get_pull_request(pull_request) |
|
711 | pull_request = self.__get_pull_request(pull_request) | |
712 | current_reviewers = PullRequestReviewers.query()\ |
|
712 | current_reviewers = PullRequestReviewers.query()\ | |
713 | .filter(PullRequestReviewers.pull_request == |
|
713 | .filter(PullRequestReviewers.pull_request == | |
714 | pull_request).all() |
|
714 | pull_request).all() | |
715 | current_reviewers_ids = set([x.user.user_id for x in current_reviewers]) |
|
715 | current_reviewers_ids = set([x.user.user_id for x in current_reviewers]) | |
716 |
|
716 | |||
717 | ids_to_add = reviewers_ids.difference(current_reviewers_ids) |
|
717 | ids_to_add = reviewers_ids.difference(current_reviewers_ids) | |
718 | ids_to_remove = current_reviewers_ids.difference(reviewers_ids) |
|
718 | ids_to_remove = current_reviewers_ids.difference(reviewers_ids) | |
719 |
|
719 | |||
720 | log.debug("Adding %s reviewers", ids_to_add) |
|
720 | log.debug("Adding %s reviewers", ids_to_add) | |
721 | log.debug("Removing %s reviewers", ids_to_remove) |
|
721 | log.debug("Removing %s reviewers", ids_to_remove) | |
722 | changed = False |
|
722 | changed = False | |
723 | for uid in ids_to_add: |
|
723 | for uid in ids_to_add: | |
724 | changed = True |
|
724 | changed = True | |
725 | _usr = self._get_user(uid) |
|
725 | _usr = self._get_user(uid) | |
726 | reviewer = PullRequestReviewers(_usr, pull_request) |
|
726 | reviewer = PullRequestReviewers(_usr, pull_request) | |
727 | Session().add(reviewer) |
|
727 | Session().add(reviewer) | |
728 |
|
728 | |||
729 | self.notify_reviewers(pull_request, ids_to_add) |
|
729 | self.notify_reviewers(pull_request, ids_to_add) | |
730 |
|
730 | |||
731 | for uid in ids_to_remove: |
|
731 | for uid in ids_to_remove: | |
732 | changed = True |
|
732 | changed = True | |
733 | reviewer = PullRequestReviewers.query()\ |
|
733 | reviewer = PullRequestReviewers.query()\ | |
734 | .filter(PullRequestReviewers.user_id == uid, |
|
734 | .filter(PullRequestReviewers.user_id == uid, | |
735 | PullRequestReviewers.pull_request == pull_request)\ |
|
735 | PullRequestReviewers.pull_request == pull_request)\ | |
736 | .scalar() |
|
736 | .scalar() | |
737 | if reviewer: |
|
737 | if reviewer: | |
738 | Session().delete(reviewer) |
|
738 | Session().delete(reviewer) | |
739 | if changed: |
|
739 | if changed: | |
740 | pull_request.updated_on = datetime.datetime.now() |
|
740 | pull_request.updated_on = datetime.datetime.now() | |
741 | Session().add(pull_request) |
|
741 | Session().add(pull_request) | |
742 |
|
742 | |||
743 | return ids_to_add, ids_to_remove |
|
743 | return ids_to_add, ids_to_remove | |
744 |
|
744 | |||
745 | def notify_reviewers(self, pull_request, reviewers_ids): |
|
745 | def notify_reviewers(self, pull_request, reviewers_ids): | |
746 | # notification to reviewers |
|
746 | # notification to reviewers | |
747 | if not reviewers_ids: |
|
747 | if not reviewers_ids: | |
748 | return |
|
748 | return | |
749 |
|
749 | |||
750 | pull_request_obj = pull_request |
|
750 | pull_request_obj = pull_request | |
751 | # get the current participants of this pull request |
|
751 | # get the current participants of this pull request | |
752 | recipients = reviewers_ids |
|
752 | recipients = reviewers_ids | |
753 | notification_type = EmailNotificationModel.TYPE_PULL_REQUEST |
|
753 | notification_type = EmailNotificationModel.TYPE_PULL_REQUEST | |
754 |
|
754 | |||
755 | pr_source_repo = pull_request_obj.source_repo |
|
755 | pr_source_repo = pull_request_obj.source_repo | |
756 | pr_target_repo = pull_request_obj.target_repo |
|
756 | pr_target_repo = pull_request_obj.target_repo | |
757 |
|
757 | |||
758 | pr_url = h.url( |
|
758 | pr_url = h.url( | |
759 | 'pullrequest_show', |
|
759 | 'pullrequest_show', | |
760 | repo_name=pr_target_repo.repo_name, |
|
760 | repo_name=pr_target_repo.repo_name, | |
761 | pull_request_id=pull_request_obj.pull_request_id, |
|
761 | pull_request_id=pull_request_obj.pull_request_id, | |
762 | qualified=True,) |
|
762 | qualified=True,) | |
763 |
|
763 | |||
764 | # set some variables for email notification |
|
764 | # set some variables for email notification | |
765 | pr_target_repo_url = h.url( |
|
765 | pr_target_repo_url = h.url( | |
766 | 'summary_home', |
|
766 | 'summary_home', | |
767 | repo_name=pr_target_repo.repo_name, |
|
767 | repo_name=pr_target_repo.repo_name, | |
768 | qualified=True) |
|
768 | qualified=True) | |
769 |
|
769 | |||
770 | pr_source_repo_url = h.url( |
|
770 | pr_source_repo_url = h.url( | |
771 | 'summary_home', |
|
771 | 'summary_home', | |
772 | repo_name=pr_source_repo.repo_name, |
|
772 | repo_name=pr_source_repo.repo_name, | |
773 | qualified=True) |
|
773 | qualified=True) | |
774 |
|
774 | |||
775 | # pull request specifics |
|
775 | # pull request specifics | |
776 | pull_request_commits = [ |
|
776 | pull_request_commits = [ | |
777 | (x.raw_id, x.message) |
|
777 | (x.raw_id, x.message) | |
778 | for x in map(pr_source_repo.get_commit, pull_request.revisions)] |
|
778 | for x in map(pr_source_repo.get_commit, pull_request.revisions)] | |
779 |
|
779 | |||
780 | kwargs = { |
|
780 | kwargs = { | |
781 | 'user': pull_request.author, |
|
781 | 'user': pull_request.author, | |
782 | 'pull_request': pull_request_obj, |
|
782 | 'pull_request': pull_request_obj, | |
783 | 'pull_request_commits': pull_request_commits, |
|
783 | 'pull_request_commits': pull_request_commits, | |
784 |
|
784 | |||
785 | 'pull_request_target_repo': pr_target_repo, |
|
785 | 'pull_request_target_repo': pr_target_repo, | |
786 | 'pull_request_target_repo_url': pr_target_repo_url, |
|
786 | 'pull_request_target_repo_url': pr_target_repo_url, | |
787 |
|
787 | |||
788 | 'pull_request_source_repo': pr_source_repo, |
|
788 | 'pull_request_source_repo': pr_source_repo, | |
789 | 'pull_request_source_repo_url': pr_source_repo_url, |
|
789 | 'pull_request_source_repo_url': pr_source_repo_url, | |
790 |
|
790 | |||
791 | 'pull_request_url': pr_url, |
|
791 | 'pull_request_url': pr_url, | |
792 | } |
|
792 | } | |
793 |
|
793 | |||
794 | # pre-generate the subject for notification itself |
|
794 | # pre-generate the subject for notification itself | |
795 | (subject, |
|
795 | (subject, | |
796 | _h, _e, # we don't care about those |
|
796 | _h, _e, # we don't care about those | |
797 | body_plaintext) = EmailNotificationModel().render_email( |
|
797 | body_plaintext) = EmailNotificationModel().render_email( | |
798 | notification_type, **kwargs) |
|
798 | notification_type, **kwargs) | |
799 |
|
799 | |||
800 | # create notification objects, and emails |
|
800 | # create notification objects, and emails | |
801 | NotificationModel().create( |
|
801 | NotificationModel().create( | |
802 | created_by=pull_request.author, |
|
802 | created_by=pull_request.author, | |
803 | notification_subject=subject, |
|
803 | notification_subject=subject, | |
804 | notification_body=body_plaintext, |
|
804 | notification_body=body_plaintext, | |
805 | notification_type=notification_type, |
|
805 | notification_type=notification_type, | |
806 | recipients=recipients, |
|
806 | recipients=recipients, | |
807 | email_kwargs=kwargs, |
|
807 | email_kwargs=kwargs, | |
808 | ) |
|
808 | ) | |
809 |
|
809 | |||
810 | def delete(self, pull_request): |
|
810 | def delete(self, pull_request): | |
811 | pull_request = self.__get_pull_request(pull_request) |
|
811 | pull_request = self.__get_pull_request(pull_request) | |
812 | self._cleanup_merge_workspace(pull_request) |
|
812 | self._cleanup_merge_workspace(pull_request) | |
813 | Session().delete(pull_request) |
|
813 | Session().delete(pull_request) | |
814 |
|
814 | |||
815 | def close_pull_request(self, pull_request, user): |
|
815 | def close_pull_request(self, pull_request, user): | |
816 | pull_request = self.__get_pull_request(pull_request) |
|
816 | pull_request = self.__get_pull_request(pull_request) | |
817 | self._cleanup_merge_workspace(pull_request) |
|
817 | self._cleanup_merge_workspace(pull_request) | |
818 | pull_request.status = PullRequest.STATUS_CLOSED |
|
818 | pull_request.status = PullRequest.STATUS_CLOSED | |
819 | pull_request.updated_on = datetime.datetime.now() |
|
819 | pull_request.updated_on = datetime.datetime.now() | |
820 | Session().add(pull_request) |
|
820 | Session().add(pull_request) | |
821 | self._trigger_pull_request_hook( |
|
821 | self._trigger_pull_request_hook( | |
822 | pull_request, pull_request.author, 'close') |
|
822 | pull_request, pull_request.author, 'close') | |
823 | self._log_action('user_closed_pull_request', user, pull_request) |
|
823 | self._log_action('user_closed_pull_request', user, pull_request) | |
824 |
|
824 | |||
825 | def close_pull_request_with_comment(self, pull_request, user, repo, |
|
825 | def close_pull_request_with_comment(self, pull_request, user, repo, | |
826 | message=None): |
|
826 | message=None): | |
827 | status = ChangesetStatus.STATUS_REJECTED |
|
827 | status = ChangesetStatus.STATUS_REJECTED | |
828 |
|
828 | |||
829 | if not message: |
|
829 | if not message: | |
830 | message = ( |
|
830 | message = ( | |
831 | _('Status change %(transition_icon)s %(status)s') % { |
|
831 | _('Status change %(transition_icon)s %(status)s') % { | |
832 | 'transition_icon': '>', |
|
832 | 'transition_icon': '>', | |
833 | 'status': ChangesetStatus.get_status_lbl(status)}) |
|
833 | 'status': ChangesetStatus.get_status_lbl(status)}) | |
834 |
|
834 | |||
835 | internal_message = _('Closing with') + ' ' + message |
|
835 | internal_message = _('Closing with') + ' ' + message | |
836 |
|
836 | |||
837 | comm = ChangesetCommentsModel().create( |
|
837 | comm = ChangesetCommentsModel().create( | |
838 | text=internal_message, |
|
838 | text=internal_message, | |
839 | repo=repo.repo_id, |
|
839 | repo=repo.repo_id, | |
840 | user=user.user_id, |
|
840 | user=user.user_id, | |
841 | pull_request=pull_request.pull_request_id, |
|
841 | pull_request=pull_request.pull_request_id, | |
842 | f_path=None, |
|
842 | f_path=None, | |
843 | line_no=None, |
|
843 | line_no=None, | |
844 | status_change=ChangesetStatus.get_status_lbl(status), |
|
844 | status_change=ChangesetStatus.get_status_lbl(status), | |
845 | closing_pr=True |
|
845 | closing_pr=True | |
846 | ) |
|
846 | ) | |
847 |
|
847 | |||
848 | ChangesetStatusModel().set_status( |
|
848 | ChangesetStatusModel().set_status( | |
849 | repo.repo_id, |
|
849 | repo.repo_id, | |
850 | status, |
|
850 | status, | |
851 | user.user_id, |
|
851 | user.user_id, | |
852 | comm, |
|
852 | comm, | |
853 | pull_request=pull_request.pull_request_id |
|
853 | pull_request=pull_request.pull_request_id | |
854 | ) |
|
854 | ) | |
855 | Session().flush() |
|
855 | Session().flush() | |
856 |
|
856 | |||
857 | PullRequestModel().close_pull_request( |
|
857 | PullRequestModel().close_pull_request( | |
858 | pull_request.pull_request_id, user) |
|
858 | pull_request.pull_request_id, user) | |
859 |
|
859 | |||
860 | def merge_status(self, pull_request): |
|
860 | def merge_status(self, pull_request): | |
861 | if not self._is_merge_enabled(pull_request): |
|
861 | if not self._is_merge_enabled(pull_request): | |
862 | return False, _('Server-side pull request merging is disabled.') |
|
862 | return False, _('Server-side pull request merging is disabled.') | |
863 | if pull_request.is_closed(): |
|
863 | if pull_request.is_closed(): | |
864 | return False, _('This pull request is closed.') |
|
864 | return False, _('This pull request is closed.') | |
865 | merge_possible, msg = self._check_repo_requirements( |
|
865 | merge_possible, msg = self._check_repo_requirements( | |
866 | target=pull_request.target_repo, source=pull_request.source_repo) |
|
866 | target=pull_request.target_repo, source=pull_request.source_repo) | |
867 | if not merge_possible: |
|
867 | if not merge_possible: | |
868 | return merge_possible, msg |
|
868 | return merge_possible, msg | |
869 |
|
869 | |||
870 | try: |
|
870 | try: | |
871 | resp = self._try_merge(pull_request) |
|
871 | resp = self._try_merge(pull_request) | |
872 | status = resp.possible, self.merge_status_message( |
|
872 | status = resp.possible, self.merge_status_message( | |
873 | resp.failure_reason) |
|
873 | resp.failure_reason) | |
874 | except NotImplementedError: |
|
874 | except NotImplementedError: | |
875 | status = False, _('Pull request merging is not supported.') |
|
875 | status = False, _('Pull request merging is not supported.') | |
876 |
|
876 | |||
877 | return status |
|
877 | return status | |
878 |
|
878 | |||
879 | def _check_repo_requirements(self, target, source): |
|
879 | def _check_repo_requirements(self, target, source): | |
880 | """ |
|
880 | """ | |
881 | Check if `target` and `source` have compatible requirements. |
|
881 | Check if `target` and `source` have compatible requirements. | |
882 |
|
882 | |||
883 | Currently this is just checking for largefiles. |
|
883 | Currently this is just checking for largefiles. | |
884 | """ |
|
884 | """ | |
885 | target_has_largefiles = self._has_largefiles(target) |
|
885 | target_has_largefiles = self._has_largefiles(target) | |
886 | source_has_largefiles = self._has_largefiles(source) |
|
886 | source_has_largefiles = self._has_largefiles(source) | |
887 | merge_possible = True |
|
887 | merge_possible = True | |
888 | message = u'' |
|
888 | message = u'' | |
889 |
|
889 | |||
890 | if target_has_largefiles != source_has_largefiles: |
|
890 | if target_has_largefiles != source_has_largefiles: | |
891 | merge_possible = False |
|
891 | merge_possible = False | |
892 | if source_has_largefiles: |
|
892 | if source_has_largefiles: | |
893 | message = _( |
|
893 | message = _( | |
894 | 'Target repository large files support is disabled.') |
|
894 | 'Target repository large files support is disabled.') | |
895 | else: |
|
895 | else: | |
896 | message = _( |
|
896 | message = _( | |
897 | 'Source repository large files support is disabled.') |
|
897 | 'Source repository large files support is disabled.') | |
898 |
|
898 | |||
899 | return merge_possible, message |
|
899 | return merge_possible, message | |
900 |
|
900 | |||
901 | def _has_largefiles(self, repo): |
|
901 | def _has_largefiles(self, repo): | |
902 | largefiles_ui = VcsSettingsModel(repo=repo).get_ui_settings( |
|
902 | largefiles_ui = VcsSettingsModel(repo=repo).get_ui_settings( | |
903 | 'extensions', 'largefiles') |
|
903 | 'extensions', 'largefiles') | |
904 | return largefiles_ui and largefiles_ui[0].active |
|
904 | return largefiles_ui and largefiles_ui[0].active | |
905 |
|
905 | |||
906 | def _try_merge(self, pull_request): |
|
906 | def _try_merge(self, pull_request): | |
907 | """ |
|
907 | """ | |
908 | Try to merge the pull request and return the merge status. |
|
908 | Try to merge the pull request and return the merge status. | |
909 | """ |
|
909 | """ | |
910 | target_vcs = pull_request.target_repo.scm_instance() |
|
910 | target_vcs = pull_request.target_repo.scm_instance() | |
911 | target_ref = self._refresh_reference( |
|
911 | target_ref = self._refresh_reference( | |
912 | pull_request.target_ref_parts, target_vcs) |
|
912 | pull_request.target_ref_parts, target_vcs) | |
913 |
|
913 | |||
914 | target_locked = pull_request.target_repo.locked |
|
914 | target_locked = pull_request.target_repo.locked | |
915 | if target_locked and target_locked[0]: |
|
915 | if target_locked and target_locked[0]: | |
916 | merge_state = MergeResponse( |
|
916 | merge_state = MergeResponse( | |
917 | False, False, None, MergeFailureReason.TARGET_IS_LOCKED) |
|
917 | False, False, None, MergeFailureReason.TARGET_IS_LOCKED) | |
918 | elif self._needs_merge_state_refresh(pull_request, target_ref): |
|
918 | elif self._needs_merge_state_refresh(pull_request, target_ref): | |
919 | merge_state = self._refresh_merge_state( |
|
919 | merge_state = self._refresh_merge_state( | |
920 | pull_request, target_vcs, target_ref) |
|
920 | pull_request, target_vcs, target_ref) | |
921 | else: |
|
921 | else: | |
922 | possible = pull_request.\ |
|
922 | possible = pull_request.\ | |
923 | _last_merge_status == MergeFailureReason.NONE |
|
923 | _last_merge_status == MergeFailureReason.NONE | |
924 | merge_state = MergeResponse( |
|
924 | merge_state = MergeResponse( | |
925 | possible, False, None, pull_request._last_merge_status) |
|
925 | possible, False, None, pull_request._last_merge_status) | |
926 | return merge_state |
|
926 | return merge_state | |
927 |
|
927 | |||
928 | def _refresh_reference(self, reference, vcs_repository): |
|
928 | def _refresh_reference(self, reference, vcs_repository): | |
929 | if reference.type in ('branch', 'book'): |
|
929 | if reference.type in ('branch', 'book'): | |
930 | name_or_id = reference.name |
|
930 | name_or_id = reference.name | |
931 | else: |
|
931 | else: | |
932 | name_or_id = reference.commit_id |
|
932 | name_or_id = reference.commit_id | |
933 | refreshed_commit = vcs_repository.get_commit(name_or_id) |
|
933 | refreshed_commit = vcs_repository.get_commit(name_or_id) | |
934 | refreshed_reference = Reference( |
|
934 | refreshed_reference = Reference( | |
935 | reference.type, reference.name, refreshed_commit.raw_id) |
|
935 | reference.type, reference.name, refreshed_commit.raw_id) | |
936 | return refreshed_reference |
|
936 | return refreshed_reference | |
937 |
|
937 | |||
938 | def _needs_merge_state_refresh(self, pull_request, target_reference): |
|
938 | def _needs_merge_state_refresh(self, pull_request, target_reference): | |
939 | return not( |
|
939 | return not( | |
940 | pull_request.revisions and |
|
940 | pull_request.revisions and | |
941 | pull_request.revisions[0] == pull_request._last_merge_source_rev and |
|
941 | pull_request.revisions[0] == pull_request._last_merge_source_rev and | |
942 | target_reference.commit_id == pull_request._last_merge_target_rev) |
|
942 | target_reference.commit_id == pull_request._last_merge_target_rev) | |
943 |
|
943 | |||
944 | def _refresh_merge_state(self, pull_request, target_vcs, target_reference): |
|
944 | def _refresh_merge_state(self, pull_request, target_vcs, target_reference): | |
945 | workspace_id = self._workspace_id(pull_request) |
|
945 | workspace_id = self._workspace_id(pull_request) | |
946 | source_vcs = pull_request.source_repo.scm_instance() |
|
946 | source_vcs = pull_request.source_repo.scm_instance() | |
947 | merge_state = target_vcs.merge( |
|
947 | merge_state = target_vcs.merge( | |
948 | target_reference, source_vcs, pull_request.source_ref_parts, |
|
948 | target_reference, source_vcs, pull_request.source_ref_parts, | |
949 | workspace_id, dry_run=True) |
|
949 | workspace_id, dry_run=True) | |
950 |
|
950 | |||
951 | # Do not store the response if there was an unknown error. |
|
951 | # Do not store the response if there was an unknown error. | |
952 | if merge_state.failure_reason != MergeFailureReason.UNKNOWN: |
|
952 | if merge_state.failure_reason != MergeFailureReason.UNKNOWN: | |
953 | pull_request._last_merge_source_rev = pull_request.\ |
|
953 | pull_request._last_merge_source_rev = pull_request.\ | |
954 | source_ref_parts.commit_id |
|
954 | source_ref_parts.commit_id | |
955 | pull_request._last_merge_target_rev = target_reference.commit_id |
|
955 | pull_request._last_merge_target_rev = target_reference.commit_id | |
956 | pull_request._last_merge_status = ( |
|
956 | pull_request._last_merge_status = ( | |
957 | merge_state.failure_reason) |
|
957 | merge_state.failure_reason) | |
958 | Session().add(pull_request) |
|
958 | Session().add(pull_request) | |
959 | Session().flush() |
|
959 | Session().flush() | |
960 |
|
960 | |||
961 | return merge_state |
|
961 | return merge_state | |
962 |
|
962 | |||
963 | def _workspace_id(self, pull_request): |
|
963 | def _workspace_id(self, pull_request): | |
964 | workspace_id = 'pr-%s' % pull_request.pull_request_id |
|
964 | workspace_id = 'pr-%s' % pull_request.pull_request_id | |
965 | return workspace_id |
|
965 | return workspace_id | |
966 |
|
966 | |||
967 | def merge_status_message(self, status_code): |
|
967 | def merge_status_message(self, status_code): | |
968 | """ |
|
968 | """ | |
969 | Return a human friendly error message for the given merge status code. |
|
969 | Return a human friendly error message for the given merge status code. | |
970 | """ |
|
970 | """ | |
971 | return self.MERGE_STATUS_MESSAGES[status_code] |
|
971 | return self.MERGE_STATUS_MESSAGES[status_code] | |
972 |
|
972 | |||
973 | def generate_repo_data(self, repo, commit_id=None, branch=None, |
|
973 | def generate_repo_data(self, repo, commit_id=None, branch=None, | |
974 | bookmark=None): |
|
974 | bookmark=None): | |
975 | all_refs, selected_ref = \ |
|
975 | all_refs, selected_ref = \ | |
976 | self._get_repo_pullrequest_sources( |
|
976 | self._get_repo_pullrequest_sources( | |
977 | repo.scm_instance(), commit_id=commit_id, |
|
977 | repo.scm_instance(), commit_id=commit_id, | |
978 | branch=branch, bookmark=bookmark) |
|
978 | branch=branch, bookmark=bookmark) | |
979 |
|
979 | |||
980 | refs_select2 = [] |
|
980 | refs_select2 = [] | |
981 | for element in all_refs: |
|
981 | for element in all_refs: | |
982 | children = [{'id': x[0], 'text': x[1]} for x in element[0]] |
|
982 | children = [{'id': x[0], 'text': x[1]} for x in element[0]] | |
983 | refs_select2.append({'text': element[1], 'children': children}) |
|
983 | refs_select2.append({'text': element[1], 'children': children}) | |
984 |
|
984 | |||
985 | return { |
|
985 | return { | |
986 | 'user': { |
|
986 | 'user': { | |
987 | 'user_id': repo.user.user_id, |
|
987 | 'user_id': repo.user.user_id, | |
988 | 'username': repo.user.username, |
|
988 | 'username': repo.user.username, | |
989 | 'firstname': repo.user.firstname, |
|
989 | 'firstname': repo.user.firstname, | |
990 | 'lastname': repo.user.lastname, |
|
990 | 'lastname': repo.user.lastname, | |
991 | 'gravatar_link': h.gravatar_url(repo.user.email, 14), |
|
991 | 'gravatar_link': h.gravatar_url(repo.user.email, 14), | |
992 | }, |
|
992 | }, | |
993 | 'description': h.chop_at_smart(repo.description, '\n'), |
|
993 | 'description': h.chop_at_smart(repo.description, '\n'), | |
994 | 'refs': { |
|
994 | 'refs': { | |
995 | 'all_refs': all_refs, |
|
995 | 'all_refs': all_refs, | |
996 | 'selected_ref': selected_ref, |
|
996 | 'selected_ref': selected_ref, | |
997 | 'select2_refs': refs_select2 |
|
997 | 'select2_refs': refs_select2 | |
998 | } |
|
998 | } | |
999 | } |
|
999 | } | |
1000 |
|
1000 | |||
1001 | def generate_pullrequest_title(self, source, source_ref, target): |
|
1001 | def generate_pullrequest_title(self, source, source_ref, target): | |
1002 | return '{source}#{at_ref} to {target}'.format( |
|
1002 | return '{source}#{at_ref} to {target}'.format( | |
1003 | source=source, |
|
1003 | source=source, | |
1004 | at_ref=source_ref, |
|
1004 | at_ref=source_ref, | |
1005 | target=target, |
|
1005 | target=target, | |
1006 | ) |
|
1006 | ) | |
1007 |
|
1007 | |||
1008 | def _cleanup_merge_workspace(self, pull_request): |
|
1008 | def _cleanup_merge_workspace(self, pull_request): | |
1009 | # Merging related cleanup |
|
1009 | # Merging related cleanup | |
1010 | target_scm = pull_request.target_repo.scm_instance() |
|
1010 | target_scm = pull_request.target_repo.scm_instance() | |
1011 | workspace_id = 'pr-%s' % pull_request.pull_request_id |
|
1011 | workspace_id = 'pr-%s' % pull_request.pull_request_id | |
1012 |
|
1012 | |||
1013 | try: |
|
1013 | try: | |
1014 | target_scm.cleanup_merge_workspace(workspace_id) |
|
1014 | target_scm.cleanup_merge_workspace(workspace_id) | |
1015 | except NotImplementedError: |
|
1015 | except NotImplementedError: | |
1016 | pass |
|
1016 | pass | |
1017 |
|
1017 | |||
1018 | def _get_repo_pullrequest_sources( |
|
1018 | def _get_repo_pullrequest_sources( | |
1019 | self, repo, commit_id=None, branch=None, bookmark=None): |
|
1019 | self, repo, commit_id=None, branch=None, bookmark=None): | |
1020 | """ |
|
1020 | """ | |
1021 | Return a structure with repo's interesting commits, suitable for |
|
1021 | Return a structure with repo's interesting commits, suitable for | |
1022 | the selectors in pullrequest controller |
|
1022 | the selectors in pullrequest controller | |
1023 |
|
1023 | |||
1024 | :param commit_id: a commit that must be in the list somehow |
|
1024 | :param commit_id: a commit that must be in the list somehow | |
1025 | and selected by default |
|
1025 | and selected by default | |
1026 | :param branch: a branch that must be in the list and selected |
|
1026 | :param branch: a branch that must be in the list and selected | |
1027 | by default - even if closed |
|
1027 | by default - even if closed | |
1028 | :param bookmark: a bookmark that must be in the list and selected |
|
1028 | :param bookmark: a bookmark that must be in the list and selected | |
1029 | """ |
|
1029 | """ | |
1030 |
|
1030 | |||
1031 | commit_id = safe_str(commit_id) if commit_id else None |
|
1031 | commit_id = safe_str(commit_id) if commit_id else None | |
1032 | branch = safe_str(branch) if branch else None |
|
1032 | branch = safe_str(branch) if branch else None | |
1033 | bookmark = safe_str(bookmark) if bookmark else None |
|
1033 | bookmark = safe_str(bookmark) if bookmark else None | |
1034 |
|
1034 | |||
1035 | selected = None |
|
1035 | selected = None | |
1036 |
|
1036 | |||
1037 | # order matters: first source that has commit_id in it will be selected |
|
1037 | # order matters: first source that has commit_id in it will be selected | |
1038 | sources = [] |
|
1038 | sources = [] | |
1039 | sources.append(('book', repo.bookmarks.items(), _('Bookmarks'), bookmark)) |
|
1039 | sources.append(('book', repo.bookmarks.items(), _('Bookmarks'), bookmark)) | |
1040 | sources.append(('branch', repo.branches.items(), _('Branches'), branch)) |
|
1040 | sources.append(('branch', repo.branches.items(), _('Branches'), branch)) | |
1041 |
|
1041 | |||
1042 | if commit_id: |
|
1042 | if commit_id: | |
1043 | ref_commit = (h.short_id(commit_id), commit_id) |
|
1043 | ref_commit = (h.short_id(commit_id), commit_id) | |
1044 | sources.append(('rev', [ref_commit], _('Commit IDs'), commit_id)) |
|
1044 | sources.append(('rev', [ref_commit], _('Commit IDs'), commit_id)) | |
1045 |
|
1045 | |||
1046 | sources.append( |
|
1046 | sources.append( | |
1047 | ('branch', repo.branches_closed.items(), _('Closed Branches'), branch), |
|
1047 | ('branch', repo.branches_closed.items(), _('Closed Branches'), branch), | |
1048 | ) |
|
1048 | ) | |
1049 |
|
1049 | |||
1050 | groups = [] |
|
1050 | groups = [] | |
1051 | for group_key, ref_list, group_name, match in sources: |
|
1051 | for group_key, ref_list, group_name, match in sources: | |
1052 | group_refs = [] |
|
1052 | group_refs = [] | |
1053 | for ref_name, ref_id in ref_list: |
|
1053 | for ref_name, ref_id in ref_list: | |
1054 | ref_key = '%s:%s:%s' % (group_key, ref_name, ref_id) |
|
1054 | ref_key = '%s:%s:%s' % (group_key, ref_name, ref_id) | |
1055 | group_refs.append((ref_key, ref_name)) |
|
1055 | group_refs.append((ref_key, ref_name)) | |
1056 |
|
1056 | |||
1057 |
if not selected |
|
1057 | if not selected: | |
1058 | selected = ref_key |
|
1058 | if set([commit_id, match]) & set([ref_id, ref_name]): | |
|
1059 | selected = ref_key | |||
|
1060 | ||||
1059 | if group_refs: |
|
1061 | if group_refs: | |
1060 | groups.append((group_refs, group_name)) |
|
1062 | groups.append((group_refs, group_name)) | |
1061 |
|
1063 | |||
1062 | if not selected: |
|
1064 | if not selected: | |
1063 | ref = commit_id or branch or bookmark |
|
1065 | ref = commit_id or branch or bookmark | |
1064 | if ref: |
|
1066 | if ref: | |
1065 | raise CommitDoesNotExistError( |
|
1067 | raise CommitDoesNotExistError( | |
1066 | 'No commit refs could be found matching: %s' % ref) |
|
1068 | 'No commit refs could be found matching: %s' % ref) | |
1067 | elif repo.DEFAULT_BRANCH_NAME in repo.branches: |
|
1069 | elif repo.DEFAULT_BRANCH_NAME in repo.branches: | |
1068 | selected = 'branch:%s:%s' % ( |
|
1070 | selected = 'branch:%s:%s' % ( | |
1069 | repo.DEFAULT_BRANCH_NAME, |
|
1071 | repo.DEFAULT_BRANCH_NAME, | |
1070 | repo.branches[repo.DEFAULT_BRANCH_NAME] |
|
1072 | repo.branches[repo.DEFAULT_BRANCH_NAME] | |
1071 | ) |
|
1073 | ) | |
1072 | elif repo.commit_ids: |
|
1074 | elif repo.commit_ids: | |
1073 | rev = repo.commit_ids[0] |
|
1075 | rev = repo.commit_ids[0] | |
1074 | selected = 'rev:%s:%s' % (rev, rev) |
|
1076 | selected = 'rev:%s:%s' % (rev, rev) | |
1075 | else: |
|
1077 | else: | |
1076 | raise EmptyRepositoryError() |
|
1078 | raise EmptyRepositoryError() | |
1077 | return groups, selected |
|
1079 | return groups, selected | |
1078 |
|
1080 | |||
1079 | def get_diff(self, pull_request, context=DIFF_CONTEXT): |
|
1081 | def get_diff(self, pull_request, context=DIFF_CONTEXT): | |
1080 | pull_request = self.__get_pull_request(pull_request) |
|
1082 | pull_request = self.__get_pull_request(pull_request) | |
1081 | return self._get_diff_from_pr_or_version(pull_request, context=context) |
|
1083 | return self._get_diff_from_pr_or_version(pull_request, context=context) | |
1082 |
|
1084 | |||
1083 | def _get_diff_from_pr_or_version(self, pr_or_version, context): |
|
1085 | def _get_diff_from_pr_or_version(self, pr_or_version, context): | |
1084 | source_repo = pr_or_version.source_repo |
|
1086 | source_repo = pr_or_version.source_repo | |
1085 |
|
1087 | |||
1086 | # we swap org/other ref since we run a simple diff on one repo |
|
1088 | # we swap org/other ref since we run a simple diff on one repo | |
1087 | target_ref_id = pr_or_version.target_ref_parts.commit_id |
|
1089 | target_ref_id = pr_or_version.target_ref_parts.commit_id | |
1088 | source_ref_id = pr_or_version.source_ref_parts.commit_id |
|
1090 | source_ref_id = pr_or_version.source_ref_parts.commit_id | |
1089 | target_commit = source_repo.get_commit( |
|
1091 | target_commit = source_repo.get_commit( | |
1090 | commit_id=safe_str(target_ref_id)) |
|
1092 | commit_id=safe_str(target_ref_id)) | |
1091 | source_commit = source_repo.get_commit(commit_id=safe_str(source_ref_id)) |
|
1093 | source_commit = source_repo.get_commit(commit_id=safe_str(source_ref_id)) | |
1092 | vcs_repo = source_repo.scm_instance() |
|
1094 | vcs_repo = source_repo.scm_instance() | |
1093 |
|
1095 | |||
1094 | # TODO: johbo: In the context of an update, we cannot reach |
|
1096 | # TODO: johbo: In the context of an update, we cannot reach | |
1095 | # the old commit anymore with our normal mechanisms. It needs |
|
1097 | # the old commit anymore with our normal mechanisms. It needs | |
1096 | # some sort of special support in the vcs layer to avoid this |
|
1098 | # some sort of special support in the vcs layer to avoid this | |
1097 | # workaround. |
|
1099 | # workaround. | |
1098 | if (source_commit.raw_id == vcs_repo.EMPTY_COMMIT_ID and |
|
1100 | if (source_commit.raw_id == vcs_repo.EMPTY_COMMIT_ID and | |
1099 | vcs_repo.alias == 'git'): |
|
1101 | vcs_repo.alias == 'git'): | |
1100 | source_commit.raw_id = safe_str(source_ref_id) |
|
1102 | source_commit.raw_id = safe_str(source_ref_id) | |
1101 |
|
1103 | |||
1102 | log.debug('calculating diff between ' |
|
1104 | log.debug('calculating diff between ' | |
1103 | 'source_ref:%s and target_ref:%s for repo `%s`', |
|
1105 | 'source_ref:%s and target_ref:%s for repo `%s`', | |
1104 | target_ref_id, source_ref_id, |
|
1106 | target_ref_id, source_ref_id, | |
1105 | safe_unicode(vcs_repo.path)) |
|
1107 | safe_unicode(vcs_repo.path)) | |
1106 |
|
1108 | |||
1107 | vcs_diff = vcs_repo.get_diff( |
|
1109 | vcs_diff = vcs_repo.get_diff( | |
1108 | commit1=target_commit, commit2=source_commit, context=context) |
|
1110 | commit1=target_commit, commit2=source_commit, context=context) | |
1109 | return vcs_diff |
|
1111 | return vcs_diff | |
1110 |
|
1112 | |||
1111 | def _is_merge_enabled(self, pull_request): |
|
1113 | def _is_merge_enabled(self, pull_request): | |
1112 | settings_model = VcsSettingsModel(repo=pull_request.target_repo) |
|
1114 | settings_model = VcsSettingsModel(repo=pull_request.target_repo) | |
1113 | settings = settings_model.get_general_settings() |
|
1115 | settings = settings_model.get_general_settings() | |
1114 | return settings.get('rhodecode_pr_merge_enabled', False) |
|
1116 | return settings.get('rhodecode_pr_merge_enabled', False) | |
1115 |
|
1117 | |||
1116 | def _log_action(self, action, user, pull_request): |
|
1118 | def _log_action(self, action, user, pull_request): | |
1117 | action_logger( |
|
1119 | action_logger( | |
1118 | user, |
|
1120 | user, | |
1119 | '{action}:{pr_id}'.format( |
|
1121 | '{action}:{pr_id}'.format( | |
1120 | action=action, pr_id=pull_request.pull_request_id), |
|
1122 | action=action, pr_id=pull_request.pull_request_id), | |
1121 | pull_request.target_repo) |
|
1123 | pull_request.target_repo) | |
1122 |
|
1124 | |||
1123 |
|
1125 | |||
1124 | ChangeTuple = namedtuple('ChangeTuple', |
|
1126 | ChangeTuple = namedtuple('ChangeTuple', | |
1125 | ['added', 'common', 'removed']) |
|
1127 | ['added', 'common', 'removed']) | |
1126 |
|
1128 | |||
1127 | FileChangeTuple = namedtuple('FileChangeTuple', |
|
1129 | FileChangeTuple = namedtuple('FileChangeTuple', | |
1128 | ['added', 'modified', 'removed']) |
|
1130 | ['added', 'modified', 'removed']) |
@@ -1,600 +1,605 b'' | |||||
1 | // Default styles |
|
1 | // Default styles | |
2 |
|
2 | |||
3 | .diff-collapse { |
|
3 | .diff-collapse { | |
4 | margin: @padding 0; |
|
4 | margin: @padding 0; | |
5 | text-align: right; |
|
5 | text-align: right; | |
6 | } |
|
6 | } | |
7 |
|
7 | |||
8 | .diff-container { |
|
8 | .diff-container { | |
9 | margin-bottom: @space; |
|
9 | margin-bottom: @space; | |
10 |
|
10 | |||
11 | .diffblock { |
|
11 | .diffblock { | |
12 | margin-bottom: @space; |
|
12 | margin-bottom: @space; | |
13 | } |
|
13 | } | |
14 |
|
14 | |||
15 | &.hidden { |
|
15 | &.hidden { | |
16 | display: none; |
|
16 | display: none; | |
17 | overflow: hidden; |
|
17 | overflow: hidden; | |
18 | } |
|
18 | } | |
19 | } |
|
19 | } | |
20 |
|
20 | |||
21 | .compare_view_files { |
|
21 | .compare_view_files { | |
22 |
|
22 | |||
23 | .diff-container { |
|
23 | .diff-container { | |
24 |
|
24 | |||
25 | .diffblock { |
|
25 | .diffblock { | |
26 | margin-bottom: 0; |
|
26 | margin-bottom: 0; | |
27 | } |
|
27 | } | |
28 | } |
|
28 | } | |
29 | } |
|
29 | } | |
30 |
|
30 | |||
31 | div.diffblock .sidebyside { |
|
31 | div.diffblock .sidebyside { | |
32 | background: #ffffff; |
|
32 | background: #ffffff; | |
33 | } |
|
33 | } | |
34 |
|
34 | |||
35 | div.diffblock { |
|
35 | div.diffblock { | |
36 | overflow-x: auto; |
|
36 | overflow-x: auto; | |
37 | overflow-y: hidden; |
|
37 | overflow-y: hidden; | |
38 | clear: both; |
|
38 | clear: both; | |
39 | padding: 0px; |
|
39 | padding: 0px; | |
40 | background: @grey6; |
|
40 | background: @grey6; | |
41 | border: @border-thickness solid @grey5; |
|
41 | border: @border-thickness solid @grey5; | |
42 | -webkit-border-radius: @border-radius @border-radius 0px 0px; |
|
42 | -webkit-border-radius: @border-radius @border-radius 0px 0px; | |
43 | border-radius: @border-radius @border-radius 0px 0px; |
|
43 | border-radius: @border-radius @border-radius 0px 0px; | |
44 |
|
44 | |||
45 |
|
45 | |||
46 | .comments-number { |
|
46 | .comments-number { | |
47 | float: right; |
|
47 | float: right; | |
48 | } |
|
48 | } | |
49 |
|
49 | |||
50 | // BEGIN CODE-HEADER STYLES |
|
50 | // BEGIN CODE-HEADER STYLES | |
51 |
|
51 | |||
52 | .code-header { |
|
52 | .code-header { | |
53 | background: @grey6; |
|
53 | background: @grey6; | |
54 | padding: 10px 0 10px 0; |
|
54 | padding: 10px 0 10px 0; | |
55 | height: auto; |
|
55 | height: auto; | |
56 | width: 100%; |
|
56 | width: 100%; | |
57 |
|
57 | |||
58 | .hash { |
|
58 | .hash { | |
59 | float: left; |
|
59 | float: left; | |
60 | padding: 2px 0 0 2px; |
|
60 | padding: 2px 0 0 2px; | |
61 | } |
|
61 | } | |
62 |
|
62 | |||
63 | .date { |
|
63 | .date { | |
64 | float: left; |
|
64 | float: left; | |
65 | text-transform: uppercase; |
|
65 | text-transform: uppercase; | |
66 | padding: 4px 0px 0px 2px; |
|
66 | padding: 4px 0px 0px 2px; | |
67 | } |
|
67 | } | |
68 |
|
68 | |||
69 | div { |
|
69 | div { | |
70 | margin-left: 4px; |
|
70 | margin-left: 4px; | |
71 | } |
|
71 | } | |
72 |
|
72 | |||
73 | div.compare_header { |
|
73 | div.compare_header { | |
74 | min-height: 40px; |
|
74 | min-height: 40px; | |
75 | margin: 0; |
|
75 | margin: 0; | |
76 | padding: 0 @padding; |
|
76 | padding: 0 @padding; | |
77 |
|
77 | |||
78 | .drop-menu { |
|
78 | .drop-menu { | |
79 | float:left; |
|
79 | float:left; | |
80 | display: block; |
|
80 | display: block; | |
81 | margin:0 0 @padding 0; |
|
81 | margin:0 0 @padding 0; | |
82 | } |
|
82 | } | |
83 |
|
83 | |||
84 | .compare-label { |
|
84 | .compare-label { | |
85 | float: left; |
|
85 | float: left; | |
86 | clear: both; |
|
86 | clear: both; | |
87 | display: inline-block; |
|
87 | display: inline-block; | |
88 | min-width: 5em; |
|
88 | min-width: 5em; | |
89 | margin: 0; |
|
89 | margin: 0; | |
90 | padding: @button-padding @button-padding @button-padding 0; |
|
90 | padding: @button-padding @button-padding @button-padding 0; | |
91 | font-family: @text-semibold; |
|
91 | font-family: @text-semibold; | |
92 | } |
|
92 | } | |
93 |
|
93 | |||
94 | .compare-buttons { |
|
94 | .compare-buttons { | |
95 | float: left; |
|
95 | float: left; | |
96 | margin: 0; |
|
96 | margin: 0; | |
97 | padding: 0 0 @padding; |
|
97 | padding: 0 0 @padding; | |
98 |
|
98 | |||
99 | .btn { |
|
99 | .btn { | |
100 | margin: 0 @padding 0 0; |
|
100 | margin: 0 @padding 0 0; | |
101 | } |
|
101 | } | |
102 | } |
|
102 | } | |
103 | } |
|
103 | } | |
104 |
|
104 | |||
105 | } |
|
105 | } | |
106 |
|
106 | |||
107 | .parents { |
|
107 | .parents { | |
108 | float: left; |
|
108 | float: left; | |
109 | width: 100px; |
|
109 | width: 100px; | |
110 | font-weight: 400; |
|
110 | font-weight: 400; | |
111 | vertical-align: middle; |
|
111 | vertical-align: middle; | |
112 | padding: 0px 2px 0px 2px; |
|
112 | padding: 0px 2px 0px 2px; | |
113 | background-color: @grey6; |
|
113 | background-color: @grey6; | |
114 |
|
114 | |||
115 | #parent_link { |
|
115 | #parent_link { | |
116 | margin: 00px 2px; |
|
116 | margin: 00px 2px; | |
117 |
|
117 | |||
118 | &.double { |
|
118 | &.double { | |
119 | margin: 0px 2px; |
|
119 | margin: 0px 2px; | |
120 | } |
|
120 | } | |
121 |
|
121 | |||
122 | &.disabled{ |
|
122 | &.disabled{ | |
123 | margin-right: @padding; |
|
123 | margin-right: @padding; | |
124 | } |
|
124 | } | |
125 | } |
|
125 | } | |
126 | } |
|
126 | } | |
127 |
|
127 | |||
128 | .children { |
|
128 | .children { | |
129 | float: right; |
|
129 | float: right; | |
130 | width: 100px; |
|
130 | width: 100px; | |
131 | font-weight: 400; |
|
131 | font-weight: 400; | |
132 | vertical-align: middle; |
|
132 | vertical-align: middle; | |
133 | text-align: right; |
|
133 | text-align: right; | |
134 | padding: 0px 2px 0px 2px; |
|
134 | padding: 0px 2px 0px 2px; | |
135 | background-color: @grey6; |
|
135 | background-color: @grey6; | |
136 |
|
136 | |||
137 | #child_link { |
|
137 | #child_link { | |
138 | margin: 0px 2px; |
|
138 | margin: 0px 2px; | |
139 |
|
139 | |||
140 | &.double { |
|
140 | &.double { | |
141 | margin: 0px 2px; |
|
141 | margin: 0px 2px; | |
142 | } |
|
142 | } | |
143 |
|
143 | |||
144 | &.disabled{ |
|
144 | &.disabled{ | |
145 | margin-right: @padding; |
|
145 | margin-right: @padding; | |
146 | } |
|
146 | } | |
147 | } |
|
147 | } | |
148 | } |
|
148 | } | |
149 |
|
149 | |||
150 | .changeset_header { |
|
150 | .changeset_header { | |
151 | height: 16px; |
|
151 | height: 16px; | |
152 |
|
152 | |||
153 | & > div{ |
|
153 | & > div{ | |
154 | margin-right: @padding; |
|
154 | margin-right: @padding; | |
155 | } |
|
155 | } | |
156 | } |
|
156 | } | |
157 |
|
157 | |||
158 | .changeset_file { |
|
158 | .changeset_file { | |
159 | text-align: left; |
|
159 | text-align: left; | |
160 | float: left; |
|
160 | float: left; | |
161 | padding: 0; |
|
161 | padding: 0; | |
162 |
|
162 | |||
163 | a{ |
|
163 | a{ | |
164 | display: inline-block; |
|
164 | display: inline-block; | |
165 | margin-right: 0.5em; |
|
165 | margin-right: 0.5em; | |
166 | } |
|
166 | } | |
167 |
|
167 | |||
168 | #selected_mode{ |
|
168 | #selected_mode{ | |
169 | margin-left: 0; |
|
169 | margin-left: 0; | |
170 | } |
|
170 | } | |
171 | } |
|
171 | } | |
172 |
|
172 | |||
173 | .diff-menu-wrapper { |
|
173 | .diff-menu-wrapper { | |
174 | float: left; |
|
174 | float: left; | |
175 | } |
|
175 | } | |
176 |
|
176 | |||
177 | .diff-menu { |
|
177 | .diff-menu { | |
178 | position: absolute; |
|
178 | position: absolute; | |
179 | background: none repeat scroll 0 0 #FFFFFF; |
|
179 | background: none repeat scroll 0 0 #FFFFFF; | |
180 | border-color: #003367 @grey3 @grey3; |
|
180 | border-color: #003367 @grey3 @grey3; | |
181 | border-right: 1px solid @grey3; |
|
181 | border-right: 1px solid @grey3; | |
182 | border-style: solid solid solid; |
|
182 | border-style: solid solid solid; | |
183 | border-width: @border-thickness; |
|
183 | border-width: @border-thickness; | |
184 | box-shadow: 2px 8px 4px rgba(0, 0, 0, 0.2); |
|
184 | box-shadow: 2px 8px 4px rgba(0, 0, 0, 0.2); | |
185 | margin-top: 5px; |
|
185 | margin-top: 5px; | |
186 | margin-left: 1px; |
|
186 | margin-left: 1px; | |
187 | } |
|
187 | } | |
188 |
|
188 | |||
189 | .diff-actions, .editor-actions { |
|
189 | .diff-actions, .editor-actions { | |
190 | float: left; |
|
190 | float: left; | |
191 |
|
191 | |||
192 | input{ |
|
192 | input{ | |
193 | margin: 0 0.5em 0 0; |
|
193 | margin: 0 0.5em 0 0; | |
194 | } |
|
194 | } | |
195 | } |
|
195 | } | |
196 |
|
196 | |||
197 | // END CODE-HEADER STYLES |
|
197 | // END CODE-HEADER STYLES | |
198 |
|
198 | |||
199 | // BEGIN CODE-BODY STYLES |
|
199 | // BEGIN CODE-BODY STYLES | |
200 |
|
200 | |||
201 | .code-body { |
|
201 | .code-body { | |
202 | background: white; |
|
202 | background: white; | |
203 | padding: 0; |
|
203 | padding: 0; | |
204 | background-color: #ffffff; |
|
204 | background-color: #ffffff; | |
205 | position: relative; |
|
205 | position: relative; | |
206 | max-width: none; |
|
206 | max-width: none; | |
207 | box-sizing: border-box; |
|
207 | box-sizing: border-box; | |
208 | // TODO: johbo: Parent has overflow: auto, this forces the child here |
|
208 | // TODO: johbo: Parent has overflow: auto, this forces the child here | |
209 | // to have the intended size and to scroll. Should be simplified. |
|
209 | // to have the intended size and to scroll. Should be simplified. | |
210 | width: 100%; |
|
210 | width: 100%; | |
211 | overflow-x: auto; |
|
211 | overflow-x: auto; | |
212 | } |
|
212 | } | |
213 |
|
213 | |||
214 | pre.raw { |
|
214 | pre.raw { | |
215 | background: white; |
|
215 | background: white; | |
216 | color: @grey1; |
|
216 | color: @grey1; | |
217 | } |
|
217 | } | |
218 | // END CODE-BODY STYLES |
|
218 | // END CODE-BODY STYLES | |
219 |
|
219 | |||
220 | } |
|
220 | } | |
221 |
|
221 | |||
222 |
|
222 | |||
223 | table.code-difftable { |
|
223 | table.code-difftable { | |
224 | border-collapse: collapse; |
|
224 | border-collapse: collapse; | |
225 | width: 99%; |
|
225 | width: 99%; | |
226 | border-radius: 0px !important; |
|
226 | border-radius: 0px !important; | |
227 |
|
227 | |||
228 | td { |
|
228 | td { | |
229 | padding: 0 !important; |
|
229 | padding: 0 !important; | |
230 | background: none !important; |
|
230 | background: none !important; | |
231 | border: 0 !important; |
|
231 | border: 0 !important; | |
232 | } |
|
232 | } | |
233 |
|
233 | |||
234 | .context { |
|
234 | .context { | |
235 | background: none repeat scroll 0 0 #DDE7EF; |
|
235 | background: none repeat scroll 0 0 #DDE7EF; | |
236 | } |
|
236 | } | |
237 |
|
237 | |||
238 | .add { |
|
238 | .add { | |
239 | background: none repeat scroll 0 0 #DDFFDD; |
|
239 | background: none repeat scroll 0 0 #DDFFDD; | |
240 |
|
240 | |||
241 | ins { |
|
241 | ins { | |
242 | background: none repeat scroll 0 0 #AAFFAA; |
|
242 | background: none repeat scroll 0 0 #AAFFAA; | |
243 | text-decoration: none; |
|
243 | text-decoration: none; | |
244 | } |
|
244 | } | |
245 | } |
|
245 | } | |
246 |
|
246 | |||
247 | .del { |
|
247 | .del { | |
248 | background: none repeat scroll 0 0 #FFDDDD; |
|
248 | background: none repeat scroll 0 0 #FFDDDD; | |
249 |
|
249 | |||
250 | del { |
|
250 | del { | |
251 | background: none repeat scroll 0 0 #FFAAAA; |
|
251 | background: none repeat scroll 0 0 #FFAAAA; | |
252 | text-decoration: none; |
|
252 | text-decoration: none; | |
253 | } |
|
253 | } | |
254 | } |
|
254 | } | |
255 |
|
255 | |||
256 | /** LINE NUMBERS **/ |
|
256 | /** LINE NUMBERS **/ | |
257 | .lineno { |
|
257 | .lineno { | |
258 | padding-left: 2px; |
|
258 | padding-left: 2px; | |
259 | padding-right: 2px; |
|
259 | padding-right: 2px; | |
260 | text-align: right; |
|
260 | text-align: right; | |
261 | width: 32px; |
|
261 | width: 32px; | |
262 | -moz-user-select: none; |
|
262 | -moz-user-select: none; | |
263 | -webkit-user-select: none; |
|
263 | -webkit-user-select: none; | |
264 | border-right: @border-thickness solid @grey5 !important; |
|
264 | border-right: @border-thickness solid @grey5 !important; | |
265 | border-left: 0px solid #CCC !important; |
|
265 | border-left: 0px solid #CCC !important; | |
266 | border-top: 0px solid #CCC !important; |
|
266 | border-top: 0px solid #CCC !important; | |
267 | border-bottom: none !important; |
|
267 | border-bottom: none !important; | |
268 |
|
268 | |||
269 | a { |
|
269 | a { | |
270 | &:extend(pre); |
|
270 | &:extend(pre); | |
271 | text-align: right; |
|
271 | text-align: right; | |
272 | padding-right: 2px; |
|
272 | padding-right: 2px; | |
273 | cursor: pointer; |
|
273 | cursor: pointer; | |
274 | display: block; |
|
274 | display: block; | |
275 | width: 32px; |
|
275 | width: 32px; | |
276 | } |
|
276 | } | |
277 | } |
|
277 | } | |
278 |
|
278 | |||
279 | .context { |
|
279 | .context { | |
280 | cursor: auto; |
|
280 | cursor: auto; | |
281 | &:extend(pre); |
|
281 | &:extend(pre); | |
282 | } |
|
282 | } | |
283 |
|
283 | |||
284 | .lineno-inline { |
|
284 | .lineno-inline { | |
285 | background: none repeat scroll 0 0 #FFF !important; |
|
285 | background: none repeat scroll 0 0 #FFF !important; | |
286 | padding-left: 2px; |
|
286 | padding-left: 2px; | |
287 | padding-right: 2px; |
|
287 | padding-right: 2px; | |
288 | text-align: right; |
|
288 | text-align: right; | |
289 | width: 30px; |
|
289 | width: 30px; | |
290 | -moz-user-select: none; |
|
290 | -moz-user-select: none; | |
291 | -webkit-user-select: none; |
|
291 | -webkit-user-select: none; | |
292 | } |
|
292 | } | |
293 |
|
293 | |||
294 | /** CODE **/ |
|
294 | /** CODE **/ | |
295 | .code { |
|
295 | .code { | |
296 | display: block; |
|
296 | display: block; | |
297 | width: 100%; |
|
297 | width: 100%; | |
298 |
|
298 | |||
299 | td { |
|
299 | td { | |
300 | margin: 0; |
|
300 | margin: 0; | |
301 | padding: 0; |
|
301 | padding: 0; | |
302 | } |
|
302 | } | |
303 |
|
303 | |||
304 | pre { |
|
304 | pre { | |
305 | margin: 0; |
|
305 | margin: 0; | |
306 | padding: 0; |
|
306 | padding: 0; | |
307 | margin-left: .5em; |
|
307 | margin-left: .5em; | |
308 | } |
|
308 | } | |
309 | } |
|
309 | } | |
310 | } |
|
310 | } | |
311 |
|
311 | |||
312 |
|
312 | |||
313 | // Comments |
|
313 | // Comments | |
314 |
|
314 | |||
315 | div.comment:target { |
|
315 | div.comment:target { | |
316 | border-left: 6px solid @comment-highlight-color; |
|
316 | border-left: 6px solid @comment-highlight-color; | |
317 | padding-left: 3px; |
|
317 | padding-left: 3px; | |
318 | margin-left: -9px; |
|
318 | margin-left: -9px; | |
319 | } |
|
319 | } | |
320 |
|
320 | |||
321 | //TODO: anderson: can't get an absolute number out of anything, so had to put the |
|
321 | //TODO: anderson: can't get an absolute number out of anything, so had to put the | |
322 | //current values that might change. But to make it clear I put as a calculation |
|
322 | //current values that might change. But to make it clear I put as a calculation | |
323 | @comment-max-width: 1065px; |
|
323 | @comment-max-width: 1065px; | |
324 | @pr-extra-margin: 34px; |
|
324 | @pr-extra-margin: 34px; | |
325 | @pr-border-spacing: 4px; |
|
325 | @pr-border-spacing: 4px; | |
326 | @pr-comment-width: @comment-max-width - @pr-extra-margin - @pr-border-spacing; |
|
326 | @pr-comment-width: @comment-max-width - @pr-extra-margin - @pr-border-spacing; | |
327 |
|
327 | |||
328 | // Pull Request |
|
328 | // Pull Request | |
329 | .cs_files .code-difftable { |
|
329 | .cs_files .code-difftable { | |
330 | border: @border-thickness solid @grey5; //borders only on PRs |
|
330 | border: @border-thickness solid @grey5; //borders only on PRs | |
331 |
|
331 | |||
332 | .comment-inline-form, |
|
332 | .comment-inline-form, | |
333 | div.comment { |
|
333 | div.comment { | |
334 | width: @pr-comment-width; |
|
334 | width: @pr-comment-width; | |
335 | } |
|
335 | } | |
336 | } |
|
336 | } | |
337 |
|
337 | |||
338 | // Changeset |
|
338 | // Changeset | |
339 | .code-difftable { |
|
339 | .code-difftable { | |
340 | .comment-inline-form, |
|
340 | .comment-inline-form, | |
341 | div.comment { |
|
341 | div.comment { | |
342 | width: @comment-max-width; |
|
342 | width: @comment-max-width; | |
343 | } |
|
343 | } | |
344 | } |
|
344 | } | |
345 |
|
345 | |||
346 | //Style page |
|
346 | //Style page | |
347 | @style-extra-margin: @sidebar-width + (@sidebarpadding * 3) + @padding; |
|
347 | @style-extra-margin: @sidebar-width + (@sidebarpadding * 3) + @padding; | |
348 | #style-page .code-difftable{ |
|
348 | #style-page .code-difftable{ | |
349 | .comment-inline-form, |
|
349 | .comment-inline-form, | |
350 | div.comment { |
|
350 | div.comment { | |
351 | width: @comment-max-width - @style-extra-margin; |
|
351 | width: @comment-max-width - @style-extra-margin; | |
352 | } |
|
352 | } | |
353 | } |
|
353 | } | |
354 |
|
354 | |||
355 | #context-bar > h2 { |
|
355 | #context-bar > h2 { | |
356 | font-size: 20px; |
|
356 | font-size: 20px; | |
357 | } |
|
357 | } | |
358 |
|
358 | |||
359 | #context-bar > h2> a { |
|
359 | #context-bar > h2> a { | |
360 | font-size: 20px; |
|
360 | font-size: 20px; | |
361 | } |
|
361 | } | |
362 | // end of defaults |
|
362 | // end of defaults | |
363 |
|
363 | |||
364 | .file_diff_buttons { |
|
364 | .file_diff_buttons { | |
365 | padding: 0 0 @padding; |
|
365 | padding: 0 0 @padding; | |
366 |
|
366 | |||
367 | .drop-menu { |
|
367 | .drop-menu { | |
368 | float: left; |
|
368 | float: left; | |
369 | margin: 0 @padding 0 0; |
|
369 | margin: 0 @padding 0 0; | |
370 | } |
|
370 | } | |
371 | .btn { |
|
371 | .btn { | |
372 | margin: 0 @padding 0 0; |
|
372 | margin: 0 @padding 0 0; | |
373 | } |
|
373 | } | |
374 | } |
|
374 | } | |
375 |
|
375 | |||
376 | .code-body.textarea.editor { |
|
376 | .code-body.textarea.editor { | |
377 | max-width: none; |
|
377 | max-width: none; | |
378 | padding: 15px; |
|
378 | padding: 15px; | |
379 | } |
|
379 | } | |
380 |
|
380 | |||
381 | td.injected_diff{ |
|
381 | td.injected_diff{ | |
382 | max-width: 1178px; |
|
382 | max-width: 1178px; | |
383 | overflow-x: auto; |
|
383 | overflow-x: auto; | |
384 | overflow-y: hidden; |
|
384 | overflow-y: hidden; | |
385 |
|
385 | |||
386 | div.diff-container, |
|
386 | div.diff-container, | |
387 | div.diffblock{ |
|
387 | div.diffblock{ | |
388 | max-width: 100%; |
|
388 | max-width: 100%; | |
389 | } |
|
389 | } | |
390 |
|
390 | |||
391 | div.code-body { |
|
391 | div.code-body { | |
392 | max-width: 1124px; |
|
392 | max-width: 1124px; | |
393 | overflow-x: auto; |
|
393 | overflow-x: auto; | |
394 | padding: 0; |
|
394 | padding: 0; | |
395 | } |
|
395 | } | |
396 | div.diffblock { |
|
396 | div.diffblock { | |
397 | border: none; |
|
397 | border: none; | |
398 | } |
|
398 | } | |
399 |
|
399 | |||
400 | &.inline-form { |
|
400 | &.inline-form { | |
401 | width: 99% |
|
401 | width: 99% | |
402 | } |
|
402 | } | |
403 | } |
|
403 | } | |
404 |
|
404 | |||
405 |
|
405 | |||
406 | table.code-difftable { |
|
406 | table.code-difftable { | |
407 | width: 100%; |
|
407 | width: 100%; | |
408 | } |
|
408 | } | |
409 |
|
409 | |||
410 | /** PYGMENTS COLORING **/ |
|
410 | /** PYGMENTS COLORING **/ | |
411 | div.codeblock { |
|
411 | div.codeblock { | |
412 |
|
412 | |||
413 | // TODO: johbo: Added interim to get rid of the margin around |
|
413 | // TODO: johbo: Added interim to get rid of the margin around | |
414 | // Select2 widgets. This needs further cleanup. |
|
414 | // Select2 widgets. This needs further cleanup. | |
415 | margin-top: @padding; |
|
415 | margin-top: @padding; | |
416 |
|
416 | |||
417 | overflow: auto; |
|
417 | overflow: auto; | |
418 | padding: 0px; |
|
418 | padding: 0px; | |
419 | border: @border-thickness solid @grey5; |
|
419 | border: @border-thickness solid @grey5; | |
420 | background: @grey6; |
|
420 | background: @grey6; | |
421 | .border-radius(@border-radius); |
|
421 | .border-radius(@border-radius); | |
422 |
|
422 | |||
423 | #remove_gist { |
|
423 | #remove_gist { | |
424 | float: right; |
|
424 | float: right; | |
425 | } |
|
425 | } | |
426 |
|
426 | |||
427 | .author { |
|
427 | .author { | |
428 | clear: both; |
|
428 | clear: both; | |
429 | vertical-align: middle; |
|
429 | vertical-align: middle; | |
430 | font-family: @text-bold; |
|
430 | font-family: @text-bold; | |
431 | } |
|
431 | } | |
432 |
|
432 | |||
433 | .btn-mini { |
|
433 | .btn-mini { | |
434 | float: left; |
|
434 | float: left; | |
435 | margin: 0 5px 0 0; |
|
435 | margin: 0 5px 0 0; | |
436 | } |
|
436 | } | |
437 |
|
437 | |||
438 | .code-header { |
|
438 | .code-header { | |
439 | padding: @padding; |
|
439 | padding: @padding; | |
440 | border-bottom: @border-thickness solid @grey5; |
|
440 | border-bottom: @border-thickness solid @grey5; | |
441 |
|
441 | |||
|
442 | .rc-user { | |||
|
443 | min-width: 0; | |||
|
444 | margin-right: .5em; | |||
|
445 | } | |||
|
446 | ||||
442 | .stats { |
|
447 | .stats { | |
443 | clear: both; |
|
448 | clear: both; | |
444 | margin: 0 0 @padding 0; |
|
449 | margin: 0 0 @padding 0; | |
445 | padding: 0; |
|
450 | padding: 0; | |
446 | .left { |
|
451 | .left { | |
447 | float: left; |
|
452 | float: left; | |
448 | clear: left; |
|
453 | clear: left; | |
449 | max-width: 75%; |
|
454 | max-width: 75%; | |
450 | margin: 0 0 @padding 0; |
|
455 | margin: 0 0 @padding 0; | |
451 |
|
456 | |||
452 | &.item { |
|
457 | &.item { | |
453 | margin-right: @padding; |
|
458 | margin-right: @padding; | |
454 | &.last { border-right: none; } |
|
459 | &.last { border-right: none; } | |
455 | } |
|
460 | } | |
456 | } |
|
461 | } | |
457 | .buttons { float: right; } |
|
462 | .buttons { float: right; } | |
458 | .author { |
|
463 | .author { | |
459 | height: 25px; margin-left: 15px; font-weight: bold; |
|
464 | height: 25px; margin-left: 15px; font-weight: bold; | |
460 | } |
|
465 | } | |
461 | } |
|
466 | } | |
462 |
|
467 | |||
463 | .commit { |
|
468 | .commit { | |
464 | margin: 5px 0 0 26px; |
|
469 | margin: 5px 0 0 26px; | |
465 | font-weight: normal; |
|
470 | font-weight: normal; | |
466 | white-space: pre-wrap; |
|
471 | white-space: pre-wrap; | |
467 | } |
|
472 | } | |
468 | } |
|
473 | } | |
469 |
|
474 | |||
470 | .message { |
|
475 | .message { | |
471 | position: relative; |
|
476 | position: relative; | |
472 | margin: @padding; |
|
477 | margin: @padding; | |
473 |
|
478 | |||
474 | .codeblock-label { |
|
479 | .codeblock-label { | |
475 | margin: 0 0 1em 0; |
|
480 | margin: 0 0 1em 0; | |
476 | } |
|
481 | } | |
477 | } |
|
482 | } | |
478 |
|
483 | |||
479 | .code-body { |
|
484 | .code-body { | |
480 | padding: @padding; |
|
485 | padding: @padding; | |
481 | background-color: #ffffff; |
|
486 | background-color: #ffffff; | |
482 | min-width: 100%; |
|
487 | min-width: 100%; | |
483 | box-sizing: border-box; |
|
488 | box-sizing: border-box; | |
484 | // TODO: johbo: Parent has overflow: auto, this forces the child here |
|
489 | // TODO: johbo: Parent has overflow: auto, this forces the child here | |
485 | // to have the intended size and to scroll. Should be simplified. |
|
490 | // to have the intended size and to scroll. Should be simplified. | |
486 | width: 100%; |
|
491 | width: 100%; | |
487 | overflow-x: auto; |
|
492 | overflow-x: auto; | |
488 | } |
|
493 | } | |
489 | } |
|
494 | } | |
490 |
|
495 | |||
491 | .code-highlighttable, |
|
496 | .code-highlighttable, | |
492 | div.codeblock .code-body table { |
|
497 | div.codeblock .code-body table { | |
493 | width: 0 !important; |
|
498 | width: 0 !important; | |
494 | border: 0px !important; |
|
499 | border: 0px !important; | |
495 | margin: 0; |
|
500 | margin: 0; | |
496 | letter-spacing: normal; |
|
501 | letter-spacing: normal; | |
497 |
|
502 | |||
498 |
|
503 | |||
499 | td { |
|
504 | td { | |
500 | border: 0px !important; |
|
505 | border: 0px !important; | |
501 | vertical-align: top; |
|
506 | vertical-align: top; | |
502 | } |
|
507 | } | |
503 | } |
|
508 | } | |
504 |
|
509 | |||
505 | div.codeblock .code-header .search-path { padding: 0 0 0 10px; } |
|
510 | div.codeblock .code-header .search-path { padding: 0 0 0 10px; } | |
506 | div.search-code-body { |
|
511 | div.search-code-body { | |
507 | background-color: #ffffff; padding: 5px 0 5px 10px; |
|
512 | background-color: #ffffff; padding: 5px 0 5px 10px; | |
508 | pre { |
|
513 | pre { | |
509 | .match { background-color: #faffa6;} |
|
514 | .match { background-color: #faffa6;} | |
510 | .break { display: block; width: 100%; background-color: #DDE7EF; color: #747474; } |
|
515 | .break { display: block; width: 100%; background-color: #DDE7EF; color: #747474; } | |
511 | } |
|
516 | } | |
512 | } |
|
517 | } | |
513 |
|
518 | |||
514 | div.annotatediv { margin-left: 2px; margin-right: 4px; } |
|
519 | div.annotatediv { margin-left: 2px; margin-right: 4px; } | |
515 | .code-highlight { |
|
520 | .code-highlight { | |
516 | margin: 0; padding: 0; border-left: @border-thickness solid @grey5; |
|
521 | margin: 0; padding: 0; border-left: @border-thickness solid @grey5; | |
517 | pre, .linenodiv pre { padding: 0 5px; margin: 0; } |
|
522 | pre, .linenodiv pre { padding: 0 5px; margin: 0; } | |
518 | pre div:target {background-color: @comment-highlight-color !important;} |
|
523 | pre div:target {background-color: @comment-highlight-color !important;} | |
519 | } |
|
524 | } | |
520 |
|
525 | |||
521 | .linenos a { text-decoration: none; } |
|
526 | .linenos a { text-decoration: none; } | |
522 |
|
527 | |||
523 | .CodeMirror-selected { background: @rchighlightblue; } |
|
528 | .CodeMirror-selected { background: @rchighlightblue; } | |
524 | .CodeMirror-focused .CodeMirror-selected { background: @rchighlightblue; } |
|
529 | .CodeMirror-focused .CodeMirror-selected { background: @rchighlightblue; } | |
525 | .CodeMirror ::selection { background: @rchighlightblue; } |
|
530 | .CodeMirror ::selection { background: @rchighlightblue; } | |
526 | .CodeMirror ::-moz-selection { background: @rchighlightblue; } |
|
531 | .CodeMirror ::-moz-selection { background: @rchighlightblue; } | |
527 |
|
532 | |||
528 | .code { display: block; border:0px !important; } |
|
533 | .code { display: block; border:0px !important; } | |
529 | .code-highlight, |
|
534 | .code-highlight, | |
530 | .codehilite { |
|
535 | .codehilite { | |
531 | .hll { background-color: #ffffcc } |
|
536 | .hll { background-color: #ffffcc } | |
532 | .c { color: #408080; font-style: italic } /* Comment */ |
|
537 | .c { color: #408080; font-style: italic } /* Comment */ | |
533 | .err, .codehilite .err { border: @border-thickness solid #FF0000 } /* Error */ |
|
538 | .err, .codehilite .err { border: @border-thickness solid #FF0000 } /* Error */ | |
534 | .k { color: #008000; font-weight: bold } /* Keyword */ |
|
539 | .k { color: #008000; font-weight: bold } /* Keyword */ | |
535 | .o { color: #666666 } /* Operator */ |
|
540 | .o { color: #666666 } /* Operator */ | |
536 | .cm { color: #408080; font-style: italic } /* Comment.Multiline */ |
|
541 | .cm { color: #408080; font-style: italic } /* Comment.Multiline */ | |
537 | .cp { color: #BC7A00 } /* Comment.Preproc */ |
|
542 | .cp { color: #BC7A00 } /* Comment.Preproc */ | |
538 | .c1 { color: #408080; font-style: italic } /* Comment.Single */ |
|
543 | .c1 { color: #408080; font-style: italic } /* Comment.Single */ | |
539 | .cs { color: #408080; font-style: italic } /* Comment.Special */ |
|
544 | .cs { color: #408080; font-style: italic } /* Comment.Special */ | |
540 | .gd { color: #A00000 } /* Generic.Deleted */ |
|
545 | .gd { color: #A00000 } /* Generic.Deleted */ | |
541 | .ge { font-style: italic } /* Generic.Emph */ |
|
546 | .ge { font-style: italic } /* Generic.Emph */ | |
542 | .gr { color: #FF0000 } /* Generic.Error */ |
|
547 | .gr { color: #FF0000 } /* Generic.Error */ | |
543 | .gh { color: #000080; font-weight: bold } /* Generic.Heading */ |
|
548 | .gh { color: #000080; font-weight: bold } /* Generic.Heading */ | |
544 | .gi { color: #00A000 } /* Generic.Inserted */ |
|
549 | .gi { color: #00A000 } /* Generic.Inserted */ | |
545 | .go { color: #808080 } /* Generic.Output */ |
|
550 | .go { color: #808080 } /* Generic.Output */ | |
546 | .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ |
|
551 | .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ | |
547 | .gs { font-weight: bold } /* Generic.Strong */ |
|
552 | .gs { font-weight: bold } /* Generic.Strong */ | |
548 | .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ |
|
553 | .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ | |
549 | .gt { color: #0040D0 } /* Generic.Traceback */ |
|
554 | .gt { color: #0040D0 } /* Generic.Traceback */ | |
550 | .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ |
|
555 | .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ | |
551 | .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ |
|
556 | .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ | |
552 | .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ |
|
557 | .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ | |
553 | .kp { color: #008000 } /* Keyword.Pseudo */ |
|
558 | .kp { color: #008000 } /* Keyword.Pseudo */ | |
554 | .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ |
|
559 | .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ | |
555 | .kt { color: #B00040 } /* Keyword.Type */ |
|
560 | .kt { color: #B00040 } /* Keyword.Type */ | |
556 | .m { color: #666666 } /* Literal.Number */ |
|
561 | .m { color: #666666 } /* Literal.Number */ | |
557 | .s { color: #BA2121 } /* Literal.String */ |
|
562 | .s { color: #BA2121 } /* Literal.String */ | |
558 | .na { color: #7D9029 } /* Name.Attribute */ |
|
563 | .na { color: #7D9029 } /* Name.Attribute */ | |
559 | .nb { color: #008000 } /* Name.Builtin */ |
|
564 | .nb { color: #008000 } /* Name.Builtin */ | |
560 | .nc { color: #0000FF; font-weight: bold } /* Name.Class */ |
|
565 | .nc { color: #0000FF; font-weight: bold } /* Name.Class */ | |
561 | .no { color: #880000 } /* Name.Constant */ |
|
566 | .no { color: #880000 } /* Name.Constant */ | |
562 | .nd { color: #AA22FF } /* Name.Decorator */ |
|
567 | .nd { color: #AA22FF } /* Name.Decorator */ | |
563 | .ni { color: #999999; font-weight: bold } /* Name.Entity */ |
|
568 | .ni { color: #999999; font-weight: bold } /* Name.Entity */ | |
564 | .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ |
|
569 | .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ | |
565 | .nf { color: #0000FF } /* Name.Function */ |
|
570 | .nf { color: #0000FF } /* Name.Function */ | |
566 | .nl { color: #A0A000 } /* Name.Label */ |
|
571 | .nl { color: #A0A000 } /* Name.Label */ | |
567 | .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ |
|
572 | .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ | |
568 | .nt { color: #008000; font-weight: bold } /* Name.Tag */ |
|
573 | .nt { color: #008000; font-weight: bold } /* Name.Tag */ | |
569 | .nv { color: #19177C } /* Name.Variable */ |
|
574 | .nv { color: #19177C } /* Name.Variable */ | |
570 | .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ |
|
575 | .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ | |
571 | .w { color: #bbbbbb } /* Text.Whitespace */ |
|
576 | .w { color: #bbbbbb } /* Text.Whitespace */ | |
572 | .mf { color: #666666 } /* Literal.Number.Float */ |
|
577 | .mf { color: #666666 } /* Literal.Number.Float */ | |
573 | .mh { color: #666666 } /* Literal.Number.Hex */ |
|
578 | .mh { color: #666666 } /* Literal.Number.Hex */ | |
574 | .mi { color: #666666 } /* Literal.Number.Integer */ |
|
579 | .mi { color: #666666 } /* Literal.Number.Integer */ | |
575 | .mo { color: #666666 } /* Literal.Number.Oct */ |
|
580 | .mo { color: #666666 } /* Literal.Number.Oct */ | |
576 | .sb { color: #BA2121 } /* Literal.String.Backtick */ |
|
581 | .sb { color: #BA2121 } /* Literal.String.Backtick */ | |
577 | .sc { color: #BA2121 } /* Literal.String.Char */ |
|
582 | .sc { color: #BA2121 } /* Literal.String.Char */ | |
578 | .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ |
|
583 | .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ | |
579 | .s2 { color: #BA2121 } /* Literal.String.Double */ |
|
584 | .s2 { color: #BA2121 } /* Literal.String.Double */ | |
580 | .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ |
|
585 | .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ | |
581 | .sh { color: #BA2121 } /* Literal.String.Heredoc */ |
|
586 | .sh { color: #BA2121 } /* Literal.String.Heredoc */ | |
582 | .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ |
|
587 | .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ | |
583 | .sx { color: #008000 } /* Literal.String.Other */ |
|
588 | .sx { color: #008000 } /* Literal.String.Other */ | |
584 | .sr { color: #BB6688 } /* Literal.String.Regex */ |
|
589 | .sr { color: #BB6688 } /* Literal.String.Regex */ | |
585 | .s1 { color: #BA2121 } /* Literal.String.Single */ |
|
590 | .s1 { color: #BA2121 } /* Literal.String.Single */ | |
586 | .ss { color: #19177C } /* Literal.String.Symbol */ |
|
591 | .ss { color: #19177C } /* Literal.String.Symbol */ | |
587 | .bp { color: #008000 } /* Name.Builtin.Pseudo */ |
|
592 | .bp { color: #008000 } /* Name.Builtin.Pseudo */ | |
588 | .vc { color: #19177C } /* Name.Variable.Class */ |
|
593 | .vc { color: #19177C } /* Name.Variable.Class */ | |
589 | .vg { color: #19177C } /* Name.Variable.Global */ |
|
594 | .vg { color: #19177C } /* Name.Variable.Global */ | |
590 | .vi { color: #19177C } /* Name.Variable.Instance */ |
|
595 | .vi { color: #19177C } /* Name.Variable.Instance */ | |
591 | .il { color: #666666 } /* Literal.Number.Integer.Long */ |
|
596 | .il { color: #666666 } /* Literal.Number.Integer.Long */ | |
592 | } |
|
597 | } | |
593 |
|
598 | |||
594 | /* customized pre blocks for markdown/rst */ |
|
599 | /* customized pre blocks for markdown/rst */ | |
595 | pre.literal-block, .codehilite pre{ |
|
600 | pre.literal-block, .codehilite pre{ | |
596 | padding: @padding; |
|
601 | padding: @padding; | |
597 | border: 1px solid @grey6; |
|
602 | border: 1px solid @grey6; | |
598 | .border-radius(@border-radius); |
|
603 | .border-radius(@border-radius); | |
599 | background-color: @grey7; |
|
604 | background-color: @grey7; | |
600 | } |
|
605 | } |
@@ -1,356 +1,361 b'' | |||||
1 | // comments.less |
|
1 | // comments.less | |
2 | // For use in RhodeCode applications; |
|
2 | // For use in RhodeCode applications; | |
3 | // see style guide documentation for guidelines. |
|
3 | // see style guide documentation for guidelines. | |
4 |
|
4 | |||
5 |
|
5 | |||
6 | // Comments |
|
6 | // Comments | |
7 | .comments { |
|
7 | .comments { | |
8 | width: 100%; |
|
8 | width: 100%; | |
9 | } |
|
9 | } | |
10 |
|
10 | |||
11 | tr.inline-comments div { |
|
11 | tr.inline-comments div { | |
12 | max-width: 100%; |
|
12 | max-width: 100%; | |
13 |
|
13 | |||
14 | p { |
|
14 | p { | |
15 | white-space: normal; |
|
15 | white-space: normal; | |
16 | } |
|
16 | } | |
17 |
|
17 | |||
18 | code, pre, .code, dd { |
|
18 | code, pre, .code, dd { | |
19 | overflow-x: auto; |
|
19 | overflow-x: auto; | |
20 | width: 1062px; |
|
20 | width: 1062px; | |
21 | } |
|
21 | } | |
22 |
|
22 | |||
23 | dd { |
|
23 | dd { | |
24 | width: auto; |
|
24 | width: auto; | |
25 | } |
|
25 | } | |
26 | } |
|
26 | } | |
27 |
|
27 | |||
28 | #injected_page_comments { |
|
28 | #injected_page_comments { | |
29 | .comment-previous-link, |
|
29 | .comment-previous-link, | |
30 | .comment-next-link, |
|
30 | .comment-next-link, | |
31 | .comment-links-divider { |
|
31 | .comment-links-divider { | |
32 | display: none; |
|
32 | display: none; | |
33 | } |
|
33 | } | |
34 | } |
|
34 | } | |
35 |
|
35 | |||
36 | .add-comment { |
|
36 | .add-comment { | |
37 | margin-bottom: 10px; |
|
37 | margin-bottom: 10px; | |
38 | } |
|
38 | } | |
39 | .hide-comment-button .add-comment { |
|
39 | .hide-comment-button .add-comment { | |
40 | display: none; |
|
40 | display: none; | |
41 | } |
|
41 | } | |
42 |
|
42 | |||
43 | .comment-bubble { |
|
43 | .comment-bubble { | |
44 | color: @grey4; |
|
44 | color: @grey4; | |
45 | margin-top: 4px; |
|
45 | margin-top: 4px; | |
46 | margin-right: 30px; |
|
46 | margin-right: 30px; | |
47 | visibility: hidden; |
|
47 | visibility: hidden; | |
48 | } |
|
48 | } | |
49 |
|
49 | |||
50 | .comment { |
|
50 | .comment { | |
51 | margin: @padding 0; |
|
51 | margin: @padding 0; | |
52 | padding: 4px 0 0 0; |
|
52 | padding: 4px 0 0 0; | |
53 | line-height: 1em; |
|
53 | line-height: 1em; | |
54 |
|
54 | |||
|
55 | .rc-user { | |||
|
56 | min-width: 0; | |||
|
57 | margin: -2px .5em 0 0; | |||
|
58 | } | |||
|
59 | ||||
55 | .meta { |
|
60 | .meta { | |
56 | position: relative; |
|
61 | position: relative; | |
57 | width: 100%; |
|
62 | width: 100%; | |
58 | margin: 0 0 .5em 0; |
|
63 | margin: 0 0 .5em 0; | |
59 |
|
64 | |||
60 | &:hover .permalink { |
|
65 | &:hover .permalink { | |
61 | visibility: visible; |
|
66 | visibility: visible; | |
62 | color: @rcblue; |
|
67 | color: @rcblue; | |
63 | } |
|
68 | } | |
64 | } |
|
69 | } | |
65 |
|
70 | |||
66 | .author, |
|
71 | .author, | |
67 | .date { |
|
72 | .date { | |
68 | display: inline; |
|
73 | display: inline; | |
69 | margin: 0 .5 0 0; |
|
74 | margin: 0 .5 0 0; | |
70 | padding: 0 .5 0 0; |
|
75 | padding: 0 .5 0 0; | |
71 |
|
76 | |||
72 | &:after { |
|
77 | &:after { | |
73 | content: ' | '; |
|
78 | content: ' | '; | |
74 | color: @grey5; |
|
79 | color: @grey5; | |
75 | } |
|
80 | } | |
76 | } |
|
81 | } | |
77 |
|
82 | |||
78 | .status-change, |
|
83 | .status-change, | |
79 | .permalink, |
|
84 | .permalink, | |
80 | .changeset-status-lbl { |
|
85 | .changeset-status-lbl { | |
81 | display: inline; |
|
86 | display: inline; | |
82 | } |
|
87 | } | |
83 |
|
88 | |||
84 | .permalink { |
|
89 | .permalink { | |
85 | visibility: hidden; |
|
90 | visibility: hidden; | |
86 | } |
|
91 | } | |
87 |
|
92 | |||
88 | .comment-links-divider { |
|
93 | .comment-links-divider { | |
89 | display: inline; |
|
94 | display: inline; | |
90 | } |
|
95 | } | |
91 |
|
96 | |||
92 | .comment-links-block { |
|
97 | .comment-links-block { | |
93 | float:right; |
|
98 | float:right; | |
94 | text-align: right; |
|
99 | text-align: right; | |
95 | min-width: 85px; |
|
100 | min-width: 85px; | |
96 |
|
101 | |||
97 | [class^="icon-"]:before, |
|
102 | [class^="icon-"]:before, | |
98 | [class*=" icon-"]:before { |
|
103 | [class*=" icon-"]:before { | |
99 | margin-left: 0; |
|
104 | margin-left: 0; | |
100 | margin-right: 0; |
|
105 | margin-right: 0; | |
101 | } |
|
106 | } | |
102 | } |
|
107 | } | |
103 |
|
108 | |||
104 | .comment-previous-link { |
|
109 | .comment-previous-link { | |
105 | display: inline-block; |
|
110 | display: inline-block; | |
106 |
|
111 | |||
107 | .arrow_comment_link{ |
|
112 | .arrow_comment_link{ | |
108 | cursor: pointer; |
|
113 | cursor: pointer; | |
109 | i { |
|
114 | i { | |
110 | font-size:10px; |
|
115 | font-size:10px; | |
111 | } |
|
116 | } | |
112 | } |
|
117 | } | |
113 | .arrow_comment_link.disabled { |
|
118 | .arrow_comment_link.disabled { | |
114 | cursor: default; |
|
119 | cursor: default; | |
115 | color: @grey5; |
|
120 | color: @grey5; | |
116 | } |
|
121 | } | |
117 | } |
|
122 | } | |
118 |
|
123 | |||
119 | .comment-next-link { |
|
124 | .comment-next-link { | |
120 | display: inline-block; |
|
125 | display: inline-block; | |
121 |
|
126 | |||
122 | .arrow_comment_link{ |
|
127 | .arrow_comment_link{ | |
123 | cursor: pointer; |
|
128 | cursor: pointer; | |
124 | i { |
|
129 | i { | |
125 | font-size:10px; |
|
130 | font-size:10px; | |
126 | } |
|
131 | } | |
127 | } |
|
132 | } | |
128 | .arrow_comment_link.disabled { |
|
133 | .arrow_comment_link.disabled { | |
129 | cursor: default; |
|
134 | cursor: default; | |
130 | color: @grey5; |
|
135 | color: @grey5; | |
131 | } |
|
136 | } | |
132 | } |
|
137 | } | |
133 |
|
138 | |||
134 | .flag_status { |
|
139 | .flag_status { | |
135 | display: inline-block; |
|
140 | display: inline-block; | |
136 | margin: -2px .5em 0 .25em |
|
141 | margin: -2px .5em 0 .25em | |
137 | } |
|
142 | } | |
138 |
|
143 | |||
139 | .delete-comment { |
|
144 | .delete-comment { | |
140 | display: inline-block; |
|
145 | display: inline-block; | |
141 | color: @rcblue; |
|
146 | color: @rcblue; | |
142 |
|
147 | |||
143 | &:hover { |
|
148 | &:hover { | |
144 | cursor: pointer; |
|
149 | cursor: pointer; | |
145 | } |
|
150 | } | |
146 | } |
|
151 | } | |
147 |
|
152 | |||
148 |
|
153 | |||
149 | .text { |
|
154 | .text { | |
150 | clear: both; |
|
155 | clear: both; | |
151 | border: @border-thickness solid @grey5; |
|
156 | border: @border-thickness solid @grey5; | |
152 | .border-radius(@border-radius); |
|
157 | .border-radius(@border-radius); | |
153 | .box-sizing(border-box); |
|
158 | .box-sizing(border-box); | |
154 |
|
159 | |||
155 | .markdown-block p, |
|
160 | .markdown-block p, | |
156 | .rst-block p { |
|
161 | .rst-block p { | |
157 | margin: .5em 0 !important; |
|
162 | margin: .5em 0 !important; | |
158 | // TODO: lisa: This is needed because of other rst !important rules :[ |
|
163 | // TODO: lisa: This is needed because of other rst !important rules :[ | |
159 | } |
|
164 | } | |
160 | } |
|
165 | } | |
161 | } |
|
166 | } | |
162 |
|
167 | |||
163 | .show-outdated-comments { |
|
168 | .show-outdated-comments { | |
164 | display: inline; |
|
169 | display: inline; | |
165 | color: @rcblue; |
|
170 | color: @rcblue; | |
166 | } |
|
171 | } | |
167 |
|
172 | |||
168 | .outdated { |
|
173 | .outdated { | |
169 | display: none; |
|
174 | display: none; | |
170 | opacity: 0.6; |
|
175 | opacity: 0.6; | |
171 |
|
176 | |||
172 | .comment { |
|
177 | .comment { | |
173 | margin: 0 0 @padding; |
|
178 | margin: 0 0 @padding; | |
174 |
|
179 | |||
175 | .date:after { |
|
180 | .date:after { | |
176 | content: none; |
|
181 | content: none; | |
177 | } |
|
182 | } | |
178 | } |
|
183 | } | |
179 | .outdated_comment_block { |
|
184 | .outdated_comment_block { | |
180 | padding: 0 0 @space 0; |
|
185 | padding: 0 0 @space 0; | |
181 | } |
|
186 | } | |
182 | } |
|
187 | } | |
183 |
|
188 | |||
184 | // Comment Form |
|
189 | // Comment Form | |
185 | div.comment-form { |
|
190 | div.comment-form { | |
186 | margin-top: 20px; |
|
191 | margin-top: 20px; | |
187 | } |
|
192 | } | |
188 |
|
193 | |||
189 | .comment-form strong { |
|
194 | .comment-form strong { | |
190 | display: block; |
|
195 | display: block; | |
191 | margin-bottom: 15px; |
|
196 | margin-bottom: 15px; | |
192 | } |
|
197 | } | |
193 |
|
198 | |||
194 | .comment-form textarea { |
|
199 | .comment-form textarea { | |
195 | width: 100%; |
|
200 | width: 100%; | |
196 | height: 100px; |
|
201 | height: 100px; | |
197 | font-family: 'Monaco', 'Courier', 'Courier New', monospace; |
|
202 | font-family: 'Monaco', 'Courier', 'Courier New', monospace; | |
198 | } |
|
203 | } | |
199 |
|
204 | |||
200 | form.comment-form { |
|
205 | form.comment-form { | |
201 | margin-top: 10px; |
|
206 | margin-top: 10px; | |
202 | margin-left: 10px; |
|
207 | margin-left: 10px; | |
203 | } |
|
208 | } | |
204 |
|
209 | |||
205 | .comment-inline-form .comment-block-ta, |
|
210 | .comment-inline-form .comment-block-ta, | |
206 | .comment-form .comment-block-ta, |
|
211 | .comment-form .comment-block-ta, | |
207 | .comment-form .preview-box { |
|
212 | .comment-form .preview-box { | |
208 | border: @border-thickness solid @grey5; |
|
213 | border: @border-thickness solid @grey5; | |
209 | .border-radius(@border-radius); |
|
214 | .border-radius(@border-radius); | |
210 | .box-sizing(border-box); |
|
215 | .box-sizing(border-box); | |
211 | background-color: white; |
|
216 | background-color: white; | |
212 | } |
|
217 | } | |
213 |
|
218 | |||
214 | .comment-form-submit { |
|
219 | .comment-form-submit { | |
215 | margin-top: 5px; |
|
220 | margin-top: 5px; | |
216 | margin-left: 525px; |
|
221 | margin-left: 525px; | |
217 | } |
|
222 | } | |
218 |
|
223 | |||
219 | .file-comments { |
|
224 | .file-comments { | |
220 | display: none; |
|
225 | display: none; | |
221 | } |
|
226 | } | |
222 |
|
227 | |||
223 | .comment-form .preview-box.unloaded, |
|
228 | .comment-form .preview-box.unloaded, | |
224 | .comment-inline-form .preview-box.unloaded { |
|
229 | .comment-inline-form .preview-box.unloaded { | |
225 | height: 50px; |
|
230 | height: 50px; | |
226 | text-align: center; |
|
231 | text-align: center; | |
227 | padding: 20px; |
|
232 | padding: 20px; | |
228 | background-color: white; |
|
233 | background-color: white; | |
229 | } |
|
234 | } | |
230 |
|
235 | |||
231 | .comment-footer { |
|
236 | .comment-footer { | |
232 | position: relative; |
|
237 | position: relative; | |
233 | width: 100%; |
|
238 | width: 100%; | |
234 | min-height: 42px; |
|
239 | min-height: 42px; | |
235 |
|
240 | |||
236 | .status_box, |
|
241 | .status_box, | |
237 | .cancel-button { |
|
242 | .cancel-button { | |
238 | float: left; |
|
243 | float: left; | |
239 | display: inline-block; |
|
244 | display: inline-block; | |
240 | } |
|
245 | } | |
241 |
|
246 | |||
242 | .action-buttons { |
|
247 | .action-buttons { | |
243 | float: right; |
|
248 | float: right; | |
244 | display: inline-block; |
|
249 | display: inline-block; | |
245 | } |
|
250 | } | |
246 | } |
|
251 | } | |
247 |
|
252 | |||
248 | .comment-form { |
|
253 | .comment-form { | |
249 |
|
254 | |||
250 | .comment { |
|
255 | .comment { | |
251 | margin-left: 10px; |
|
256 | margin-left: 10px; | |
252 | } |
|
257 | } | |
253 |
|
258 | |||
254 | .comment-help { |
|
259 | .comment-help { | |
255 | color: @grey4; |
|
260 | color: @grey4; | |
256 | padding: 5px 0 5px 0; |
|
261 | padding: 5px 0 5px 0; | |
257 | } |
|
262 | } | |
258 |
|
263 | |||
259 | .comment-title { |
|
264 | .comment-title { | |
260 | padding: 5px 0 5px 0; |
|
265 | padding: 5px 0 5px 0; | |
261 | } |
|
266 | } | |
262 |
|
267 | |||
263 | .comment-button { |
|
268 | .comment-button { | |
264 | display: inline-block; |
|
269 | display: inline-block; | |
265 | } |
|
270 | } | |
266 |
|
271 | |||
267 | .comment-button .comment-button-input { |
|
272 | .comment-button .comment-button-input { | |
268 | margin-right: 0; |
|
273 | margin-right: 0; | |
269 | } |
|
274 | } | |
270 |
|
275 | |||
271 | .comment-footer { |
|
276 | .comment-footer { | |
272 | margin-bottom: 110px; |
|
277 | margin-bottom: 110px; | |
273 | } |
|
278 | } | |
274 | } |
|
279 | } | |
275 |
|
280 | |||
276 |
|
281 | |||
277 | .comment-form-login { |
|
282 | .comment-form-login { | |
278 | .comment-help { |
|
283 | .comment-help { | |
279 | padding: 0.9em; //same as the button |
|
284 | padding: 0.9em; //same as the button | |
280 | } |
|
285 | } | |
281 |
|
286 | |||
282 | div.clearfix { |
|
287 | div.clearfix { | |
283 | clear: both; |
|
288 | clear: both; | |
284 | width: 100%; |
|
289 | width: 100%; | |
285 | display: block; |
|
290 | display: block; | |
286 | } |
|
291 | } | |
287 | } |
|
292 | } | |
288 |
|
293 | |||
289 | .preview-box { |
|
294 | .preview-box { | |
290 | padding: 10px; |
|
295 | padding: 10px; | |
291 | min-height: 100px; |
|
296 | min-height: 100px; | |
292 | margin-bottom: 15px; |
|
297 | margin-bottom: 15px; | |
293 | background-color: white; |
|
298 | background-color: white; | |
294 | border: @border-thickness solid #ccc; |
|
299 | border: @border-thickness solid #ccc; | |
295 | .border-radius(@border-radius); |
|
300 | .border-radius(@border-radius); | |
296 | .box-sizing(border-box); |
|
301 | .box-sizing(border-box); | |
297 | } |
|
302 | } | |
298 |
|
303 | |||
299 | .add-another-button { |
|
304 | .add-another-button { | |
300 | margin-left: 10px; |
|
305 | margin-left: 10px; | |
301 | margin-top: 10px; |
|
306 | margin-top: 10px; | |
302 | margin-bottom: 10px; |
|
307 | margin-bottom: 10px; | |
303 | } |
|
308 | } | |
304 |
|
309 | |||
305 | .comment .buttons { |
|
310 | .comment .buttons { | |
306 | float: right; |
|
311 | float: right; | |
307 | margin: -1px 0px 0px 0px; |
|
312 | margin: -1px 0px 0px 0px; | |
308 | } |
|
313 | } | |
309 |
|
314 | |||
310 | // Inline Comment Form |
|
315 | // Inline Comment Form | |
311 | .injected_diff .comment-inline-form, |
|
316 | .injected_diff .comment-inline-form, | |
312 | .comment-inline-form { |
|
317 | .comment-inline-form { | |
313 | background-color: @grey6; |
|
318 | background-color: @grey6; | |
314 | margin-top: 10px; |
|
319 | margin-top: 10px; | |
315 | margin-bottom: 20px; |
|
320 | margin-bottom: 20px; | |
316 | } |
|
321 | } | |
317 |
|
322 | |||
318 | .inline-form { |
|
323 | .inline-form { | |
319 | padding: 10px 7px; |
|
324 | padding: 10px 7px; | |
320 | } |
|
325 | } | |
321 |
|
326 | |||
322 | .inline-form div { |
|
327 | .inline-form div { | |
323 | max-width: 100%; |
|
328 | max-width: 100%; | |
324 | } |
|
329 | } | |
325 |
|
330 | |||
326 | .overlay { |
|
331 | .overlay { | |
327 | display: none; |
|
332 | display: none; | |
328 | position: absolute; |
|
333 | position: absolute; | |
329 | width: 100%; |
|
334 | width: 100%; | |
330 | text-align: center; |
|
335 | text-align: center; | |
331 | vertical-align: middle; |
|
336 | vertical-align: middle; | |
332 | font-size: 16px; |
|
337 | font-size: 16px; | |
333 | background: none repeat scroll 0 0 white; |
|
338 | background: none repeat scroll 0 0 white; | |
334 |
|
339 | |||
335 | &.submitting { |
|
340 | &.submitting { | |
336 | display: block; |
|
341 | display: block; | |
337 | opacity: 0.5; |
|
342 | opacity: 0.5; | |
338 | z-index: 100; |
|
343 | z-index: 100; | |
339 | } |
|
344 | } | |
340 | } |
|
345 | } | |
341 | .comment-inline-form .overlay.submitting .overlay-text { |
|
346 | .comment-inline-form .overlay.submitting .overlay-text { | |
342 | margin-top: 5%; |
|
347 | margin-top: 5%; | |
343 | } |
|
348 | } | |
344 |
|
349 | |||
345 | .comment-inline-form .clearfix, |
|
350 | .comment-inline-form .clearfix, | |
346 | .comment-form .clearfix { |
|
351 | .comment-form .clearfix { | |
347 | .border-radius(@border-radius); |
|
352 | .border-radius(@border-radius); | |
348 | margin: 0px; |
|
353 | margin: 0px; | |
349 | } |
|
354 | } | |
350 |
|
355 | |||
351 | .hide-inline-form-button { |
|
356 | .hide-inline-form-button { | |
352 | margin-left: 5px; |
|
357 | margin-left: 5px; | |
353 | } |
|
358 | } | |
354 | .comment-button .hide-inline-form { |
|
359 | .comment-button .hide-inline-form { | |
355 | background: white; |
|
360 | background: white; | |
356 | } |
|
361 | } |
@@ -1,2076 +1,2087 b'' | |||||
1 | //Primary CSS |
|
1 | //Primary CSS | |
2 |
|
2 | |||
3 | //--- IMPORTS ------------------// |
|
3 | //--- IMPORTS ------------------// | |
4 |
|
4 | |||
5 | @import 'helpers'; |
|
5 | @import 'helpers'; | |
6 | @import 'mixins'; |
|
6 | @import 'mixins'; | |
7 | @import 'rcicons'; |
|
7 | @import 'rcicons'; | |
8 | @import 'fonts'; |
|
8 | @import 'fonts'; | |
9 | @import 'variables'; |
|
9 | @import 'variables'; | |
10 | @import 'bootstrap-variables'; |
|
10 | @import 'bootstrap-variables'; | |
11 | @import 'form-bootstrap'; |
|
11 | @import 'form-bootstrap'; | |
12 | @import 'codemirror'; |
|
12 | @import 'codemirror'; | |
13 | @import 'legacy_code_styles'; |
|
13 | @import 'legacy_code_styles'; | |
14 | @import 'progress-bar'; |
|
14 | @import 'progress-bar'; | |
15 |
|
15 | |||
16 | @import 'type'; |
|
16 | @import 'type'; | |
17 | @import 'alerts'; |
|
17 | @import 'alerts'; | |
18 | @import 'buttons'; |
|
18 | @import 'buttons'; | |
19 | @import 'tags'; |
|
19 | @import 'tags'; | |
20 | @import 'code-block'; |
|
20 | @import 'code-block'; | |
21 | @import 'examples'; |
|
21 | @import 'examples'; | |
22 | @import 'login'; |
|
22 | @import 'login'; | |
23 | @import 'main-content'; |
|
23 | @import 'main-content'; | |
24 | @import 'select2'; |
|
24 | @import 'select2'; | |
25 | @import 'comments'; |
|
25 | @import 'comments'; | |
26 | @import 'panels-bootstrap'; |
|
26 | @import 'panels-bootstrap'; | |
27 | @import 'panels'; |
|
27 | @import 'panels'; | |
28 |
|
28 | |||
29 |
|
29 | |||
30 | //--- BASE ------------------// |
|
30 | //--- BASE ------------------// | |
31 | .noscript-error { |
|
31 | .noscript-error { | |
32 | top: 0; |
|
32 | top: 0; | |
33 | left: 0; |
|
33 | left: 0; | |
34 | width: 100%; |
|
34 | width: 100%; | |
35 | z-index: 101; |
|
35 | z-index: 101; | |
36 | text-align: center; |
|
36 | text-align: center; | |
37 | font-family: @text-semibold; |
|
37 | font-family: @text-semibold; | |
38 | font-size: 120%; |
|
38 | font-size: 120%; | |
39 | color: white; |
|
39 | color: white; | |
40 | background-color: @alert2; |
|
40 | background-color: @alert2; | |
41 | padding: 5px 0 5px 0; |
|
41 | padding: 5px 0 5px 0; | |
42 | } |
|
42 | } | |
43 |
|
43 | |||
44 | html { |
|
44 | html { | |
45 | display: table; |
|
45 | display: table; | |
46 | height: 100%; |
|
46 | height: 100%; | |
47 | width: 100%; |
|
47 | width: 100%; | |
48 | } |
|
48 | } | |
49 |
|
49 | |||
50 | body { |
|
50 | body { | |
51 | display: table-cell; |
|
51 | display: table-cell; | |
52 | width: 100%; |
|
52 | width: 100%; | |
53 | } |
|
53 | } | |
54 |
|
54 | |||
55 | //--- LAYOUT ------------------// |
|
55 | //--- LAYOUT ------------------// | |
56 |
|
56 | |||
57 | .hidden{ |
|
57 | .hidden{ | |
58 | display: none !important; |
|
58 | display: none !important; | |
59 | } |
|
59 | } | |
60 |
|
60 | |||
61 | .box{ |
|
61 | .box{ | |
62 | float: left; |
|
62 | float: left; | |
63 | width: 100%; |
|
63 | width: 100%; | |
64 | } |
|
64 | } | |
65 |
|
65 | |||
66 | .browser-header { |
|
66 | .browser-header { | |
67 | clear: both; |
|
67 | clear: both; | |
68 | } |
|
68 | } | |
69 | .main { |
|
69 | .main { | |
70 | clear: both; |
|
70 | clear: both; | |
71 | padding:0 0 @pagepadding; |
|
71 | padding:0 0 @pagepadding; | |
72 | height: auto; |
|
72 | height: auto; | |
73 |
|
73 | |||
74 | &:after { //clearfix |
|
74 | &:after { //clearfix | |
75 | content:""; |
|
75 | content:""; | |
76 | clear:both; |
|
76 | clear:both; | |
77 | width:100%; |
|
77 | width:100%; | |
78 | display:block; |
|
78 | display:block; | |
79 | } |
|
79 | } | |
80 | } |
|
80 | } | |
81 |
|
81 | |||
82 | .action-link{ |
|
82 | .action-link{ | |
83 | margin-left: @padding; |
|
83 | margin-left: @padding; | |
84 | padding-left: @padding; |
|
84 | padding-left: @padding; | |
85 | border-left: @border-thickness solid @border-default-color; |
|
85 | border-left: @border-thickness solid @border-default-color; | |
86 | } |
|
86 | } | |
87 |
|
87 | |||
88 | input + .action-link, .action-link.first{ |
|
88 | input + .action-link, .action-link.first{ | |
89 | border-left: none; |
|
89 | border-left: none; | |
90 | } |
|
90 | } | |
91 |
|
91 | |||
92 | .action-link.last{ |
|
92 | .action-link.last{ | |
93 | margin-right: @padding; |
|
93 | margin-right: @padding; | |
94 | padding-right: @padding; |
|
94 | padding-right: @padding; | |
95 | } |
|
95 | } | |
96 |
|
96 | |||
97 | .action-link.active, |
|
97 | .action-link.active, | |
98 | .action-link.active a{ |
|
98 | .action-link.active a{ | |
99 | color: @grey4; |
|
99 | color: @grey4; | |
100 | } |
|
100 | } | |
101 |
|
101 | |||
102 | ul.simple-list{ |
|
102 | ul.simple-list{ | |
103 | list-style: none; |
|
103 | list-style: none; | |
104 | margin: 0; |
|
104 | margin: 0; | |
105 | padding: 0; |
|
105 | padding: 0; | |
106 | } |
|
106 | } | |
107 |
|
107 | |||
108 | .main-content { |
|
108 | .main-content { | |
109 | padding-bottom: @pagepadding; |
|
109 | padding-bottom: @pagepadding; | |
110 | } |
|
110 | } | |
111 |
|
111 | |||
112 | .wrapper { |
|
112 | .wrapper { | |
113 | position: relative; |
|
113 | position: relative; | |
114 | max-width: @wrapper-maxwidth; |
|
114 | max-width: @wrapper-maxwidth; | |
115 | margin: 0 auto; |
|
115 | margin: 0 auto; | |
116 | } |
|
116 | } | |
117 |
|
117 | |||
118 | #content { |
|
118 | #content { | |
119 | clear: both; |
|
119 | clear: both; | |
120 | padding: 0 @contentpadding; |
|
120 | padding: 0 @contentpadding; | |
121 | } |
|
121 | } | |
122 |
|
122 | |||
123 | .advanced-settings-fields{ |
|
123 | .advanced-settings-fields{ | |
124 | input{ |
|
124 | input{ | |
125 | margin-left: @textmargin; |
|
125 | margin-left: @textmargin; | |
126 | margin-right: @padding/2; |
|
126 | margin-right: @padding/2; | |
127 | } |
|
127 | } | |
128 | } |
|
128 | } | |
129 |
|
129 | |||
130 | .cs_files_title { |
|
130 | .cs_files_title { | |
131 | margin: @pagepadding 0 0; |
|
131 | margin: @pagepadding 0 0; | |
132 | } |
|
132 | } | |
133 |
|
133 | |||
134 | input.inline[type="file"] { |
|
134 | input.inline[type="file"] { | |
135 | display: inline; |
|
135 | display: inline; | |
136 | } |
|
136 | } | |
137 |
|
137 | |||
138 | .error_page { |
|
138 | .error_page { | |
139 | margin: 10% auto; |
|
139 | margin: 10% auto; | |
140 |
|
140 | |||
141 | h1 { |
|
141 | h1 { | |
142 | color: @grey2; |
|
142 | color: @grey2; | |
143 | } |
|
143 | } | |
144 |
|
144 | |||
145 | .error-branding { |
|
145 | .error-branding { | |
146 | font-family: @text-semibold; |
|
146 | font-family: @text-semibold; | |
147 | color: @grey4; |
|
147 | color: @grey4; | |
148 | } |
|
148 | } | |
149 |
|
149 | |||
150 | .error_message { |
|
150 | .error_message { | |
151 | font-family: @text-regular; |
|
151 | font-family: @text-regular; | |
152 | } |
|
152 | } | |
153 |
|
153 | |||
154 | .sidebar { |
|
154 | .sidebar { | |
155 | min-height: 275px; |
|
155 | min-height: 275px; | |
156 | margin: 0; |
|
156 | margin: 0; | |
157 | padding: 0 0 @sidebarpadding @sidebarpadding; |
|
157 | padding: 0 0 @sidebarpadding @sidebarpadding; | |
158 | border: none; |
|
158 | border: none; | |
159 | } |
|
159 | } | |
160 |
|
160 | |||
161 | .main-content { |
|
161 | .main-content { | |
162 | position: relative; |
|
162 | position: relative; | |
163 | margin: 0 @sidebarpadding @sidebarpadding; |
|
163 | margin: 0 @sidebarpadding @sidebarpadding; | |
164 | padding: 0 0 0 @sidebarpadding; |
|
164 | padding: 0 0 0 @sidebarpadding; | |
165 | border-left: @border-thickness solid @grey5; |
|
165 | border-left: @border-thickness solid @grey5; | |
166 |
|
166 | |||
167 | @media (max-width:767px) { |
|
167 | @media (max-width:767px) { | |
168 | clear: both; |
|
168 | clear: both; | |
169 | width: 100%; |
|
169 | width: 100%; | |
170 | margin: 0; |
|
170 | margin: 0; | |
171 | border: none; |
|
171 | border: none; | |
172 | } |
|
172 | } | |
173 | } |
|
173 | } | |
174 |
|
174 | |||
175 | .inner-column { |
|
175 | .inner-column { | |
176 | float: left; |
|
176 | float: left; | |
177 | width: 29.75%; |
|
177 | width: 29.75%; | |
178 | min-height: 150px; |
|
178 | min-height: 150px; | |
179 | margin: @sidebarpadding 2% 0 0; |
|
179 | margin: @sidebarpadding 2% 0 0; | |
180 | padding: 0 2% 0 0; |
|
180 | padding: 0 2% 0 0; | |
181 | border-right: @border-thickness solid @grey5; |
|
181 | border-right: @border-thickness solid @grey5; | |
182 |
|
182 | |||
183 | @media (max-width:767px) { |
|
183 | @media (max-width:767px) { | |
184 | clear: both; |
|
184 | clear: both; | |
185 | width: 100%; |
|
185 | width: 100%; | |
186 | border: none; |
|
186 | border: none; | |
187 | } |
|
187 | } | |
188 |
|
188 | |||
189 | ul { |
|
189 | ul { | |
190 | padding-left: 1.25em; |
|
190 | padding-left: 1.25em; | |
191 | } |
|
191 | } | |
192 |
|
192 | |||
193 | &:last-child { |
|
193 | &:last-child { | |
194 | margin: @sidebarpadding 0 0; |
|
194 | margin: @sidebarpadding 0 0; | |
195 | border: none; |
|
195 | border: none; | |
196 | } |
|
196 | } | |
197 |
|
197 | |||
198 | h4 { |
|
198 | h4 { | |
199 | margin: 0 0 @padding; |
|
199 | margin: 0 0 @padding; | |
200 | font-family: @text-semibold; |
|
200 | font-family: @text-semibold; | |
201 | } |
|
201 | } | |
202 | } |
|
202 | } | |
203 | } |
|
203 | } | |
204 | .error-page-logo { |
|
204 | .error-page-logo { | |
205 | width: 130px; |
|
205 | width: 130px; | |
206 | height: 160px; |
|
206 | height: 160px; | |
207 | } |
|
207 | } | |
208 |
|
208 | |||
209 | // HEADER |
|
209 | // HEADER | |
210 | .header { |
|
210 | .header { | |
211 |
|
211 | |||
212 | // TODO: johbo: Fix login pages, so that they work without a min-height |
|
212 | // TODO: johbo: Fix login pages, so that they work without a min-height | |
213 | // for the header and then remove the min-height. I chose a smaller value |
|
213 | // for the header and then remove the min-height. I chose a smaller value | |
214 | // intentionally here to avoid rendering issues in the main navigation. |
|
214 | // intentionally here to avoid rendering issues in the main navigation. | |
215 | min-height: 49px; |
|
215 | min-height: 49px; | |
216 |
|
216 | |||
217 | position: relative; |
|
217 | position: relative; | |
218 | vertical-align: bottom; |
|
218 | vertical-align: bottom; | |
219 | padding: 0 @header-padding; |
|
219 | padding: 0 @header-padding; | |
220 | background-color: @grey2; |
|
220 | background-color: @grey2; | |
221 | color: @grey5; |
|
221 | color: @grey5; | |
222 |
|
222 | |||
223 | .title { |
|
223 | .title { | |
224 | overflow: visible; |
|
224 | overflow: visible; | |
225 | } |
|
225 | } | |
226 |
|
226 | |||
227 | &:before, |
|
227 | &:before, | |
228 | &:after { |
|
228 | &:after { | |
229 | content: ""; |
|
229 | content: ""; | |
230 | clear: both; |
|
230 | clear: both; | |
231 | width: 100%; |
|
231 | width: 100%; | |
232 | } |
|
232 | } | |
233 |
|
233 | |||
234 | // TODO: johbo: Avoids breaking "Repositories" chooser |
|
234 | // TODO: johbo: Avoids breaking "Repositories" chooser | |
235 | .select2-container .select2-choice .select2-arrow { |
|
235 | .select2-container .select2-choice .select2-arrow { | |
236 | display: none; |
|
236 | display: none; | |
237 | } |
|
237 | } | |
238 | } |
|
238 | } | |
239 |
|
239 | |||
240 | #header-inner { |
|
240 | #header-inner { | |
241 | &.title { |
|
241 | &.title { | |
242 | margin: 0; |
|
242 | margin: 0; | |
243 | } |
|
243 | } | |
244 | &:before, |
|
244 | &:before, | |
245 | &:after { |
|
245 | &:after { | |
246 | content: ""; |
|
246 | content: ""; | |
247 | clear: both; |
|
247 | clear: both; | |
248 | } |
|
248 | } | |
249 | } |
|
249 | } | |
250 |
|
250 | |||
251 | // Gists |
|
251 | // Gists | |
252 | #files_data { |
|
252 | #files_data { | |
253 | clear: both; //for firefox |
|
253 | clear: both; //for firefox | |
254 | } |
|
254 | } | |
255 | #gistid { |
|
255 | #gistid { | |
256 | margin-right: @padding; |
|
256 | margin-right: @padding; | |
257 | } |
|
257 | } | |
258 |
|
258 | |||
259 | // Global Settings Editor |
|
259 | // Global Settings Editor | |
260 | .textarea.editor { |
|
260 | .textarea.editor { | |
261 | float: left; |
|
261 | float: left; | |
262 | position: relative; |
|
262 | position: relative; | |
263 | max-width: @texteditor-width; |
|
263 | max-width: @texteditor-width; | |
264 |
|
264 | |||
265 | select { |
|
265 | select { | |
266 | position: absolute; |
|
266 | position: absolute; | |
267 | top:10px; |
|
267 | top:10px; | |
268 | right:0; |
|
268 | right:0; | |
269 | } |
|
269 | } | |
270 |
|
270 | |||
271 | .CodeMirror { |
|
271 | .CodeMirror { | |
272 | margin: 0; |
|
272 | margin: 0; | |
273 | } |
|
273 | } | |
274 |
|
274 | |||
275 | .help-block { |
|
275 | .help-block { | |
276 | margin: 0 0 @padding; |
|
276 | margin: 0 0 @padding; | |
277 | padding:.5em; |
|
277 | padding:.5em; | |
278 | background-color: @grey6; |
|
278 | background-color: @grey6; | |
279 | } |
|
279 | } | |
280 | } |
|
280 | } | |
281 |
|
281 | |||
282 | ul.auth_plugins { |
|
282 | ul.auth_plugins { | |
283 | margin: @padding 0 @padding @legend-width; |
|
283 | margin: @padding 0 @padding @legend-width; | |
284 | padding: 0; |
|
284 | padding: 0; | |
285 |
|
285 | |||
286 | li { |
|
286 | li { | |
287 | margin-bottom: @padding; |
|
287 | margin-bottom: @padding; | |
288 | line-height: 1em; |
|
288 | line-height: 1em; | |
289 | list-style-type: none; |
|
289 | list-style-type: none; | |
290 |
|
290 | |||
291 | .auth_buttons .btn { |
|
291 | .auth_buttons .btn { | |
292 | margin-right: @padding; |
|
292 | margin-right: @padding; | |
293 | } |
|
293 | } | |
294 |
|
294 | |||
295 | &:before { content: none; } |
|
295 | &:before { content: none; } | |
296 | } |
|
296 | } | |
297 | } |
|
297 | } | |
298 |
|
298 | |||
299 | // Pull Requests |
|
299 | // Pull Requests | |
300 |
|
300 | |||
301 | .pullrequestlist { |
|
301 | .pullrequestlist { | |
302 | max-width: @pullrequest-width; |
|
302 | max-width: @pullrequest-width; | |
303 | margin-bottom: @space; |
|
303 | margin-bottom: @space; | |
304 |
|
304 | |||
305 | // Tweaks for "My Account" / "Pull requests" |
|
305 | // Tweaks for "My Account" / "Pull requests" | |
306 | .prwrapper { |
|
306 | .prwrapper { | |
307 | clear: left; |
|
307 | clear: left; | |
308 |
|
308 | |||
309 | .pr { |
|
309 | .pr { | |
310 | margin: 0; |
|
310 | margin: 0; | |
311 | padding: 0; |
|
311 | padding: 0; | |
312 | border-bottom: none; |
|
312 | border-bottom: none; | |
313 | } |
|
313 | } | |
314 |
|
314 | |||
315 | // TODO: johbo: Replace with something that makes up an inline form or |
|
315 | // TODO: johbo: Replace with something that makes up an inline form or | |
316 | // similar. |
|
316 | // similar. | |
317 | .repolist_actions { |
|
317 | .repolist_actions { | |
318 | display: inline-block; |
|
318 | display: inline-block; | |
319 | } |
|
319 | } | |
320 | } |
|
320 | } | |
321 |
|
321 | |||
322 | } |
|
322 | } | |
323 |
|
323 | |||
324 | .pullrequests_section_head { |
|
324 | .pullrequests_section_head { | |
325 | display: block; |
|
325 | display: block; | |
326 | clear: both; |
|
326 | clear: both; | |
327 | margin: @padding 0; |
|
327 | margin: @padding 0; | |
328 | font-family: @text-bold; |
|
328 | font-family: @text-bold; | |
329 | } |
|
329 | } | |
330 |
|
330 | |||
331 | .pr-origininfo, .pr-targetinfo { |
|
331 | .pr-origininfo, .pr-targetinfo { | |
332 | position: relative; |
|
332 | position: relative; | |
333 |
|
333 | |||
334 | .tag { |
|
334 | .tag { | |
335 | display: inline-block; |
|
335 | display: inline-block; | |
336 | margin: 0 1em .5em 0; |
|
336 | margin: 0 1em .5em 0; | |
337 | } |
|
337 | } | |
338 |
|
338 | |||
339 | .clone-url { |
|
339 | .clone-url { | |
340 | display: inline-block; |
|
340 | display: inline-block; | |
341 | margin: 0 0 .5em 0; |
|
341 | margin: 0 0 .5em 0; | |
342 | padding: 0; |
|
342 | padding: 0; | |
343 | line-height: 1.2em; |
|
343 | line-height: 1.2em; | |
344 | } |
|
344 | } | |
345 | } |
|
345 | } | |
346 |
|
346 | |||
347 | .pr-pullinfo { |
|
347 | .pr-pullinfo { | |
348 | clear: both; |
|
348 | clear: both; | |
349 | margin: .5em 0; |
|
349 | margin: .5em 0; | |
350 | } |
|
350 | } | |
351 |
|
351 | |||
352 | #pr-title-input { |
|
352 | #pr-title-input { | |
353 | width: 72%; |
|
353 | width: 72%; | |
354 | font-size: 1em; |
|
354 | font-size: 1em; | |
355 | font-family: @text-bold; |
|
355 | font-family: @text-bold; | |
356 | margin: 0; |
|
356 | margin: 0; | |
357 | padding: 0 0 0 @padding/4; |
|
357 | padding: 0 0 0 @padding/4; | |
358 | line-height: 1.7em; |
|
358 | line-height: 1.7em; | |
359 | color: @text-color; |
|
359 | color: @text-color; | |
360 | letter-spacing: .02em; |
|
360 | letter-spacing: .02em; | |
361 | } |
|
361 | } | |
362 |
|
362 | |||
363 | #pullrequest_title { |
|
363 | #pullrequest_title { | |
364 | width: 100%; |
|
364 | width: 100%; | |
365 | box-sizing: border-box; |
|
365 | box-sizing: border-box; | |
366 | } |
|
366 | } | |
367 |
|
367 | |||
368 | #pr_open_message { |
|
368 | #pr_open_message { | |
369 | border: @border-thickness solid #fff; |
|
369 | border: @border-thickness solid #fff; | |
370 | border-radius: @border-radius; |
|
370 | border-radius: @border-radius; | |
371 | padding: @padding-large-vertical @padding-large-vertical @padding-large-vertical 0; |
|
371 | padding: @padding-large-vertical @padding-large-vertical @padding-large-vertical 0; | |
372 | text-align: right; |
|
372 | text-align: right; | |
373 | overflow: hidden; |
|
373 | overflow: hidden; | |
374 | } |
|
374 | } | |
375 |
|
375 | |||
376 | .pr-submit-button { |
|
376 | .pr-submit-button { | |
377 | float: right; |
|
377 | float: right; | |
378 | margin: 0 0 0 5px; |
|
378 | margin: 0 0 0 5px; | |
379 | } |
|
379 | } | |
380 |
|
380 | |||
381 | .pr-spacing-container { |
|
381 | .pr-spacing-container { | |
382 | padding: 20px; |
|
382 | padding: 20px; | |
383 | clear: both |
|
383 | clear: both | |
384 | } |
|
384 | } | |
385 |
|
385 | |||
386 | #pr-description-input { |
|
386 | #pr-description-input { | |
387 | margin-bottom: 0; |
|
387 | margin-bottom: 0; | |
388 | } |
|
388 | } | |
389 |
|
389 | |||
390 | .pr-description-label { |
|
390 | .pr-description-label { | |
391 | vertical-align: top; |
|
391 | vertical-align: top; | |
392 | } |
|
392 | } | |
393 |
|
393 | |||
394 | .perms_section_head { |
|
394 | .perms_section_head { | |
395 | min-width: 625px; |
|
395 | min-width: 625px; | |
396 |
|
396 | |||
397 | h2 { |
|
397 | h2 { | |
398 | margin-bottom: 0; |
|
398 | margin-bottom: 0; | |
399 | } |
|
399 | } | |
400 |
|
400 | |||
401 | .label-checkbox { |
|
401 | .label-checkbox { | |
402 | float: left; |
|
402 | float: left; | |
403 | } |
|
403 | } | |
404 |
|
404 | |||
405 | &.field { |
|
405 | &.field { | |
406 | margin: @space 0 @padding; |
|
406 | margin: @space 0 @padding; | |
407 | } |
|
407 | } | |
408 |
|
408 | |||
409 | &:first-child.field { |
|
409 | &:first-child.field { | |
410 | margin-top: 0; |
|
410 | margin-top: 0; | |
411 |
|
411 | |||
412 | .label { |
|
412 | .label { | |
413 | margin-top: 0; |
|
413 | margin-top: 0; | |
414 | padding-top: 0; |
|
414 | padding-top: 0; | |
415 | } |
|
415 | } | |
416 |
|
416 | |||
417 | .radios { |
|
417 | .radios { | |
418 | padding-top: 0; |
|
418 | padding-top: 0; | |
419 | } |
|
419 | } | |
420 | } |
|
420 | } | |
421 |
|
421 | |||
422 | .radios { |
|
422 | .radios { | |
423 | float: right; |
|
423 | float: right; | |
424 | position: relative; |
|
424 | position: relative; | |
425 | width: 405px; |
|
425 | width: 405px; | |
426 | } |
|
426 | } | |
427 | } |
|
427 | } | |
428 |
|
428 | |||
429 | //--- MODULES ------------------// |
|
429 | //--- MODULES ------------------// | |
430 |
|
430 | |||
431 |
|
431 | |||
432 | // Fixed Sidebar Column |
|
432 | // Fixed Sidebar Column | |
433 | .sidebar-col-wrapper { |
|
433 | .sidebar-col-wrapper { | |
434 | padding-left: @sidebar-all-width; |
|
434 | padding-left: @sidebar-all-width; | |
435 |
|
435 | |||
436 | .sidebar { |
|
436 | .sidebar { | |
437 | width: @sidebar-width; |
|
437 | width: @sidebar-width; | |
438 | margin-left: -@sidebar-all-width; |
|
438 | margin-left: -@sidebar-all-width; | |
439 | } |
|
439 | } | |
440 | } |
|
440 | } | |
441 |
|
441 | |||
442 | .sidebar-col-wrapper.scw-small { |
|
442 | .sidebar-col-wrapper.scw-small { | |
443 | padding-left: @sidebar-small-all-width; |
|
443 | padding-left: @sidebar-small-all-width; | |
444 |
|
444 | |||
445 | .sidebar { |
|
445 | .sidebar { | |
446 | width: @sidebar-small-width; |
|
446 | width: @sidebar-small-width; | |
447 | margin-left: -@sidebar-small-all-width; |
|
447 | margin-left: -@sidebar-small-all-width; | |
448 | } |
|
448 | } | |
449 | } |
|
449 | } | |
450 |
|
450 | |||
451 |
|
451 | |||
452 | // FOOTER |
|
452 | // FOOTER | |
453 | #footer { |
|
453 | #footer { | |
454 | padding: 0; |
|
454 | padding: 0; | |
455 | text-align: center; |
|
455 | text-align: center; | |
456 | vertical-align: middle; |
|
456 | vertical-align: middle; | |
457 | color: @grey2; |
|
457 | color: @grey2; | |
458 | background-color: @grey6; |
|
458 | background-color: @grey6; | |
459 |
|
459 | |||
460 | p { |
|
460 | p { | |
461 | margin: 0; |
|
461 | margin: 0; | |
462 | padding: 1em; |
|
462 | padding: 1em; | |
463 | line-height: 1em; |
|
463 | line-height: 1em; | |
464 | } |
|
464 | } | |
465 |
|
465 | |||
466 | .server-instance { //server instance |
|
466 | .server-instance { //server instance | |
467 | display: none; |
|
467 | display: none; | |
468 | } |
|
468 | } | |
469 |
|
469 | |||
470 | .title { |
|
470 | .title { | |
471 | float: none; |
|
471 | float: none; | |
472 | margin: 0 auto; |
|
472 | margin: 0 auto; | |
473 | } |
|
473 | } | |
474 | } |
|
474 | } | |
475 |
|
475 | |||
476 | button.close { |
|
476 | button.close { | |
477 | padding: 0; |
|
477 | padding: 0; | |
478 | cursor: pointer; |
|
478 | cursor: pointer; | |
479 | background: transparent; |
|
479 | background: transparent; | |
480 | border: 0; |
|
480 | border: 0; | |
481 | .box-shadow(none); |
|
481 | .box-shadow(none); | |
482 | -webkit-appearance: none; |
|
482 | -webkit-appearance: none; | |
483 | } |
|
483 | } | |
484 |
|
484 | |||
485 | .close { |
|
485 | .close { | |
486 | float: right; |
|
486 | float: right; | |
487 | font-size: 21px; |
|
487 | font-size: 21px; | |
488 | font-family: @text-bootstrap; |
|
488 | font-family: @text-bootstrap; | |
489 | line-height: 1em; |
|
489 | line-height: 1em; | |
490 | font-weight: bold; |
|
490 | font-weight: bold; | |
491 | color: @grey2; |
|
491 | color: @grey2; | |
492 |
|
492 | |||
493 | &:hover, |
|
493 | &:hover, | |
494 | &:focus { |
|
494 | &:focus { | |
495 | color: @grey1; |
|
495 | color: @grey1; | |
496 | text-decoration: none; |
|
496 | text-decoration: none; | |
497 | cursor: pointer; |
|
497 | cursor: pointer; | |
498 | } |
|
498 | } | |
499 | } |
|
499 | } | |
500 |
|
500 | |||
501 | // GRID |
|
501 | // GRID | |
502 | .sorting, |
|
502 | .sorting, | |
503 | .sorting_desc, |
|
503 | .sorting_desc, | |
504 | .sorting_asc { |
|
504 | .sorting_asc { | |
505 | cursor: pointer; |
|
505 | cursor: pointer; | |
506 | } |
|
506 | } | |
507 | .sorting_desc:after { |
|
507 | .sorting_desc:after { | |
508 | content: "\00A0\25B2"; |
|
508 | content: "\00A0\25B2"; | |
509 | font-size: .75em; |
|
509 | font-size: .75em; | |
510 | } |
|
510 | } | |
511 | .sorting_asc:after { |
|
511 | .sorting_asc:after { | |
512 | content: "\00A0\25BC"; |
|
512 | content: "\00A0\25BC"; | |
513 | font-size: .68em; |
|
513 | font-size: .68em; | |
514 | } |
|
514 | } | |
515 |
|
515 | |||
516 |
|
516 | |||
517 | .user_auth_tokens { |
|
517 | .user_auth_tokens { | |
518 |
|
518 | |||
519 | &.truncate { |
|
519 | &.truncate { | |
520 | white-space: nowrap; |
|
520 | white-space: nowrap; | |
521 | overflow: hidden; |
|
521 | overflow: hidden; | |
522 | text-overflow: ellipsis; |
|
522 | text-overflow: ellipsis; | |
523 | } |
|
523 | } | |
524 |
|
524 | |||
525 | .fields .field .input { |
|
525 | .fields .field .input { | |
526 | margin: 0; |
|
526 | margin: 0; | |
527 | } |
|
527 | } | |
528 |
|
528 | |||
529 | input#description { |
|
529 | input#description { | |
530 | width: 100px; |
|
530 | width: 100px; | |
531 | margin: 0; |
|
531 | margin: 0; | |
532 | } |
|
532 | } | |
533 |
|
533 | |||
534 | .drop-menu { |
|
534 | .drop-menu { | |
535 | // TODO: johbo: Remove this, should work out of the box when |
|
535 | // TODO: johbo: Remove this, should work out of the box when | |
536 | // having multiple inputs inline |
|
536 | // having multiple inputs inline | |
537 | margin: 0 0 0 5px; |
|
537 | margin: 0 0 0 5px; | |
538 | } |
|
538 | } | |
539 | } |
|
539 | } | |
540 | #user_list_table { |
|
540 | #user_list_table { | |
541 | .closed { |
|
541 | .closed { | |
542 | background-color: @grey6; |
|
542 | background-color: @grey6; | |
543 | } |
|
543 | } | |
544 | } |
|
544 | } | |
545 |
|
545 | |||
546 |
|
546 | |||
547 | input { |
|
547 | input { | |
548 | &.disabled { |
|
548 | &.disabled { | |
549 | opacity: .5; |
|
549 | opacity: .5; | |
550 | } |
|
550 | } | |
551 | } |
|
551 | } | |
552 |
|
552 | |||
553 | // remove extra padding in firefox |
|
553 | // remove extra padding in firefox | |
554 | input::-moz-focus-inner { border:0; padding:0 } |
|
554 | input::-moz-focus-inner { border:0; padding:0 } | |
555 |
|
555 | |||
556 | .adjacent input { |
|
556 | .adjacent input { | |
557 | margin-bottom: @padding; |
|
557 | margin-bottom: @padding; | |
558 | } |
|
558 | } | |
559 |
|
559 | |||
560 | .permissions_boxes { |
|
560 | .permissions_boxes { | |
561 | display: block; |
|
561 | display: block; | |
562 | } |
|
562 | } | |
563 |
|
563 | |||
564 | //TODO: lisa: this should be in tables |
|
564 | //TODO: lisa: this should be in tables | |
565 | .show_more_col { |
|
565 | .show_more_col { | |
566 | width: 20px; |
|
566 | width: 20px; | |
567 | } |
|
567 | } | |
568 |
|
568 | |||
569 | //FORMS |
|
569 | //FORMS | |
570 |
|
570 | |||
571 | .medium-inline, |
|
571 | .medium-inline, | |
572 | input#description.medium-inline { |
|
572 | input#description.medium-inline { | |
573 | display: inline; |
|
573 | display: inline; | |
574 | width: @medium-inline-input-width; |
|
574 | width: @medium-inline-input-width; | |
575 | min-width: 100px; |
|
575 | min-width: 100px; | |
576 | } |
|
576 | } | |
577 |
|
577 | |||
578 | select { |
|
578 | select { | |
579 | //reset |
|
579 | //reset | |
580 | -webkit-appearance: none; |
|
580 | -webkit-appearance: none; | |
581 | -moz-appearance: none; |
|
581 | -moz-appearance: none; | |
582 |
|
582 | |||
583 | display: inline-block; |
|
583 | display: inline-block; | |
584 | height: 28px; |
|
584 | height: 28px; | |
585 | width: auto; |
|
585 | width: auto; | |
586 | margin: 0 @padding @padding 0; |
|
586 | margin: 0 @padding @padding 0; | |
587 | padding: 0 18px 0 8px; |
|
587 | padding: 0 18px 0 8px; | |
588 | line-height:1em; |
|
588 | line-height:1em; | |
589 | font-size: @basefontsize; |
|
589 | font-size: @basefontsize; | |
590 | border: @border-thickness solid @rcblue; |
|
590 | border: @border-thickness solid @rcblue; | |
591 | background:white url("../images/dt-arrow-dn.png") no-repeat 100% 50%; |
|
591 | background:white url("../images/dt-arrow-dn.png") no-repeat 100% 50%; | |
592 | color: @rcblue; |
|
592 | color: @rcblue; | |
593 |
|
593 | |||
594 | &:after { |
|
594 | &:after { | |
595 | content: "\00A0\25BE"; |
|
595 | content: "\00A0\25BE"; | |
596 | } |
|
596 | } | |
597 |
|
597 | |||
598 | &:focus { |
|
598 | &:focus { | |
599 | outline: none; |
|
599 | outline: none; | |
600 | } |
|
600 | } | |
601 | } |
|
601 | } | |
602 |
|
602 | |||
603 | option { |
|
603 | option { | |
604 | &:focus { |
|
604 | &:focus { | |
605 | outline: none; |
|
605 | outline: none; | |
606 | } |
|
606 | } | |
607 | } |
|
607 | } | |
608 |
|
608 | |||
609 | input, |
|
609 | input, | |
610 | textarea { |
|
610 | textarea { | |
611 | padding: @input-padding; |
|
611 | padding: @input-padding; | |
612 | border: @input-border-thickness solid @border-highlight-color; |
|
612 | border: @input-border-thickness solid @border-highlight-color; | |
613 | .border-radius (@border-radius); |
|
613 | .border-radius (@border-radius); | |
614 | font-family: @text-light; |
|
614 | font-family: @text-light; | |
615 | font-size: @basefontsize; |
|
615 | font-size: @basefontsize; | |
616 |
|
616 | |||
617 | &.input-sm { |
|
617 | &.input-sm { | |
618 | padding: 5px; |
|
618 | padding: 5px; | |
619 | } |
|
619 | } | |
620 |
|
620 | |||
621 | &#description { |
|
621 | &#description { | |
622 | min-width: @input-description-minwidth; |
|
622 | min-width: @input-description-minwidth; | |
623 | min-height: 1em; |
|
623 | min-height: 1em; | |
624 | padding: 10px; |
|
624 | padding: 10px; | |
625 | } |
|
625 | } | |
626 | } |
|
626 | } | |
627 |
|
627 | |||
628 | .field-sm { |
|
628 | .field-sm { | |
629 | input, |
|
629 | input, | |
630 | textarea { |
|
630 | textarea { | |
631 | padding: 5px; |
|
631 | padding: 5px; | |
632 | } |
|
632 | } | |
633 | } |
|
633 | } | |
634 |
|
634 | |||
635 | textarea { |
|
635 | textarea { | |
636 | display: block; |
|
636 | display: block; | |
637 | clear: both; |
|
637 | clear: both; | |
638 | width: 100%; |
|
638 | width: 100%; | |
639 | min-height: 100px; |
|
639 | min-height: 100px; | |
640 | margin-bottom: @padding; |
|
640 | margin-bottom: @padding; | |
641 | .box-sizing(border-box); |
|
641 | .box-sizing(border-box); | |
642 | overflow: auto; |
|
642 | overflow: auto; | |
643 | } |
|
643 | } | |
644 |
|
644 | |||
645 | label { |
|
645 | label { | |
646 | font-family: @text-light; |
|
646 | font-family: @text-light; | |
647 | } |
|
647 | } | |
648 |
|
648 | |||
649 | // GRAVATARS |
|
649 | // GRAVATARS | |
650 | // centers gravatar on username to the right |
|
650 | // centers gravatar on username to the right | |
651 |
|
651 | |||
652 | .gravatar { |
|
652 | .gravatar { | |
653 | display: inline; |
|
653 | display: inline; | |
654 | min-width: 16px; |
|
654 | min-width: 16px; | |
655 | min-height: 16px; |
|
655 | min-height: 16px; | |
656 | margin: -5px 0; |
|
656 | margin: -5px 0; | |
657 | padding: 0; |
|
657 | padding: 0; | |
658 | line-height: 1em; |
|
658 | line-height: 1em; | |
659 | border: 1px solid @grey4; |
|
659 | border: 1px solid @grey4; | |
660 |
|
660 | |||
661 | &.gravatar-large { |
|
661 | &.gravatar-large { | |
662 | margin: -0.5em .25em -0.5em 0; |
|
662 | margin: -0.5em .25em -0.5em 0; | |
663 | } |
|
663 | } | |
664 |
|
664 | |||
665 | & + .user { |
|
665 | & + .user { | |
666 | display: inline; |
|
666 | display: inline; | |
667 | margin: 0; |
|
667 | margin: 0; | |
668 | padding: 0 0 0 .17em; |
|
668 | padding: 0 0 0 .17em; | |
669 | line-height: 1em; |
|
669 | line-height: 1em; | |
670 | } |
|
670 | } | |
671 | } |
|
671 | } | |
672 |
|
672 | |||
673 | .rc-user { // gravatar + user wrapper |
|
673 | .rc-user { // gravatar + user wrapper | |
|
674 | float: left; | |||
674 |
|
|
675 | position: relative; | |
675 | min-width: 100px; |
|
676 | min-width: 100px; | |
676 | max-width: 200px; |
|
677 | max-width: 200px; | |
677 | min-height: (@gravatar-size + @border-thickness * 2); // account for border |
|
678 | min-height: (@gravatar-size + @border-thickness * 2); // account for border | |
678 | display: block; |
|
679 | display: block; | |
679 | padding: 0 0 0 (@gravatar-size + @basefontsize/2 + @border-thickness * 2); |
|
680 | padding: 0 0 0 (@gravatar-size + @basefontsize/2 + @border-thickness * 2); | |
680 |
|
681 | |||
681 |
|
682 | |||
682 | .gravatar { |
|
683 | .gravatar { | |
683 | display: block; |
|
684 | display: block; | |
684 | position: absolute; |
|
685 | position: absolute; | |
685 | top: 0; |
|
686 | top: 0; | |
686 | left: 0; |
|
687 | left: 0; | |
687 | min-width: @gravatar-size; |
|
688 | min-width: @gravatar-size; | |
688 | min-height: @gravatar-size; |
|
689 | min-height: @gravatar-size; | |
689 | margin: 0; |
|
690 | margin: 0; | |
690 | } |
|
691 | } | |
691 |
|
692 | |||
692 | .user { |
|
693 | .user { | |
693 | display: block; |
|
694 | display: block; | |
694 | max-width: 175px; |
|
695 | max-width: 175px; | |
695 | padding-top: 2px; |
|
696 | padding-top: 2px; | |
696 | overflow: hidden; |
|
697 | overflow: hidden; | |
697 | text-overflow: ellipsis; |
|
698 | text-overflow: ellipsis; | |
698 | } |
|
699 | } | |
699 | } |
|
700 | } | |
700 |
|
701 | |||
701 | .gist-gravatar, |
|
702 | .gist-gravatar, | |
702 | .journal_container { |
|
703 | .journal_container { | |
703 | .gravatar-large { |
|
704 | .gravatar-large { | |
704 | margin: 0 .5em -10px 0; |
|
705 | margin: 0 .5em -10px 0; | |
705 | } |
|
706 | } | |
706 | } |
|
707 | } | |
707 |
|
708 | |||
708 |
|
709 | |||
709 | // ADMIN SETTINGS |
|
710 | // ADMIN SETTINGS | |
710 |
|
711 | |||
711 | // Tag Patterns |
|
712 | // Tag Patterns | |
712 | .tag_patterns { |
|
713 | .tag_patterns { | |
713 | .tag_input { |
|
714 | .tag_input { | |
714 | margin-bottom: @padding; |
|
715 | margin-bottom: @padding; | |
715 | } |
|
716 | } | |
716 | } |
|
717 | } | |
717 |
|
718 | |||
718 | .locked_input { |
|
719 | .locked_input { | |
719 | position: relative; |
|
720 | position: relative; | |
720 |
|
721 | |||
721 | input { |
|
722 | input { | |
722 | display: inline; |
|
723 | display: inline; | |
723 | margin-top: 3px; |
|
724 | margin-top: 3px; | |
724 | } |
|
725 | } | |
725 |
|
726 | |||
726 | br { |
|
727 | br { | |
727 | display: none; |
|
728 | display: none; | |
728 | } |
|
729 | } | |
729 |
|
730 | |||
730 | .error-message { |
|
731 | .error-message { | |
731 | float: left; |
|
732 | float: left; | |
732 | width: 100%; |
|
733 | width: 100%; | |
733 | } |
|
734 | } | |
734 |
|
735 | |||
735 | .lock_input_button { |
|
736 | .lock_input_button { | |
736 | display: inline; |
|
737 | display: inline; | |
737 | } |
|
738 | } | |
738 |
|
739 | |||
739 | .help-block { |
|
740 | .help-block { | |
740 | clear: both; |
|
741 | clear: both; | |
741 | } |
|
742 | } | |
742 | } |
|
743 | } | |
743 |
|
744 | |||
744 | // Notifications |
|
745 | // Notifications | |
745 |
|
746 | |||
746 | .notifications_buttons { |
|
747 | .notifications_buttons { | |
747 | margin: 0 0 @space 0; |
|
748 | margin: 0 0 @space 0; | |
748 | padding: 0; |
|
749 | padding: 0; | |
749 |
|
750 | |||
750 | .btn { |
|
751 | .btn { | |
751 | display: inline-block; |
|
752 | display: inline-block; | |
752 | } |
|
753 | } | |
753 | } |
|
754 | } | |
754 |
|
755 | |||
755 | .notification-list { |
|
756 | .notification-list { | |
756 |
|
757 | |||
757 | div { |
|
758 | div { | |
758 | display: inline-block; |
|
759 | display: inline-block; | |
759 | vertical-align: middle; |
|
760 | vertical-align: middle; | |
760 | } |
|
761 | } | |
761 |
|
762 | |||
762 | .container { |
|
763 | .container { | |
763 | display: block; |
|
764 | display: block; | |
764 | margin: 0 0 @padding 0; |
|
765 | margin: 0 0 @padding 0; | |
765 | } |
|
766 | } | |
766 |
|
767 | |||
767 | .delete-notifications { |
|
768 | .delete-notifications { | |
768 | margin-left: @padding; |
|
769 | margin-left: @padding; | |
769 | text-align: right; |
|
770 | text-align: right; | |
770 | cursor: pointer; |
|
771 | cursor: pointer; | |
771 | } |
|
772 | } | |
772 |
|
773 | |||
773 | .read-notifications { |
|
774 | .read-notifications { | |
774 | margin-left: @padding/2; |
|
775 | margin-left: @padding/2; | |
775 | text-align: right; |
|
776 | text-align: right; | |
776 | width: 35px; |
|
777 | width: 35px; | |
777 | cursor: pointer; |
|
778 | cursor: pointer; | |
778 | } |
|
779 | } | |
779 |
|
780 | |||
780 | .icon-minus-sign { |
|
781 | .icon-minus-sign { | |
781 | color: @alert2; |
|
782 | color: @alert2; | |
782 | } |
|
783 | } | |
783 |
|
784 | |||
784 | .icon-ok-sign { |
|
785 | .icon-ok-sign { | |
785 | color: @alert1; |
|
786 | color: @alert1; | |
786 | } |
|
787 | } | |
787 | } |
|
788 | } | |
788 |
|
789 | |||
789 | .user_settings { |
|
790 | .user_settings { | |
790 | float: left; |
|
791 | float: left; | |
791 | clear: both; |
|
792 | clear: both; | |
792 | display: block; |
|
793 | display: block; | |
793 | width: 100%; |
|
794 | width: 100%; | |
794 |
|
795 | |||
795 | .gravatar_box { |
|
796 | .gravatar_box { | |
796 | margin-bottom: @padding; |
|
797 | margin-bottom: @padding; | |
797 |
|
798 | |||
798 | &:after { |
|
799 | &:after { | |
799 | content: " "; |
|
800 | content: " "; | |
800 | clear: both; |
|
801 | clear: both; | |
801 | width: 100%; |
|
802 | width: 100%; | |
802 | } |
|
803 | } | |
803 | } |
|
804 | } | |
804 |
|
805 | |||
805 | .fields .field { |
|
806 | .fields .field { | |
806 | clear: both; |
|
807 | clear: both; | |
807 | } |
|
808 | } | |
808 | } |
|
809 | } | |
809 |
|
810 | |||
810 | .advanced_settings { |
|
811 | .advanced_settings { | |
811 | margin-bottom: @space; |
|
812 | margin-bottom: @space; | |
812 |
|
813 | |||
813 | .help-block { |
|
814 | .help-block { | |
814 | margin-left: 0; |
|
815 | margin-left: 0; | |
815 | } |
|
816 | } | |
816 |
|
817 | |||
817 | button + .help-block { |
|
818 | button + .help-block { | |
818 | margin-top: @padding; |
|
819 | margin-top: @padding; | |
819 | } |
|
820 | } | |
820 | } |
|
821 | } | |
821 |
|
822 | |||
822 | // admin settings radio buttons and labels |
|
823 | // admin settings radio buttons and labels | |
823 | .label-2 { |
|
824 | .label-2 { | |
824 | float: left; |
|
825 | float: left; | |
825 | width: @label2-width; |
|
826 | width: @label2-width; | |
826 |
|
827 | |||
827 | label { |
|
828 | label { | |
828 | color: @grey1; |
|
829 | color: @grey1; | |
829 | } |
|
830 | } | |
830 | } |
|
831 | } | |
831 | .checkboxes { |
|
832 | .checkboxes { | |
832 | float: left; |
|
833 | float: left; | |
833 | width: @checkboxes-width; |
|
834 | width: @checkboxes-width; | |
834 | margin-bottom: @padding; |
|
835 | margin-bottom: @padding; | |
835 |
|
836 | |||
836 | .checkbox { |
|
837 | .checkbox { | |
837 | width: 100%; |
|
838 | width: 100%; | |
838 |
|
839 | |||
839 | label { |
|
840 | label { | |
840 | margin: 0; |
|
841 | margin: 0; | |
841 | padding: 0; |
|
842 | padding: 0; | |
842 | } |
|
843 | } | |
843 | } |
|
844 | } | |
844 |
|
845 | |||
845 | .checkbox + .checkbox { |
|
846 | .checkbox + .checkbox { | |
846 | display: inline-block; |
|
847 | display: inline-block; | |
847 | } |
|
848 | } | |
848 |
|
849 | |||
849 | label { |
|
850 | label { | |
850 | margin-right: 1em; |
|
851 | margin-right: 1em; | |
851 | } |
|
852 | } | |
852 | } |
|
853 | } | |
853 |
|
854 | |||
854 | // CHANGELOG |
|
855 | // CHANGELOG | |
855 | .container_header { |
|
856 | .container_header { | |
856 | float: left; |
|
857 | float: left; | |
857 | display: block; |
|
858 | display: block; | |
858 | width: 100%; |
|
859 | width: 100%; | |
859 | margin: @padding 0 @padding; |
|
860 | margin: @padding 0 @padding; | |
860 |
|
861 | |||
861 | #filter_changelog { |
|
862 | #filter_changelog { | |
862 | float: left; |
|
863 | float: left; | |
863 | margin-right: @padding; |
|
864 | margin-right: @padding; | |
864 | } |
|
865 | } | |
865 |
|
866 | |||
866 | .breadcrumbs_light { |
|
867 | .breadcrumbs_light { | |
867 | display: inline-block; |
|
868 | display: inline-block; | |
868 | } |
|
869 | } | |
869 | } |
|
870 | } | |
870 |
|
871 | |||
871 | .info_box { |
|
872 | .info_box { | |
872 | float: right; |
|
873 | float: right; | |
873 | } |
|
874 | } | |
874 |
|
875 | |||
875 |
|
876 | |||
876 | #graph_nodes { |
|
877 | #graph_nodes { | |
877 | padding-top: 43px; |
|
878 | padding-top: 43px; | |
878 | } |
|
879 | } | |
879 |
|
880 | |||
880 | #graph_content{ |
|
881 | #graph_content{ | |
881 |
|
882 | |||
882 | // adjust for table headers so that graph renders properly |
|
883 | // adjust for table headers so that graph renders properly | |
883 | // #graph_nodes padding - table cell padding |
|
884 | // #graph_nodes padding - table cell padding | |
884 | padding-top: (@space - (@basefontsize * 2.4)); |
|
885 | padding-top: (@space - (@basefontsize * 2.4)); | |
885 |
|
886 | |||
886 | &.graph_full_width { |
|
887 | &.graph_full_width { | |
887 | width: 100%; |
|
888 | width: 100%; | |
888 | max-width: 100%; |
|
889 | max-width: 100%; | |
889 | } |
|
890 | } | |
890 | } |
|
891 | } | |
891 |
|
892 | |||
892 | #graph { |
|
893 | #graph { | |
893 | .flag_status { |
|
894 | .flag_status { | |
894 | margin: 0; |
|
895 | margin: 0; | |
895 | } |
|
896 | } | |
896 |
|
897 | |||
897 | .pagination-left { |
|
898 | .pagination-left { | |
898 | float: left; |
|
899 | float: left; | |
899 | clear: both; |
|
900 | clear: both; | |
900 | } |
|
901 | } | |
901 |
|
902 | |||
902 | .log-container { |
|
903 | .log-container { | |
903 | max-width: 345px; |
|
904 | max-width: 345px; | |
904 |
|
905 | |||
905 | .message{ |
|
906 | .message{ | |
906 | max-width: 340px; |
|
907 | max-width: 340px; | |
907 | } |
|
908 | } | |
908 | } |
|
909 | } | |
909 |
|
910 | |||
910 | .graph-col-wrapper { |
|
911 | .graph-col-wrapper { | |
911 | padding-left: 110px; |
|
912 | padding-left: 110px; | |
912 |
|
913 | |||
913 | #graph_nodes { |
|
914 | #graph_nodes { | |
914 | width: 100px; |
|
915 | width: 100px; | |
915 | margin-left: -110px; |
|
916 | margin-left: -110px; | |
916 | float: left; |
|
917 | float: left; | |
917 | clear: left; |
|
918 | clear: left; | |
918 | } |
|
919 | } | |
919 | } |
|
920 | } | |
920 | } |
|
921 | } | |
921 |
|
922 | |||
922 | #filter_changelog { |
|
923 | #filter_changelog { | |
923 | float: left; |
|
924 | float: left; | |
924 | } |
|
925 | } | |
925 |
|
926 | |||
926 |
|
927 | |||
927 | //--- THEME ------------------// |
|
928 | //--- THEME ------------------// | |
928 |
|
929 | |||
929 | #logo { |
|
930 | #logo { | |
930 | float: left; |
|
931 | float: left; | |
931 | margin: 9px 0 0 0; |
|
932 | margin: 9px 0 0 0; | |
932 |
|
933 | |||
933 | .header { |
|
934 | .header { | |
934 | background-color: transparent; |
|
935 | background-color: transparent; | |
935 | } |
|
936 | } | |
936 |
|
937 | |||
937 | a { |
|
938 | a { | |
938 | display: inline-block; |
|
939 | display: inline-block; | |
939 | } |
|
940 | } | |
940 |
|
941 | |||
941 | img { |
|
942 | img { | |
942 | height:30px; |
|
943 | height:30px; | |
943 | } |
|
944 | } | |
944 | } |
|
945 | } | |
945 |
|
946 | |||
946 | .logo-wrapper { |
|
947 | .logo-wrapper { | |
947 | float:left; |
|
948 | float:left; | |
948 | } |
|
949 | } | |
949 |
|
950 | |||
950 | .branding{ |
|
951 | .branding{ | |
951 | float: left; |
|
952 | float: left; | |
952 | padding: 9px 2px; |
|
953 | padding: 9px 2px; | |
953 | line-height: 1em; |
|
954 | line-height: 1em; | |
954 | font-size: @navigation-fontsize; |
|
955 | font-size: @navigation-fontsize; | |
955 | } |
|
956 | } | |
956 |
|
957 | |||
957 | img { |
|
958 | img { | |
958 | border: none; |
|
959 | border: none; | |
959 | outline: none; |
|
960 | outline: none; | |
960 | } |
|
961 | } | |
961 | user-profile-header |
|
962 | user-profile-header | |
962 | label { |
|
963 | label { | |
963 |
|
964 | |||
964 | input[type="checkbox"] { |
|
965 | input[type="checkbox"] { | |
965 | margin-right: 1em; |
|
966 | margin-right: 1em; | |
966 | } |
|
967 | } | |
967 | input[type="radio"] { |
|
968 | input[type="radio"] { | |
968 | margin-right: 1em; |
|
969 | margin-right: 1em; | |
969 | } |
|
970 | } | |
970 | } |
|
971 | } | |
971 |
|
972 | |||
972 | .flag_status { |
|
973 | .flag_status { | |
973 | margin: 2px 8px 6px 2px; |
|
974 | margin: 2px 8px 6px 2px; | |
974 | &.under_review { |
|
975 | &.under_review { | |
975 | .circle(5px, @alert3); |
|
976 | .circle(5px, @alert3); | |
976 | } |
|
977 | } | |
977 | &.approved { |
|
978 | &.approved { | |
978 | .circle(5px, @alert1); |
|
979 | .circle(5px, @alert1); | |
979 | } |
|
980 | } | |
980 | &.rejected, |
|
981 | &.rejected, | |
981 | &.forced_closed{ |
|
982 | &.forced_closed{ | |
982 | .circle(5px, @alert2); |
|
983 | .circle(5px, @alert2); | |
983 | } |
|
984 | } | |
984 | &.not_reviewed { |
|
985 | &.not_reviewed { | |
985 | .circle(5px, @grey5); |
|
986 | .circle(5px, @grey5); | |
986 | } |
|
987 | } | |
987 | } |
|
988 | } | |
988 |
|
989 | |||
989 | .flag_status_comment_box { |
|
990 | .flag_status_comment_box { | |
990 | margin: 5px 6px 0px 2px; |
|
991 | margin: 5px 6px 0px 2px; | |
991 | } |
|
992 | } | |
992 | .test_pattern_preview { |
|
993 | .test_pattern_preview { | |
993 | margin: @space 0; |
|
994 | margin: @space 0; | |
994 |
|
995 | |||
995 | p { |
|
996 | p { | |
996 | margin-bottom: 0; |
|
997 | margin-bottom: 0; | |
997 | border-bottom: @border-thickness solid @border-default-color; |
|
998 | border-bottom: @border-thickness solid @border-default-color; | |
998 | color: @grey3; |
|
999 | color: @grey3; | |
999 | } |
|
1000 | } | |
1000 |
|
1001 | |||
1001 | .btn { |
|
1002 | .btn { | |
1002 | margin-bottom: @padding; |
|
1003 | margin-bottom: @padding; | |
1003 | } |
|
1004 | } | |
1004 | } |
|
1005 | } | |
1005 | #test_pattern_result { |
|
1006 | #test_pattern_result { | |
1006 | display: none; |
|
1007 | display: none; | |
1007 | &:extend(pre); |
|
1008 | &:extend(pre); | |
1008 | padding: .9em; |
|
1009 | padding: .9em; | |
1009 | color: @grey3; |
|
1010 | color: @grey3; | |
1010 | background-color: @grey7; |
|
1011 | background-color: @grey7; | |
1011 | border-right: @border-thickness solid @border-default-color; |
|
1012 | border-right: @border-thickness solid @border-default-color; | |
1012 | border-bottom: @border-thickness solid @border-default-color; |
|
1013 | border-bottom: @border-thickness solid @border-default-color; | |
1013 | border-left: @border-thickness solid @border-default-color; |
|
1014 | border-left: @border-thickness solid @border-default-color; | |
1014 | } |
|
1015 | } | |
1015 |
|
1016 | |||
1016 | #repo_vcs_settings { |
|
1017 | #repo_vcs_settings { | |
1017 | #inherit_overlay_vcs_default { |
|
1018 | #inherit_overlay_vcs_default { | |
1018 | display: none; |
|
1019 | display: none; | |
1019 | } |
|
1020 | } | |
1020 | #inherit_overlay_vcs_custom { |
|
1021 | #inherit_overlay_vcs_custom { | |
1021 | display: custom; |
|
1022 | display: custom; | |
1022 | } |
|
1023 | } | |
1023 | &.inherited { |
|
1024 | &.inherited { | |
1024 | #inherit_overlay_vcs_default { |
|
1025 | #inherit_overlay_vcs_default { | |
1025 | display: block; |
|
1026 | display: block; | |
1026 | } |
|
1027 | } | |
1027 | #inherit_overlay_vcs_custom { |
|
1028 | #inherit_overlay_vcs_custom { | |
1028 | display: none; |
|
1029 | display: none; | |
1029 | } |
|
1030 | } | |
1030 | } |
|
1031 | } | |
1031 | } |
|
1032 | } | |
1032 |
|
1033 | |||
1033 | .issue-tracker-link { |
|
1034 | .issue-tracker-link { | |
1034 | color: @rcblue; |
|
1035 | color: @rcblue; | |
1035 | } |
|
1036 | } | |
1036 |
|
1037 | |||
1037 | // Issue Tracker Table Show/Hide |
|
1038 | // Issue Tracker Table Show/Hide | |
1038 | #repo_issue_tracker { |
|
1039 | #repo_issue_tracker { | |
1039 | #inherit_overlay { |
|
1040 | #inherit_overlay { | |
1040 | display: none; |
|
1041 | display: none; | |
1041 | } |
|
1042 | } | |
1042 | #custom_overlay { |
|
1043 | #custom_overlay { | |
1043 | display: custom; |
|
1044 | display: custom; | |
1044 | } |
|
1045 | } | |
1045 | &.inherited { |
|
1046 | &.inherited { | |
1046 | #inherit_overlay { |
|
1047 | #inherit_overlay { | |
1047 | display: block; |
|
1048 | display: block; | |
1048 | } |
|
1049 | } | |
1049 | #custom_overlay { |
|
1050 | #custom_overlay { | |
1050 | display: none; |
|
1051 | display: none; | |
1051 | } |
|
1052 | } | |
1052 | } |
|
1053 | } | |
1053 | } |
|
1054 | } | |
1054 | table.issuetracker { |
|
1055 | table.issuetracker { | |
1055 | &.readonly { |
|
1056 | &.readonly { | |
1056 | tr, td { |
|
1057 | tr, td { | |
1057 | color: @grey3; |
|
1058 | color: @grey3; | |
1058 | } |
|
1059 | } | |
1059 | } |
|
1060 | } | |
1060 | .edit { |
|
1061 | .edit { | |
1061 | display: none; |
|
1062 | display: none; | |
1062 | } |
|
1063 | } | |
1063 | .editopen { |
|
1064 | .editopen { | |
1064 | .edit { |
|
1065 | .edit { | |
1065 | display: inline; |
|
1066 | display: inline; | |
1066 | } |
|
1067 | } | |
1067 | .entry { |
|
1068 | .entry { | |
1068 | display: none; |
|
1069 | display: none; | |
1069 | } |
|
1070 | } | |
1070 | } |
|
1071 | } | |
1071 | tr td.td-action { |
|
1072 | tr td.td-action { | |
1072 | min-width: 117px; |
|
1073 | min-width: 117px; | |
1073 | } |
|
1074 | } | |
1074 | td input { |
|
1075 | td input { | |
1075 | max-width: none; |
|
1076 | max-width: none; | |
1076 | min-width: 30px; |
|
1077 | min-width: 30px; | |
1077 | width: 80%; |
|
1078 | width: 80%; | |
1078 | } |
|
1079 | } | |
1079 | .issuetracker_pref input { |
|
1080 | .issuetracker_pref input { | |
1080 | width: 40%; |
|
1081 | width: 40%; | |
1081 | } |
|
1082 | } | |
1082 | input.edit_issuetracker_update { |
|
1083 | input.edit_issuetracker_update { | |
1083 | margin-right: 0; |
|
1084 | margin-right: 0; | |
1084 | width: auto; |
|
1085 | width: auto; | |
1085 | } |
|
1086 | } | |
1086 | } |
|
1087 | } | |
1087 |
|
1088 | |||
1088 | //Permissions Settings |
|
1089 | //Permissions Settings | |
1089 | #add_perm { |
|
1090 | #add_perm { | |
1090 | margin: 0 0 @padding; |
|
1091 | margin: 0 0 @padding; | |
1091 | cursor: pointer; |
|
1092 | cursor: pointer; | |
1092 | } |
|
1093 | } | |
1093 |
|
1094 | |||
1094 | .perm_ac { |
|
1095 | .perm_ac { | |
1095 | input { |
|
1096 | input { | |
1096 | width: 95%; |
|
1097 | width: 95%; | |
1097 | } |
|
1098 | } | |
1098 | } |
|
1099 | } | |
1099 |
|
1100 | |||
1100 | .autocomplete-suggestions { |
|
1101 | .autocomplete-suggestions { | |
1101 | width: auto !important; // overrides autocomplete.js |
|
1102 | width: auto !important; // overrides autocomplete.js | |
1102 | margin: 0; |
|
1103 | margin: 0; | |
1103 | border: @border-thickness solid @rcblue; |
|
1104 | border: @border-thickness solid @rcblue; | |
1104 | border-radius: @border-radius; |
|
1105 | border-radius: @border-radius; | |
1105 | color: @rcblue; |
|
1106 | color: @rcblue; | |
1106 | background-color: white; |
|
1107 | background-color: white; | |
1107 | } |
|
1108 | } | |
1108 | .autocomplete-selected { |
|
1109 | .autocomplete-selected { | |
1109 | background: #F0F0F0; |
|
1110 | background: #F0F0F0; | |
1110 | } |
|
1111 | } | |
1111 | .ac-container-wrap { |
|
1112 | .ac-container-wrap { | |
1112 | margin: 0; |
|
1113 | margin: 0; | |
1113 | padding: 8px; |
|
1114 | padding: 8px; | |
1114 | border-bottom: @border-thickness solid @rclightblue; |
|
1115 | border-bottom: @border-thickness solid @rclightblue; | |
1115 | list-style-type: none; |
|
1116 | list-style-type: none; | |
1116 | cursor: pointer; |
|
1117 | cursor: pointer; | |
1117 |
|
1118 | |||
1118 | &:hover { |
|
1119 | &:hover { | |
1119 | background-color: @rclightblue; |
|
1120 | background-color: @rclightblue; | |
1120 | } |
|
1121 | } | |
1121 |
|
1122 | |||
1122 | img { |
|
1123 | img { | |
1123 | margin-right: 1em; |
|
1124 | margin-right: 1em; | |
1124 | } |
|
1125 | } | |
1125 |
|
1126 | |||
1126 | strong { |
|
1127 | strong { | |
1127 | font-weight: normal; |
|
1128 | font-weight: normal; | |
1128 | } |
|
1129 | } | |
1129 | } |
|
1130 | } | |
1130 |
|
1131 | |||
1131 | // Settings Dropdown |
|
1132 | // Settings Dropdown | |
1132 | .user-menu .container { |
|
1133 | .user-menu .container { | |
1133 | padding: 0 4px; |
|
1134 | padding: 0 4px; | |
1134 | margin: 0; |
|
1135 | margin: 0; | |
1135 | } |
|
1136 | } | |
1136 |
|
1137 | |||
1137 | .user-menu .gravatar { |
|
1138 | .user-menu .gravatar { | |
1138 | cursor: pointer; |
|
1139 | cursor: pointer; | |
1139 | } |
|
1140 | } | |
1140 |
|
1141 | |||
1141 | .codeblock { |
|
1142 | .codeblock { | |
1142 | margin-bottom: @padding; |
|
1143 | margin-bottom: @padding; | |
1143 | clear: both; |
|
1144 | clear: both; | |
1144 |
|
1145 | |||
1145 | .stats{ |
|
1146 | .stats{ | |
1146 | overflow: hidden; |
|
1147 | overflow: hidden; | |
1147 | } |
|
1148 | } | |
1148 |
|
1149 | |||
1149 | .message{ |
|
1150 | .message{ | |
1150 | textarea{ |
|
1151 | textarea{ | |
1151 | margin: 0; |
|
1152 | margin: 0; | |
1152 | } |
|
1153 | } | |
1153 | } |
|
1154 | } | |
1154 |
|
1155 | |||
1155 | .code-header { |
|
1156 | .code-header { | |
1156 | .stats { |
|
1157 | .stats { | |
1157 | line-height: 2em; |
|
1158 | line-height: 2em; | |
1158 |
|
1159 | |||
1159 | .revision_id { |
|
1160 | .revision_id { | |
1160 | margin-left: 0; |
|
1161 | margin-left: 0; | |
1161 | } |
|
1162 | } | |
1162 | .buttons { |
|
1163 | .buttons { | |
1163 | padding-right: 0; |
|
1164 | padding-right: 0; | |
1164 | } |
|
1165 | } | |
1165 | } |
|
1166 | } | |
1166 |
|
1167 | |||
1167 | .item{ |
|
1168 | .item{ | |
1168 | margin-right: 0.5em; |
|
1169 | margin-right: 0.5em; | |
1169 | } |
|
1170 | } | |
1170 | } |
|
1171 | } | |
1171 |
|
1172 | |||
1172 | #editor_container{ |
|
1173 | #editor_container{ | |
1173 | position: relative; |
|
1174 | position: relative; | |
1174 | margin: @padding; |
|
1175 | margin: @padding; | |
1175 | } |
|
1176 | } | |
1176 | } |
|
1177 | } | |
1177 |
|
1178 | |||
1178 | #file_history_container { |
|
1179 | #file_history_container { | |
1179 | display: none; |
|
1180 | display: none; | |
1180 | } |
|
1181 | } | |
1181 |
|
1182 | |||
1182 | .file-history-inner { |
|
1183 | .file-history-inner { | |
1183 | margin-bottom: 10px; |
|
1184 | margin-bottom: 10px; | |
1184 | } |
|
1185 | } | |
1185 |
|
1186 | |||
1186 | // Pull Requests |
|
1187 | // Pull Requests | |
1187 | .summary-details { |
|
1188 | .summary-details { | |
1188 | width: 72%; |
|
1189 | width: 72%; | |
1189 | } |
|
1190 | } | |
1190 | .pr-summary { |
|
1191 | .pr-summary { | |
1191 | border-bottom: @border-thickness solid @grey5; |
|
1192 | border-bottom: @border-thickness solid @grey5; | |
1192 | margin-bottom: @space; |
|
1193 | margin-bottom: @space; | |
1193 | } |
|
1194 | } | |
1194 | .reviewers-title { |
|
1195 | .reviewers-title { | |
1195 | width: 25%; |
|
1196 | width: 25%; | |
1196 | min-width: 200px; |
|
1197 | min-width: 200px; | |
1197 | } |
|
1198 | } | |
1198 | .reviewers { |
|
1199 | .reviewers { | |
1199 | width: 25%; |
|
1200 | width: 25%; | |
1200 | min-width: 200px; |
|
1201 | min-width: 200px; | |
1201 | } |
|
1202 | } | |
1202 | .reviewers ul li { |
|
1203 | .reviewers ul li { | |
1203 | position: relative; |
|
1204 | position: relative; | |
1204 | width: 100%; |
|
1205 | width: 100%; | |
1205 | margin-bottom: 8px; |
|
1206 | margin-bottom: 8px; | |
1206 | } |
|
1207 | } | |
1207 | .reviewers_member { |
|
1208 | .reviewers_member { | |
1208 | width: 100%; |
|
1209 | width: 100%; | |
1209 | overflow: auto; |
|
1210 | overflow: auto; | |
1210 | } |
|
1211 | } | |
1211 | .reviewer_status { |
|
1212 | .reviewer_status { | |
1212 | display: inline-block; |
|
1213 | display: inline-block; | |
1213 | vertical-align: top; |
|
1214 | vertical-align: top; | |
1214 | width: 7%; |
|
1215 | width: 7%; | |
1215 | min-width: 20px; |
|
1216 | min-width: 20px; | |
1216 | height: 1.2em; |
|
1217 | height: 1.2em; | |
1217 | margin-top: 3px; |
|
1218 | margin-top: 3px; | |
1218 | line-height: 1em; |
|
1219 | line-height: 1em; | |
1219 | } |
|
1220 | } | |
1220 |
|
1221 | |||
1221 | .reviewer_name { |
|
1222 | .reviewer_name { | |
1222 | display: inline-block; |
|
1223 | display: inline-block; | |
1223 | max-width: 83%; |
|
1224 | max-width: 83%; | |
1224 | padding-right: 20px; |
|
1225 | padding-right: 20px; | |
1225 | vertical-align: middle; |
|
1226 | vertical-align: middle; | |
|
1227 | line-height: 1; | |||
|
1228 | ||||
|
1229 | .rc-user { | |||
|
1230 | min-width: 0; | |||
|
1231 | margin: -2px 1em 0 0; | |||
|
1232 | } | |||
|
1233 | ||||
|
1234 | .reviewer { | |||
|
1235 | float: left; | |||
|
1236 | } | |||
1226 | } |
|
1237 | } | |
1227 |
|
1238 | |||
1228 | .reviewer_member_remove { |
|
1239 | .reviewer_member_remove { | |
1229 | position: absolute; |
|
1240 | position: absolute; | |
1230 | right: 0; |
|
1241 | right: 0; | |
1231 | top: 0; |
|
1242 | top: 0; | |
1232 | width: 16px; |
|
1243 | width: 16px; | |
1233 | margin-bottom: 10px; |
|
1244 | margin-bottom: 10px; | |
1234 | padding: 0; |
|
1245 | padding: 0; | |
1235 | color: black; |
|
1246 | color: black; | |
1236 | } |
|
1247 | } | |
1237 | .reviewer_member_status { |
|
1248 | .reviewer_member_status { | |
1238 | margin-top: 5px; |
|
1249 | margin-top: 5px; | |
1239 | } |
|
1250 | } | |
1240 | .pr-summary #summary{ |
|
1251 | .pr-summary #summary{ | |
1241 | width: 100%; |
|
1252 | width: 100%; | |
1242 | } |
|
1253 | } | |
1243 | .pr-summary .action_button:hover { |
|
1254 | .pr-summary .action_button:hover { | |
1244 | border: 0; |
|
1255 | border: 0; | |
1245 | cursor: pointer; |
|
1256 | cursor: pointer; | |
1246 | } |
|
1257 | } | |
1247 | .pr-details-title { |
|
1258 | .pr-details-title { | |
1248 | padding-bottom: 8px; |
|
1259 | padding-bottom: 8px; | |
1249 | border-bottom: @border-thickness solid @grey5; |
|
1260 | border-bottom: @border-thickness solid @grey5; | |
1250 | .action_button { |
|
1261 | .action_button { | |
1251 | color: @rcblue; |
|
1262 | color: @rcblue; | |
1252 | } |
|
1263 | } | |
1253 | } |
|
1264 | } | |
1254 | .pr-details-content { |
|
1265 | .pr-details-content { | |
1255 | margin-top: @textmargin; |
|
1266 | margin-top: @textmargin; | |
1256 |
margin-bottom: @textmargin |
|
1267 | margin-bottom: @textmargin; | |
1257 | } |
|
1268 | } | |
1258 | .pr-description { |
|
1269 | .pr-description { | |
1259 | white-space:pre-wrap; |
|
1270 | white-space:pre-wrap; | |
1260 | } |
|
1271 | } | |
1261 | .group_members { |
|
1272 | .group_members { | |
1262 | margin-top: 0; |
|
1273 | margin-top: 0; | |
1263 | padding: 0; |
|
1274 | padding: 0; | |
1264 | list-style: outside none none; |
|
1275 | list-style: outside none none; | |
1265 | } |
|
1276 | } | |
1266 | .reviewer_ac .ac-input { |
|
1277 | .reviewer_ac .ac-input { | |
1267 | width: 92%; |
|
1278 | width: 92%; | |
1268 | margin-bottom: 1em; |
|
1279 | margin-bottom: 1em; | |
1269 | } |
|
1280 | } | |
1270 | #update_commits { |
|
1281 | #update_commits { | |
1271 | float: right; |
|
1282 | float: right; | |
1272 | } |
|
1283 | } | |
1273 | .compare_view_commits tr{ |
|
1284 | .compare_view_commits tr{ | |
1274 | height: 20px; |
|
1285 | height: 20px; | |
1275 | } |
|
1286 | } | |
1276 | .compare_view_commits td { |
|
1287 | .compare_view_commits td { | |
1277 | vertical-align: top; |
|
1288 | vertical-align: top; | |
1278 | padding-top: 10px; |
|
1289 | padding-top: 10px; | |
1279 | } |
|
1290 | } | |
1280 | .compare_view_commits .author { |
|
1291 | .compare_view_commits .author { | |
1281 | margin-left: 5px; |
|
1292 | margin-left: 5px; | |
1282 | } |
|
1293 | } | |
1283 |
|
1294 | |||
1284 | .compare_view_files { |
|
1295 | .compare_view_files { | |
1285 | width: 100%; |
|
1296 | width: 100%; | |
1286 |
|
1297 | |||
1287 | td { |
|
1298 | td { | |
1288 | vertical-align: middle; |
|
1299 | vertical-align: middle; | |
1289 | } |
|
1300 | } | |
1290 | } |
|
1301 | } | |
1291 |
|
1302 | |||
1292 | .compare_view_filepath { |
|
1303 | .compare_view_filepath { | |
1293 | color: @grey1; |
|
1304 | color: @grey1; | |
1294 | } |
|
1305 | } | |
1295 |
|
1306 | |||
1296 | .show_more { |
|
1307 | .show_more { | |
1297 | display: inline-block; |
|
1308 | display: inline-block; | |
1298 | position: relative; |
|
1309 | position: relative; | |
1299 | vertical-align: middle; |
|
1310 | vertical-align: middle; | |
1300 | width: 4px; |
|
1311 | width: 4px; | |
1301 | height: @basefontsize; |
|
1312 | height: @basefontsize; | |
1302 |
|
1313 | |||
1303 | &:after { |
|
1314 | &:after { | |
1304 | content: "\00A0\25BE"; |
|
1315 | content: "\00A0\25BE"; | |
1305 | display: inline-block; |
|
1316 | display: inline-block; | |
1306 | width:10px; |
|
1317 | width:10px; | |
1307 | line-height: 5px; |
|
1318 | line-height: 5px; | |
1308 | font-size: 12px; |
|
1319 | font-size: 12px; | |
1309 | cursor: pointer; |
|
1320 | cursor: pointer; | |
1310 | } |
|
1321 | } | |
1311 | } |
|
1322 | } | |
1312 |
|
1323 | |||
1313 | .journal_more .show_more { |
|
1324 | .journal_more .show_more { | |
1314 | display: inline; |
|
1325 | display: inline; | |
1315 |
|
1326 | |||
1316 | &:after { |
|
1327 | &:after { | |
1317 | content: none; |
|
1328 | content: none; | |
1318 | } |
|
1329 | } | |
1319 | } |
|
1330 | } | |
1320 |
|
1331 | |||
1321 | .open .show_more:after, |
|
1332 | .open .show_more:after, | |
1322 | .select2-dropdown-open .show_more:after { |
|
1333 | .select2-dropdown-open .show_more:after { | |
1323 | .rotate(180deg); |
|
1334 | .rotate(180deg); | |
1324 | margin-left: 4px; |
|
1335 | margin-left: 4px; | |
1325 | } |
|
1336 | } | |
1326 |
|
1337 | |||
1327 |
|
1338 | |||
1328 | .compare_view_commits .collapse_commit:after { |
|
1339 | .compare_view_commits .collapse_commit:after { | |
1329 | cursor: pointer; |
|
1340 | cursor: pointer; | |
1330 | content: "\00A0\25B4"; |
|
1341 | content: "\00A0\25B4"; | |
1331 | margin-left: -3px; |
|
1342 | margin-left: -3px; | |
1332 | font-size: 17px; |
|
1343 | font-size: 17px; | |
1333 | color: @grey4; |
|
1344 | color: @grey4; | |
1334 | } |
|
1345 | } | |
1335 |
|
1346 | |||
1336 | .diff_links { |
|
1347 | .diff_links { | |
1337 | margin-left: 8px; |
|
1348 | margin-left: 8px; | |
1338 | } |
|
1349 | } | |
1339 |
|
1350 | |||
1340 | p.ancestor { |
|
1351 | p.ancestor { | |
1341 | margin: @padding 0; |
|
1352 | margin: @padding 0; | |
1342 | } |
|
1353 | } | |
1343 |
|
1354 | |||
1344 | .cs_icon_td input[type="checkbox"] { |
|
1355 | .cs_icon_td input[type="checkbox"] { | |
1345 | display: none; |
|
1356 | display: none; | |
1346 | } |
|
1357 | } | |
1347 |
|
1358 | |||
1348 | .cs_icon_td .expand_file_icon:after { |
|
1359 | .cs_icon_td .expand_file_icon:after { | |
1349 | cursor: pointer; |
|
1360 | cursor: pointer; | |
1350 | content: "\00A0\25B6"; |
|
1361 | content: "\00A0\25B6"; | |
1351 | font-size: 12px; |
|
1362 | font-size: 12px; | |
1352 | color: @grey4; |
|
1363 | color: @grey4; | |
1353 | } |
|
1364 | } | |
1354 |
|
1365 | |||
1355 | .cs_icon_td .collapse_file_icon:after { |
|
1366 | .cs_icon_td .collapse_file_icon:after { | |
1356 | cursor: pointer; |
|
1367 | cursor: pointer; | |
1357 | content: "\00A0\25BC"; |
|
1368 | content: "\00A0\25BC"; | |
1358 | font-size: 12px; |
|
1369 | font-size: 12px; | |
1359 | color: @grey4; |
|
1370 | color: @grey4; | |
1360 | } |
|
1371 | } | |
1361 |
|
1372 | |||
1362 | /*new binary |
|
1373 | /*new binary | |
1363 | NEW_FILENODE = 1 |
|
1374 | NEW_FILENODE = 1 | |
1364 | DEL_FILENODE = 2 |
|
1375 | DEL_FILENODE = 2 | |
1365 | MOD_FILENODE = 3 |
|
1376 | MOD_FILENODE = 3 | |
1366 | RENAMED_FILENODE = 4 |
|
1377 | RENAMED_FILENODE = 4 | |
1367 | COPIED_FILENODE = 5 |
|
1378 | COPIED_FILENODE = 5 | |
1368 | CHMOD_FILENODE = 6 |
|
1379 | CHMOD_FILENODE = 6 | |
1369 | BIN_FILENODE = 7 |
|
1380 | BIN_FILENODE = 7 | |
1370 | */ |
|
1381 | */ | |
1371 | .cs_files_expand { |
|
1382 | .cs_files_expand { | |
1372 | font-size: @basefontsize + 5px; |
|
1383 | font-size: @basefontsize + 5px; | |
1373 | line-height: 1.8em; |
|
1384 | line-height: 1.8em; | |
1374 | float: right; |
|
1385 | float: right; | |
1375 | } |
|
1386 | } | |
1376 |
|
1387 | |||
1377 | .cs_files_expand span{ |
|
1388 | .cs_files_expand span{ | |
1378 | color: @rcblue; |
|
1389 | color: @rcblue; | |
1379 | cursor: pointer; |
|
1390 | cursor: pointer; | |
1380 | } |
|
1391 | } | |
1381 | .cs_files { |
|
1392 | .cs_files { | |
1382 | clear: both; |
|
1393 | clear: both; | |
1383 | padding-bottom: @padding; |
|
1394 | padding-bottom: @padding; | |
1384 |
|
1395 | |||
1385 | .cur_cs { |
|
1396 | .cur_cs { | |
1386 | margin: 10px 2px; |
|
1397 | margin: 10px 2px; | |
1387 | font-weight: bold; |
|
1398 | font-weight: bold; | |
1388 | } |
|
1399 | } | |
1389 |
|
1400 | |||
1390 | .node { |
|
1401 | .node { | |
1391 | float: left; |
|
1402 | float: left; | |
1392 | } |
|
1403 | } | |
1393 |
|
1404 | |||
1394 | .changes { |
|
1405 | .changes { | |
1395 | float: right; |
|
1406 | float: right; | |
1396 | color: white; |
|
1407 | color: white; | |
1397 | font-size: @basefontsize - 4px; |
|
1408 | font-size: @basefontsize - 4px; | |
1398 | margin-top: 4px; |
|
1409 | margin-top: 4px; | |
1399 | opacity: 0.6; |
|
1410 | opacity: 0.6; | |
1400 | filter: Alpha(opacity=60); /* IE8 and earlier */ |
|
1411 | filter: Alpha(opacity=60); /* IE8 and earlier */ | |
1401 |
|
1412 | |||
1402 | .added { |
|
1413 | .added { | |
1403 | background-color: @alert1; |
|
1414 | background-color: @alert1; | |
1404 | float: left; |
|
1415 | float: left; | |
1405 | text-align: center; |
|
1416 | text-align: center; | |
1406 | } |
|
1417 | } | |
1407 |
|
1418 | |||
1408 | .deleted { |
|
1419 | .deleted { | |
1409 | background-color: @alert2; |
|
1420 | background-color: @alert2; | |
1410 | float: left; |
|
1421 | float: left; | |
1411 | text-align: center; |
|
1422 | text-align: center; | |
1412 | } |
|
1423 | } | |
1413 |
|
1424 | |||
1414 | .bin { |
|
1425 | .bin { | |
1415 | background-color: @alert1; |
|
1426 | background-color: @alert1; | |
1416 | text-align: center; |
|
1427 | text-align: center; | |
1417 | } |
|
1428 | } | |
1418 |
|
1429 | |||
1419 | /*new binary*/ |
|
1430 | /*new binary*/ | |
1420 | .bin.bin1 { |
|
1431 | .bin.bin1 { | |
1421 | background-color: @alert1; |
|
1432 | background-color: @alert1; | |
1422 | text-align: center; |
|
1433 | text-align: center; | |
1423 | } |
|
1434 | } | |
1424 |
|
1435 | |||
1425 | /*deleted binary*/ |
|
1436 | /*deleted binary*/ | |
1426 | .bin.bin2 { |
|
1437 | .bin.bin2 { | |
1427 | background-color: @alert2; |
|
1438 | background-color: @alert2; | |
1428 | text-align: center; |
|
1439 | text-align: center; | |
1429 | } |
|
1440 | } | |
1430 |
|
1441 | |||
1431 | /*mod binary*/ |
|
1442 | /*mod binary*/ | |
1432 | .bin.bin3 { |
|
1443 | .bin.bin3 { | |
1433 | background-color: @grey2; |
|
1444 | background-color: @grey2; | |
1434 | text-align: center; |
|
1445 | text-align: center; | |
1435 | } |
|
1446 | } | |
1436 |
|
1447 | |||
1437 | /*rename file*/ |
|
1448 | /*rename file*/ | |
1438 | .bin.bin4 { |
|
1449 | .bin.bin4 { | |
1439 | background-color: @alert4; |
|
1450 | background-color: @alert4; | |
1440 | text-align: center; |
|
1451 | text-align: center; | |
1441 | } |
|
1452 | } | |
1442 |
|
1453 | |||
1443 | /*copied file*/ |
|
1454 | /*copied file*/ | |
1444 | .bin.bin5 { |
|
1455 | .bin.bin5 { | |
1445 | background-color: @alert4; |
|
1456 | background-color: @alert4; | |
1446 | text-align: center; |
|
1457 | text-align: center; | |
1447 | } |
|
1458 | } | |
1448 |
|
1459 | |||
1449 | /*chmod file*/ |
|
1460 | /*chmod file*/ | |
1450 | .bin.bin6 { |
|
1461 | .bin.bin6 { | |
1451 | background-color: @grey2; |
|
1462 | background-color: @grey2; | |
1452 | text-align: center; |
|
1463 | text-align: center; | |
1453 | } |
|
1464 | } | |
1454 | } |
|
1465 | } | |
1455 | } |
|
1466 | } | |
1456 |
|
1467 | |||
1457 | .cs_files .cs_added, .cs_files .cs_A, |
|
1468 | .cs_files .cs_added, .cs_files .cs_A, | |
1458 | .cs_files .cs_added, .cs_files .cs_M, |
|
1469 | .cs_files .cs_added, .cs_files .cs_M, | |
1459 | .cs_files .cs_added, .cs_files .cs_D { |
|
1470 | .cs_files .cs_added, .cs_files .cs_D { | |
1460 | height: 16px; |
|
1471 | height: 16px; | |
1461 | padding-right: 10px; |
|
1472 | padding-right: 10px; | |
1462 | margin-top: 7px; |
|
1473 | margin-top: 7px; | |
1463 | text-align: left; |
|
1474 | text-align: left; | |
1464 | } |
|
1475 | } | |
1465 |
|
1476 | |||
1466 | .cs_icon_td { |
|
1477 | .cs_icon_td { | |
1467 | min-width: 16px; |
|
1478 | min-width: 16px; | |
1468 | width: 16px; |
|
1479 | width: 16px; | |
1469 | } |
|
1480 | } | |
1470 |
|
1481 | |||
1471 | .pull-request-merge { |
|
1482 | .pull-request-merge { | |
1472 | padding: 10px 0; |
|
1483 | padding: 10px 0; | |
1473 | margin-top: 10px; |
|
1484 | margin-top: 10px; | |
1474 | margin-bottom: 20px; |
|
1485 | margin-bottom: 20px; | |
1475 | } |
|
1486 | } | |
1476 |
|
1487 | |||
1477 | .pull-request-merge .pull-request-wrap { |
|
1488 | .pull-request-merge .pull-request-wrap { | |
1478 | height: 25px; |
|
1489 | height: 25px; | |
1479 | padding: 5px 0; |
|
1490 | padding: 5px 0; | |
1480 | } |
|
1491 | } | |
1481 |
|
1492 | |||
1482 | .pull-request-merge span { |
|
1493 | .pull-request-merge span { | |
1483 | margin-right: 10px; |
|
1494 | margin-right: 10px; | |
1484 | } |
|
1495 | } | |
1485 | #close_pull_request { |
|
1496 | #close_pull_request { | |
1486 | margin-right: 0px; |
|
1497 | margin-right: 0px; | |
1487 | } |
|
1498 | } | |
1488 |
|
1499 | |||
1489 | .empty_data { |
|
1500 | .empty_data { | |
1490 | color: @grey4; |
|
1501 | color: @grey4; | |
1491 | } |
|
1502 | } | |
1492 |
|
1503 | |||
1493 | #changeset_compare_view_content { |
|
1504 | #changeset_compare_view_content { | |
1494 | margin-bottom: @space; |
|
1505 | margin-bottom: @space; | |
1495 | clear: both; |
|
1506 | clear: both; | |
1496 | width: 100%; |
|
1507 | width: 100%; | |
1497 | box-sizing: border-box; |
|
1508 | box-sizing: border-box; | |
1498 | .border-radius(@border-radius); |
|
1509 | .border-radius(@border-radius); | |
1499 |
|
1510 | |||
1500 | .help-block { |
|
1511 | .help-block { | |
1501 | margin: @padding 0; |
|
1512 | margin: @padding 0; | |
1502 | color: @text-color; |
|
1513 | color: @text-color; | |
1503 | } |
|
1514 | } | |
1504 |
|
1515 | |||
1505 | .empty_data { |
|
1516 | .empty_data { | |
1506 | margin: @padding 0; |
|
1517 | margin: @padding 0; | |
1507 | } |
|
1518 | } | |
1508 |
|
1519 | |||
1509 | .alert { |
|
1520 | .alert { | |
1510 | margin-bottom: @space; |
|
1521 | margin-bottom: @space; | |
1511 | } |
|
1522 | } | |
1512 | } |
|
1523 | } | |
1513 |
|
1524 | |||
1514 | .table_disp { |
|
1525 | .table_disp { | |
1515 | .status { |
|
1526 | .status { | |
1516 | width: auto; |
|
1527 | width: auto; | |
1517 |
|
1528 | |||
1518 | .flag_status { |
|
1529 | .flag_status { | |
1519 | float: left; |
|
1530 | float: left; | |
1520 | } |
|
1531 | } | |
1521 | } |
|
1532 | } | |
1522 | } |
|
1533 | } | |
1523 |
|
1534 | |||
1524 | .status_box_menu { |
|
1535 | .status_box_menu { | |
1525 | margin: 0; |
|
1536 | margin: 0; | |
1526 | } |
|
1537 | } | |
1527 |
|
1538 | |||
1528 | .notification-table{ |
|
1539 | .notification-table{ | |
1529 | margin-bottom: @space; |
|
1540 | margin-bottom: @space; | |
1530 | display: table; |
|
1541 | display: table; | |
1531 | width: 100%; |
|
1542 | width: 100%; | |
1532 |
|
1543 | |||
1533 | .container{ |
|
1544 | .container{ | |
1534 | display: table-row; |
|
1545 | display: table-row; | |
1535 |
|
1546 | |||
1536 | .notification-header{ |
|
1547 | .notification-header{ | |
1537 | border-bottom: @border-thickness solid @border-default-color; |
|
1548 | border-bottom: @border-thickness solid @border-default-color; | |
1538 | } |
|
1549 | } | |
1539 |
|
1550 | |||
1540 | .notification-subject{ |
|
1551 | .notification-subject{ | |
1541 | display: table-cell; |
|
1552 | display: table-cell; | |
1542 | } |
|
1553 | } | |
1543 | } |
|
1554 | } | |
1544 | } |
|
1555 | } | |
1545 |
|
1556 | |||
1546 | // Notifications |
|
1557 | // Notifications | |
1547 | .notification-header{ |
|
1558 | .notification-header{ | |
1548 | display: table; |
|
1559 | display: table; | |
1549 | width: 100%; |
|
1560 | width: 100%; | |
1550 | padding: floor(@basefontsize/2) 0; |
|
1561 | padding: floor(@basefontsize/2) 0; | |
1551 | line-height: 1em; |
|
1562 | line-height: 1em; | |
1552 |
|
1563 | |||
1553 | .desc, .delete-notifications, .read-notifications{ |
|
1564 | .desc, .delete-notifications, .read-notifications{ | |
1554 | display: table-cell; |
|
1565 | display: table-cell; | |
1555 | text-align: left; |
|
1566 | text-align: left; | |
1556 | } |
|
1567 | } | |
1557 |
|
1568 | |||
1558 | .desc{ |
|
1569 | .desc{ | |
1559 | width: 1163px; |
|
1570 | width: 1163px; | |
1560 | } |
|
1571 | } | |
1561 |
|
1572 | |||
1562 | .delete-notifications, .read-notifications{ |
|
1573 | .delete-notifications, .read-notifications{ | |
1563 | width: 35px; |
|
1574 | width: 35px; | |
1564 | min-width: 35px; //fixes when only one button is displayed |
|
1575 | min-width: 35px; //fixes when only one button is displayed | |
1565 | } |
|
1576 | } | |
1566 | } |
|
1577 | } | |
1567 |
|
1578 | |||
1568 | .notification-body { |
|
1579 | .notification-body { | |
1569 | .markdown-block, |
|
1580 | .markdown-block, | |
1570 | .rst-block { |
|
1581 | .rst-block { | |
1571 | padding: @padding 0; |
|
1582 | padding: @padding 0; | |
1572 | } |
|
1583 | } | |
1573 |
|
1584 | |||
1574 | .notification-subject { |
|
1585 | .notification-subject { | |
1575 | padding: @textmargin 0; |
|
1586 | padding: @textmargin 0; | |
1576 | border-bottom: @border-thickness solid @border-default-color; |
|
1587 | border-bottom: @border-thickness solid @border-default-color; | |
1577 | } |
|
1588 | } | |
1578 | } |
|
1589 | } | |
1579 |
|
1590 | |||
1580 |
|
1591 | |||
1581 | .notifications_buttons{ |
|
1592 | .notifications_buttons{ | |
1582 | float: right; |
|
1593 | float: right; | |
1583 | } |
|
1594 | } | |
1584 |
|
1595 | |||
1585 | // Repositories |
|
1596 | // Repositories | |
1586 |
|
1597 | |||
1587 | #summary.fields{ |
|
1598 | #summary.fields{ | |
1588 | display: table; |
|
1599 | display: table; | |
1589 |
|
1600 | |||
1590 | .field{ |
|
1601 | .field{ | |
1591 | display: table-row; |
|
1602 | display: table-row; | |
1592 |
|
1603 | |||
1593 | .label-summary{ |
|
1604 | .label-summary{ | |
1594 | display: table-cell; |
|
1605 | display: table-cell; | |
1595 | min-width: @label-summary-minwidth; |
|
1606 | min-width: @label-summary-minwidth; | |
1596 | padding-top: @padding/2; |
|
1607 | padding-top: @padding/2; | |
1597 | padding-bottom: @padding/2; |
|
1608 | padding-bottom: @padding/2; | |
1598 | padding-right: @padding/2; |
|
1609 | padding-right: @padding/2; | |
1599 | } |
|
1610 | } | |
1600 |
|
1611 | |||
1601 | .input{ |
|
1612 | .input{ | |
1602 | display: table-cell; |
|
1613 | display: table-cell; | |
1603 | padding: @padding/2; |
|
1614 | padding: @padding/2; | |
1604 |
|
1615 | |||
1605 | input{ |
|
1616 | input{ | |
1606 | min-width: 29em; |
|
1617 | min-width: 29em; | |
1607 | padding: @padding/4; |
|
1618 | padding: @padding/4; | |
1608 | } |
|
1619 | } | |
1609 | } |
|
1620 | } | |
1610 | .statistics, .downloads{ |
|
1621 | .statistics, .downloads{ | |
1611 | .disabled{ |
|
1622 | .disabled{ | |
1612 | color: @grey4; |
|
1623 | color: @grey4; | |
1613 | } |
|
1624 | } | |
1614 | } |
|
1625 | } | |
1615 | } |
|
1626 | } | |
1616 | } |
|
1627 | } | |
1617 |
|
1628 | |||
1618 | #summary{ |
|
1629 | #summary{ | |
1619 | width: 70%; |
|
1630 | width: 70%; | |
1620 | } |
|
1631 | } | |
1621 |
|
1632 | |||
1622 |
|
1633 | |||
1623 | // Journal |
|
1634 | // Journal | |
1624 | .journal.title { |
|
1635 | .journal.title { | |
1625 | h5 { |
|
1636 | h5 { | |
1626 | float: left; |
|
1637 | float: left; | |
1627 | margin: 0; |
|
1638 | margin: 0; | |
1628 | width: 70%; |
|
1639 | width: 70%; | |
1629 | } |
|
1640 | } | |
1630 |
|
1641 | |||
1631 | ul { |
|
1642 | ul { | |
1632 | float: right; |
|
1643 | float: right; | |
1633 | display: inline-block; |
|
1644 | display: inline-block; | |
1634 | margin: 0; |
|
1645 | margin: 0; | |
1635 | width: 30%; |
|
1646 | width: 30%; | |
1636 | text-align: right; |
|
1647 | text-align: right; | |
1637 |
|
1648 | |||
1638 | li { |
|
1649 | li { | |
1639 | display: inline; |
|
1650 | display: inline; | |
1640 | font-size: @journal-fontsize; |
|
1651 | font-size: @journal-fontsize; | |
1641 | line-height: 1em; |
|
1652 | line-height: 1em; | |
1642 |
|
1653 | |||
1643 | &:before { content: none; } |
|
1654 | &:before { content: none; } | |
1644 | } |
|
1655 | } | |
1645 | } |
|
1656 | } | |
1646 | } |
|
1657 | } | |
1647 |
|
1658 | |||
1648 | .filterexample { |
|
1659 | .filterexample { | |
1649 | position: absolute; |
|
1660 | position: absolute; | |
1650 | top: 95px; |
|
1661 | top: 95px; | |
1651 | left: @contentpadding; |
|
1662 | left: @contentpadding; | |
1652 | color: @rcblue; |
|
1663 | color: @rcblue; | |
1653 | font-size: 11px; |
|
1664 | font-size: 11px; | |
1654 | font-family: @text-regular; |
|
1665 | font-family: @text-regular; | |
1655 | cursor: help; |
|
1666 | cursor: help; | |
1656 |
|
1667 | |||
1657 | &:hover { |
|
1668 | &:hover { | |
1658 | color: @rcdarkblue; |
|
1669 | color: @rcdarkblue; | |
1659 | } |
|
1670 | } | |
1660 |
|
1671 | |||
1661 | @media (max-width:768px) { |
|
1672 | @media (max-width:768px) { | |
1662 | position: relative; |
|
1673 | position: relative; | |
1663 | top: auto; |
|
1674 | top: auto; | |
1664 | left: auto; |
|
1675 | left: auto; | |
1665 | display: block; |
|
1676 | display: block; | |
1666 | } |
|
1677 | } | |
1667 | } |
|
1678 | } | |
1668 |
|
1679 | |||
1669 |
|
1680 | |||
1670 | #journal{ |
|
1681 | #journal{ | |
1671 | margin-bottom: @space; |
|
1682 | margin-bottom: @space; | |
1672 |
|
1683 | |||
1673 | .journal_day{ |
|
1684 | .journal_day{ | |
1674 | margin-bottom: @textmargin/2; |
|
1685 | margin-bottom: @textmargin/2; | |
1675 | padding-bottom: @textmargin/2; |
|
1686 | padding-bottom: @textmargin/2; | |
1676 | font-size: @journal-fontsize; |
|
1687 | font-size: @journal-fontsize; | |
1677 | border-bottom: @border-thickness solid @border-default-color; |
|
1688 | border-bottom: @border-thickness solid @border-default-color; | |
1678 | } |
|
1689 | } | |
1679 |
|
1690 | |||
1680 | .journal_container{ |
|
1691 | .journal_container{ | |
1681 | margin-bottom: @space; |
|
1692 | margin-bottom: @space; | |
1682 |
|
1693 | |||
1683 | .journal_user{ |
|
1694 | .journal_user{ | |
1684 | display: inline-block; |
|
1695 | display: inline-block; | |
1685 | } |
|
1696 | } | |
1686 | .journal_action_container{ |
|
1697 | .journal_action_container{ | |
1687 | display: block; |
|
1698 | display: block; | |
1688 | margin-top: @textmargin; |
|
1699 | margin-top: @textmargin; | |
1689 |
|
1700 | |||
1690 | div{ |
|
1701 | div{ | |
1691 | display: inline; |
|
1702 | display: inline; | |
1692 | } |
|
1703 | } | |
1693 |
|
1704 | |||
1694 | div.journal_action_params{ |
|
1705 | div.journal_action_params{ | |
1695 | display: block; |
|
1706 | display: block; | |
1696 | } |
|
1707 | } | |
1697 |
|
1708 | |||
1698 | div.journal_repo:after{ |
|
1709 | div.journal_repo:after{ | |
1699 | content: "\A"; |
|
1710 | content: "\A"; | |
1700 | white-space: pre; |
|
1711 | white-space: pre; | |
1701 | } |
|
1712 | } | |
1702 |
|
1713 | |||
1703 | div.date{ |
|
1714 | div.date{ | |
1704 | display: block; |
|
1715 | display: block; | |
1705 | margin-bottom: @textmargin; |
|
1716 | margin-bottom: @textmargin; | |
1706 | } |
|
1717 | } | |
1707 | } |
|
1718 | } | |
1708 | } |
|
1719 | } | |
1709 | } |
|
1720 | } | |
1710 |
|
1721 | |||
1711 | // Files |
|
1722 | // Files | |
1712 | .edit-file-title { |
|
1723 | .edit-file-title { | |
1713 | border-bottom: @border-thickness solid @border-default-color; |
|
1724 | border-bottom: @border-thickness solid @border-default-color; | |
1714 |
|
1725 | |||
1715 | .breadcrumbs { |
|
1726 | .breadcrumbs { | |
1716 | margin-bottom: 0; |
|
1727 | margin-bottom: 0; | |
1717 | } |
|
1728 | } | |
1718 | } |
|
1729 | } | |
1719 |
|
1730 | |||
1720 | .edit-file-fieldset { |
|
1731 | .edit-file-fieldset { | |
1721 | margin-top: @sidebarpadding; |
|
1732 | margin-top: @sidebarpadding; | |
1722 |
|
1733 | |||
1723 | .fieldset { |
|
1734 | .fieldset { | |
1724 | .left-label { |
|
1735 | .left-label { | |
1725 | width: 13%; |
|
1736 | width: 13%; | |
1726 | } |
|
1737 | } | |
1727 | .right-content { |
|
1738 | .right-content { | |
1728 | width: 87%; |
|
1739 | width: 87%; | |
1729 | max-width: 100%; |
|
1740 | max-width: 100%; | |
1730 | } |
|
1741 | } | |
1731 | .filename-label { |
|
1742 | .filename-label { | |
1732 | margin-top: 13px; |
|
1743 | margin-top: 13px; | |
1733 | } |
|
1744 | } | |
1734 | .commit-message-label { |
|
1745 | .commit-message-label { | |
1735 | margin-top: 4px; |
|
1746 | margin-top: 4px; | |
1736 | } |
|
1747 | } | |
1737 | .file-upload-input { |
|
1748 | .file-upload-input { | |
1738 | input { |
|
1749 | input { | |
1739 | display: none; |
|
1750 | display: none; | |
1740 | } |
|
1751 | } | |
1741 | } |
|
1752 | } | |
1742 | p { |
|
1753 | p { | |
1743 | margin-top: 5px; |
|
1754 | margin-top: 5px; | |
1744 | } |
|
1755 | } | |
1745 |
|
1756 | |||
1746 | } |
|
1757 | } | |
1747 | .custom-path-link { |
|
1758 | .custom-path-link { | |
1748 | margin-left: 5px; |
|
1759 | margin-left: 5px; | |
1749 | } |
|
1760 | } | |
1750 | #commit { |
|
1761 | #commit { | |
1751 | resize: vertical; |
|
1762 | resize: vertical; | |
1752 | } |
|
1763 | } | |
1753 | } |
|
1764 | } | |
1754 |
|
1765 | |||
1755 | .delete-file-preview { |
|
1766 | .delete-file-preview { | |
1756 | max-height: 250px; |
|
1767 | max-height: 250px; | |
1757 | } |
|
1768 | } | |
1758 |
|
1769 | |||
1759 | .new-file, |
|
1770 | .new-file, | |
1760 | #filter_activate, |
|
1771 | #filter_activate, | |
1761 | #filter_deactivate { |
|
1772 | #filter_deactivate { | |
1762 | float: left; |
|
1773 | float: left; | |
1763 | margin: 0 0 0 15px; |
|
1774 | margin: 0 0 0 15px; | |
1764 | } |
|
1775 | } | |
1765 |
|
1776 | |||
1766 | h3.files_location{ |
|
1777 | h3.files_location{ | |
1767 | line-height: 2.4em; |
|
1778 | line-height: 2.4em; | |
1768 | } |
|
1779 | } | |
1769 |
|
1780 | |||
1770 | .browser-nav { |
|
1781 | .browser-nav { | |
1771 | display: table; |
|
1782 | display: table; | |
1772 | margin-bottom: @space; |
|
1783 | margin-bottom: @space; | |
1773 |
|
1784 | |||
1774 |
|
1785 | |||
1775 | .info_box { |
|
1786 | .info_box { | |
1776 | display: inline-table; |
|
1787 | display: inline-table; | |
1777 | height: 2.5em; |
|
1788 | height: 2.5em; | |
1778 |
|
1789 | |||
1779 | .browser-cur-rev, .info_box_elem { |
|
1790 | .browser-cur-rev, .info_box_elem { | |
1780 | display: table-cell; |
|
1791 | display: table-cell; | |
1781 | vertical-align: middle; |
|
1792 | vertical-align: middle; | |
1782 | } |
|
1793 | } | |
1783 |
|
1794 | |||
1784 | .info_box_elem { |
|
1795 | .info_box_elem { | |
1785 | border-top: @border-thickness solid @rcblue; |
|
1796 | border-top: @border-thickness solid @rcblue; | |
1786 | border-bottom: @border-thickness solid @rcblue; |
|
1797 | border-bottom: @border-thickness solid @rcblue; | |
1787 |
|
1798 | |||
1788 | #at_rev, a { |
|
1799 | #at_rev, a { | |
1789 | padding: 0.6em 0.9em; |
|
1800 | padding: 0.6em 0.9em; | |
1790 | margin: 0; |
|
1801 | margin: 0; | |
1791 | .box-shadow(none); |
|
1802 | .box-shadow(none); | |
1792 | border: 0; |
|
1803 | border: 0; | |
1793 | height: 12px; |
|
1804 | height: 12px; | |
1794 | } |
|
1805 | } | |
1795 |
|
1806 | |||
1796 | input#at_rev { |
|
1807 | input#at_rev { | |
1797 | max-width: 50px; |
|
1808 | max-width: 50px; | |
1798 | text-align: right; |
|
1809 | text-align: right; | |
1799 | } |
|
1810 | } | |
1800 |
|
1811 | |||
1801 | &.previous { |
|
1812 | &.previous { | |
1802 | border: @border-thickness solid @rcblue; |
|
1813 | border: @border-thickness solid @rcblue; | |
1803 | .disabled { |
|
1814 | .disabled { | |
1804 | color: @grey4; |
|
1815 | color: @grey4; | |
1805 | cursor: not-allowed; |
|
1816 | cursor: not-allowed; | |
1806 | } |
|
1817 | } | |
1807 | } |
|
1818 | } | |
1808 |
|
1819 | |||
1809 | &.next { |
|
1820 | &.next { | |
1810 | border: @border-thickness solid @rcblue; |
|
1821 | border: @border-thickness solid @rcblue; | |
1811 | .disabled { |
|
1822 | .disabled { | |
1812 | color: @grey4; |
|
1823 | color: @grey4; | |
1813 | cursor: not-allowed; |
|
1824 | cursor: not-allowed; | |
1814 | } |
|
1825 | } | |
1815 | } |
|
1826 | } | |
1816 | } |
|
1827 | } | |
1817 |
|
1828 | |||
1818 | .browser-cur-rev { |
|
1829 | .browser-cur-rev { | |
1819 |
|
1830 | |||
1820 | span{ |
|
1831 | span{ | |
1821 | margin: 0; |
|
1832 | margin: 0; | |
1822 | color: @rcblue; |
|
1833 | color: @rcblue; | |
1823 | height: 12px; |
|
1834 | height: 12px; | |
1824 | display: inline-block; |
|
1835 | display: inline-block; | |
1825 | padding: 0.7em 1em ; |
|
1836 | padding: 0.7em 1em ; | |
1826 | border: @border-thickness solid @rcblue; |
|
1837 | border: @border-thickness solid @rcblue; | |
1827 | margin-right: @padding; |
|
1838 | margin-right: @padding; | |
1828 | } |
|
1839 | } | |
1829 | } |
|
1840 | } | |
1830 | } |
|
1841 | } | |
1831 |
|
1842 | |||
1832 | .search_activate { |
|
1843 | .search_activate { | |
1833 | display: table-cell; |
|
1844 | display: table-cell; | |
1834 | vertical-align: middle; |
|
1845 | vertical-align: middle; | |
1835 |
|
1846 | |||
1836 | input, label{ |
|
1847 | input, label{ | |
1837 | margin: 0; |
|
1848 | margin: 0; | |
1838 | padding: 0; |
|
1849 | padding: 0; | |
1839 | } |
|
1850 | } | |
1840 |
|
1851 | |||
1841 | input{ |
|
1852 | input{ | |
1842 | margin-left: @textmargin; |
|
1853 | margin-left: @textmargin; | |
1843 | } |
|
1854 | } | |
1844 |
|
1855 | |||
1845 | } |
|
1856 | } | |
1846 | } |
|
1857 | } | |
1847 |
|
1858 | |||
1848 | .file_author{ |
|
1859 | .file_author{ | |
1849 | margin-bottom: @padding; |
|
1860 | margin-bottom: @padding; | |
1850 |
|
1861 | |||
1851 | div{ |
|
1862 | div{ | |
1852 | display: inline-block; |
|
1863 | display: inline-block; | |
1853 | margin-right: 0.5em; |
|
1864 | margin-right: 0.5em; | |
1854 | } |
|
1865 | } | |
1855 | } |
|
1866 | } | |
1856 |
|
1867 | |||
1857 | .browser-cur-rev{ |
|
1868 | .browser-cur-rev{ | |
1858 | margin-bottom: @textmargin; |
|
1869 | margin-bottom: @textmargin; | |
1859 | } |
|
1870 | } | |
1860 |
|
1871 | |||
1861 | #node_filter_box_loading{ |
|
1872 | #node_filter_box_loading{ | |
1862 | .info_text; |
|
1873 | .info_text; | |
1863 | } |
|
1874 | } | |
1864 |
|
1875 | |||
1865 | .browser-search { |
|
1876 | .browser-search { | |
1866 | margin: -25px 0px 5px 0px; |
|
1877 | margin: -25px 0px 5px 0px; | |
1867 | } |
|
1878 | } | |
1868 |
|
1879 | |||
1869 | .node-filter { |
|
1880 | .node-filter { | |
1870 | font-size: @repo-title-fontsize; |
|
1881 | font-size: @repo-title-fontsize; | |
1871 | padding: 4px 0px 0px 0px; |
|
1882 | padding: 4px 0px 0px 0px; | |
1872 |
|
1883 | |||
1873 | .node-filter-path { |
|
1884 | .node-filter-path { | |
1874 | float: left; |
|
1885 | float: left; | |
1875 | color: @grey4; |
|
1886 | color: @grey4; | |
1876 | } |
|
1887 | } | |
1877 | .node-filter-input { |
|
1888 | .node-filter-input { | |
1878 | float: left; |
|
1889 | float: left; | |
1879 | margin: -2px 0px 0px 2px; |
|
1890 | margin: -2px 0px 0px 2px; | |
1880 | input { |
|
1891 | input { | |
1881 | padding: 2px; |
|
1892 | padding: 2px; | |
1882 | border: none; |
|
1893 | border: none; | |
1883 | font-size: @repo-title-fontsize; |
|
1894 | font-size: @repo-title-fontsize; | |
1884 | } |
|
1895 | } | |
1885 | } |
|
1896 | } | |
1886 | } |
|
1897 | } | |
1887 |
|
1898 | |||
1888 |
|
1899 | |||
1889 | .browser-result{ |
|
1900 | .browser-result{ | |
1890 | td a{ |
|
1901 | td a{ | |
1891 | margin-left: 0.5em; |
|
1902 | margin-left: 0.5em; | |
1892 | display: inline-block; |
|
1903 | display: inline-block; | |
1893 |
|
1904 | |||
1894 | em{ |
|
1905 | em{ | |
1895 | font-family: @text-bold; |
|
1906 | font-family: @text-bold; | |
1896 | } |
|
1907 | } | |
1897 | } |
|
1908 | } | |
1898 | } |
|
1909 | } | |
1899 |
|
1910 | |||
1900 | .browser-highlight{ |
|
1911 | .browser-highlight{ | |
1901 | background-color: @grey5-alpha; |
|
1912 | background-color: @grey5-alpha; | |
1902 | } |
|
1913 | } | |
1903 |
|
1914 | |||
1904 |
|
1915 | |||
1905 | // Search |
|
1916 | // Search | |
1906 |
|
1917 | |||
1907 | .search-form{ |
|
1918 | .search-form{ | |
1908 | #q { |
|
1919 | #q { | |
1909 | width: @search-form-width; |
|
1920 | width: @search-form-width; | |
1910 | } |
|
1921 | } | |
1911 | .fields{ |
|
1922 | .fields{ | |
1912 | margin: 0 0 @space; |
|
1923 | margin: 0 0 @space; | |
1913 | } |
|
1924 | } | |
1914 |
|
1925 | |||
1915 | label{ |
|
1926 | label{ | |
1916 | display: inline-block; |
|
1927 | display: inline-block; | |
1917 | margin-right: @textmargin; |
|
1928 | margin-right: @textmargin; | |
1918 | padding-top: 0.25em; |
|
1929 | padding-top: 0.25em; | |
1919 | } |
|
1930 | } | |
1920 |
|
1931 | |||
1921 |
|
1932 | |||
1922 | .results{ |
|
1933 | .results{ | |
1923 | clear: both; |
|
1934 | clear: both; | |
1924 | margin: 0 0 @padding; |
|
1935 | margin: 0 0 @padding; | |
1925 | } |
|
1936 | } | |
1926 | } |
|
1937 | } | |
1927 |
|
1938 | |||
1928 | div.search-feedback-items { |
|
1939 | div.search-feedback-items { | |
1929 | display: inline-block; |
|
1940 | display: inline-block; | |
1930 | padding:0px 0px 0px 96px; |
|
1941 | padding:0px 0px 0px 96px; | |
1931 | } |
|
1942 | } | |
1932 |
|
1943 | |||
1933 | div.search-code-body { |
|
1944 | div.search-code-body { | |
1934 | background-color: #ffffff; padding: 5px 0 5px 10px; |
|
1945 | background-color: #ffffff; padding: 5px 0 5px 10px; | |
1935 | pre { |
|
1946 | pre { | |
1936 | .match { background-color: #faffa6;} |
|
1947 | .match { background-color: #faffa6;} | |
1937 | .break { display: block; width: 100%; background-color: #DDE7EF; color: #747474; } |
|
1948 | .break { display: block; width: 100%; background-color: #DDE7EF; color: #747474; } | |
1938 | } |
|
1949 | } | |
1939 | } |
|
1950 | } | |
1940 |
|
1951 | |||
1941 | .expand_commit.search { |
|
1952 | .expand_commit.search { | |
1942 | .show_more.open { |
|
1953 | .show_more.open { | |
1943 | height: auto; |
|
1954 | height: auto; | |
1944 | max-height: none; |
|
1955 | max-height: none; | |
1945 | } |
|
1956 | } | |
1946 | } |
|
1957 | } | |
1947 |
|
1958 | |||
1948 | .search-results { |
|
1959 | .search-results { | |
1949 |
|
1960 | |||
1950 | h2 { |
|
1961 | h2 { | |
1951 | margin-bottom: 0; |
|
1962 | margin-bottom: 0; | |
1952 | } |
|
1963 | } | |
1953 | .codeblock { |
|
1964 | .codeblock { | |
1954 | border: none; |
|
1965 | border: none; | |
1955 | background: transparent; |
|
1966 | background: transparent; | |
1956 | } |
|
1967 | } | |
1957 |
|
1968 | |||
1958 | .codeblock-header { |
|
1969 | .codeblock-header { | |
1959 | border: none; |
|
1970 | border: none; | |
1960 | background: transparent; |
|
1971 | background: transparent; | |
1961 | } |
|
1972 | } | |
1962 |
|
1973 | |||
1963 | .code-body { |
|
1974 | .code-body { | |
1964 | border: @border-thickness solid @border-default-color; |
|
1975 | border: @border-thickness solid @border-default-color; | |
1965 | .border-radius(@border-radius); |
|
1976 | .border-radius(@border-radius); | |
1966 | } |
|
1977 | } | |
1967 |
|
1978 | |||
1968 | .td-commit { |
|
1979 | .td-commit { | |
1969 | &:extend(pre); |
|
1980 | &:extend(pre); | |
1970 | border-bottom: @border-thickness solid @border-default-color; |
|
1981 | border-bottom: @border-thickness solid @border-default-color; | |
1971 | } |
|
1982 | } | |
1972 |
|
1983 | |||
1973 | .message { |
|
1984 | .message { | |
1974 | height: auto; |
|
1985 | height: auto; | |
1975 | max-width: 350px; |
|
1986 | max-width: 350px; | |
1976 | white-space: normal; |
|
1987 | white-space: normal; | |
1977 | text-overflow: initial; |
|
1988 | text-overflow: initial; | |
1978 | overflow: visible; |
|
1989 | overflow: visible; | |
1979 |
|
1990 | |||
1980 | .match { background-color: #faffa6;} |
|
1991 | .match { background-color: #faffa6;} | |
1981 | .break { background-color: #DDE7EF; width: 100%; color: #747474; display: block; } |
|
1992 | .break { background-color: #DDE7EF; width: 100%; color: #747474; display: block; } | |
1982 | } |
|
1993 | } | |
1983 |
|
1994 | |||
1984 | } |
|
1995 | } | |
1985 |
|
1996 | |||
1986 | table.rctable td.td-search-results div { |
|
1997 | table.rctable td.td-search-results div { | |
1987 | max-width: 100%; |
|
1998 | max-width: 100%; | |
1988 | } |
|
1999 | } | |
1989 |
|
2000 | |||
1990 | #tip-box, .tip-box{ |
|
2001 | #tip-box, .tip-box{ | |
1991 | padding: @menupadding/2; |
|
2002 | padding: @menupadding/2; | |
1992 | display: block; |
|
2003 | display: block; | |
1993 | border: @border-thickness solid @border-highlight-color; |
|
2004 | border: @border-thickness solid @border-highlight-color; | |
1994 | .border-radius(@border-radius); |
|
2005 | .border-radius(@border-radius); | |
1995 | background-color: white; |
|
2006 | background-color: white; | |
1996 | z-index: 99; |
|
2007 | z-index: 99; | |
1997 | white-space: pre-wrap; |
|
2008 | white-space: pre-wrap; | |
1998 | } |
|
2009 | } | |
1999 |
|
2010 | |||
2000 | #linktt { |
|
2011 | #linktt { | |
2001 | width: 79px; |
|
2012 | width: 79px; | |
2002 | } |
|
2013 | } | |
2003 |
|
2014 | |||
2004 | #help_kb .modal-content{ |
|
2015 | #help_kb .modal-content{ | |
2005 | max-width: 750px; |
|
2016 | max-width: 750px; | |
2006 | margin: 10% auto; |
|
2017 | margin: 10% auto; | |
2007 |
|
2018 | |||
2008 | table{ |
|
2019 | table{ | |
2009 | td,th{ |
|
2020 | td,th{ | |
2010 | border-bottom: none; |
|
2021 | border-bottom: none; | |
2011 | line-height: 2.5em; |
|
2022 | line-height: 2.5em; | |
2012 | } |
|
2023 | } | |
2013 | th{ |
|
2024 | th{ | |
2014 | padding-bottom: @textmargin/2; |
|
2025 | padding-bottom: @textmargin/2; | |
2015 | } |
|
2026 | } | |
2016 | td.keys{ |
|
2027 | td.keys{ | |
2017 | text-align: center; |
|
2028 | text-align: center; | |
2018 | } |
|
2029 | } | |
2019 | } |
|
2030 | } | |
2020 |
|
2031 | |||
2021 | .block-left{ |
|
2032 | .block-left{ | |
2022 | width: 45%; |
|
2033 | width: 45%; | |
2023 | margin-right: 5%; |
|
2034 | margin-right: 5%; | |
2024 | } |
|
2035 | } | |
2025 | .modal-footer{ |
|
2036 | .modal-footer{ | |
2026 | clear: both; |
|
2037 | clear: both; | |
2027 | } |
|
2038 | } | |
2028 | .key.tag{ |
|
2039 | .key.tag{ | |
2029 | padding: 0.5em; |
|
2040 | padding: 0.5em; | |
2030 | background-color: @rcblue; |
|
2041 | background-color: @rcblue; | |
2031 | color: white; |
|
2042 | color: white; | |
2032 | border-color: @rcblue; |
|
2043 | border-color: @rcblue; | |
2033 | .box-shadow(none); |
|
2044 | .box-shadow(none); | |
2034 | } |
|
2045 | } | |
2035 | } |
|
2046 | } | |
2036 |
|
2047 | |||
2037 |
|
2048 | |||
2038 |
|
2049 | |||
2039 | //--- IMPORTS FOR REFACTORED STYLES ------------------// |
|
2050 | //--- IMPORTS FOR REFACTORED STYLES ------------------// | |
2040 |
|
2051 | |||
2041 | @import 'statistics-graph'; |
|
2052 | @import 'statistics-graph'; | |
2042 | @import 'tables'; |
|
2053 | @import 'tables'; | |
2043 | @import 'forms'; |
|
2054 | @import 'forms'; | |
2044 | @import 'diff'; |
|
2055 | @import 'diff'; | |
2045 | @import 'summary'; |
|
2056 | @import 'summary'; | |
2046 | @import 'navigation'; |
|
2057 | @import 'navigation'; | |
2047 |
|
2058 | |||
2048 | //--- SHOW/HIDE SECTIONS --// |
|
2059 | //--- SHOW/HIDE SECTIONS --// | |
2049 |
|
2060 | |||
2050 | .btn-collapse { |
|
2061 | .btn-collapse { | |
2051 | float: right; |
|
2062 | float: right; | |
2052 | text-align: right; |
|
2063 | text-align: right; | |
2053 | font-family: @text-light; |
|
2064 | font-family: @text-light; | |
2054 | font-size: @basefontsize; |
|
2065 | font-size: @basefontsize; | |
2055 | cursor: pointer; |
|
2066 | cursor: pointer; | |
2056 | border: none; |
|
2067 | border: none; | |
2057 | color: @rcblue; |
|
2068 | color: @rcblue; | |
2058 | } |
|
2069 | } | |
2059 |
|
2070 | |||
2060 | table.rctable, |
|
2071 | table.rctable, | |
2061 | table.dataTable { |
|
2072 | table.dataTable { | |
2062 | .btn-collapse { |
|
2073 | .btn-collapse { | |
2063 | float: right; |
|
2074 | float: right; | |
2064 | text-align: right; |
|
2075 | text-align: right; | |
2065 | } |
|
2076 | } | |
2066 | } |
|
2077 | } | |
2067 |
|
2078 | |||
2068 |
|
2079 | |||
2069 | // TODO: johbo: Fix for IE10, this avoids that we see a border |
|
2080 | // TODO: johbo: Fix for IE10, this avoids that we see a border | |
2070 | // and padding around checkboxes and radio boxes. Move to the right place, |
|
2081 | // and padding around checkboxes and radio boxes. Move to the right place, | |
2071 | // or better: Remove this once we did the form refactoring. |
|
2082 | // or better: Remove this once we did the form refactoring. | |
2072 | input[type=checkbox], |
|
2083 | input[type=checkbox], | |
2073 | input[type=radio] { |
|
2084 | input[type=radio] { | |
2074 | padding: 0; |
|
2085 | padding: 0; | |
2075 | border: none; |
|
2086 | border: none; | |
2076 | } |
|
2087 | } |
@@ -1,47 +1,49 b'' | |||||
1 | ## -*- coding: utf-8 -*- |
|
1 | ## -*- coding: utf-8 -*- | |
2 | <%namespace name="base" file="/base/base.html"/> |
|
2 | <%namespace name="base" file="/base/base.html"/> | |
3 |
|
3 | |||
4 | % if c.forks_pager: |
|
4 | % if c.forks_pager: | |
5 | <table class="rctable fork_summary"> |
|
5 | <table class="rctable fork_summary"> | |
6 | <tr> |
|
6 | <tr> | |
|
7 | <th>${_('Owner')}</th> | |||
7 | <th>${_('Fork')}</th> |
|
8 | <th>${_('Fork')}</th> | |
8 | <th>${_('Description')}</th> |
|
9 | <th>${_('Description')}</th> | |
9 | <th>${_('Forked')}</th> |
|
10 | <th>${_('Forked')}</th> | |
10 | <th></th> |
|
11 | <th></th> | |
11 | </tr> |
|
12 | </tr> | |
12 | % for f in c.forks_pager: |
|
13 | % for f in c.forks_pager: | |
13 | <tr> |
|
14 | <tr> | |
14 | <td class="td-user fork_user"> |
|
15 | <td class="td-user fork_user"> | |
15 | ${base.gravatar_with_user(f.user.email, 16)} |
|
16 | ${base.gravatar_with_user(f.user.email, 16)} | |
16 |
|
|
17 | </td> | |
|
18 | <td class="td-componentname"> | |||
17 | ${h.link_to(f.repo_name,h.url('summary_home',repo_name=f.repo_name))} |
|
19 | ${h.link_to(f.repo_name,h.url('summary_home',repo_name=f.repo_name))} | |
18 | </td> |
|
20 | </td> | |
19 | <td class="td-description"> |
|
21 | <td class="td-description"> | |
20 | <div class="truncate">${f.description}</div> |
|
22 | <div class="truncate">${f.description}</div> | |
21 | </td> |
|
23 | </td> | |
22 | <td class="td-time follower_date"> |
|
24 | <td class="td-time follower_date"> | |
23 | ${h.age_component(f.created_on)} |
|
25 | ${h.age_component(f.created_on)} | |
24 | </td> |
|
26 | </td> | |
25 | <td class="td-compare"> |
|
27 | <td class="td-compare"> | |
26 | <a title="${_('Compare fork with %s' % c.repo_name)}" |
|
28 | <a title="${_('Compare fork with %s' % c.repo_name)}" | |
27 | href="${h.url('compare_url',repo_name=c.repo_name, source_ref_type=c.rhodecode_db_repo.landing_rev[0],source_ref=c.rhodecode_db_repo.landing_rev[1],target_repo=f.repo_name,target_ref_type=c.rhodecode_db_repo.landing_rev[0],target_ref=c.rhodecode_db_repo.landing_rev[1], merge=1)}" |
|
29 | href="${h.url('compare_url',repo_name=c.repo_name, source_ref_type=c.rhodecode_db_repo.landing_rev[0],source_ref=c.rhodecode_db_repo.landing_rev[1],target_repo=f.repo_name,target_ref_type=c.rhodecode_db_repo.landing_rev[0],target_ref=c.rhodecode_db_repo.landing_rev[1], merge=1)}" | |
28 | class="btn-link"><i class="icon-loop"></i> ${_('Compare fork')}</a> |
|
30 | class="btn-link"><i class="icon-loop"></i> ${_('Compare fork')}</a> | |
29 | </td> |
|
31 | </td> | |
30 | </tr> |
|
32 | </tr> | |
31 | % endfor |
|
33 | % endfor | |
32 | </table> |
|
34 | </table> | |
33 | <div class="pagination-wh pagination-left"> |
|
35 | <div class="pagination-wh pagination-left"> | |
34 | <script type="text/javascript"> |
|
36 | <script type="text/javascript"> | |
35 | $(document).pjax('#forks .pager_link','#forks'); |
|
37 | $(document).pjax('#forks .pager_link','#forks'); | |
36 | $(document).on('pjax:success',function(){ |
|
38 | $(document).on('pjax:success',function(){ | |
37 | show_more_event(); |
|
39 | show_more_event(); | |
38 | timeagoActivate(); |
|
40 | timeagoActivate(); | |
39 | tooltip_activate(); |
|
41 | tooltip_activate(); | |
40 | show_changeset_tooltip(); |
|
42 | show_changeset_tooltip(); | |
41 | }); |
|
43 | }); | |
42 | </script> |
|
44 | </script> | |
43 | ${c.forks_pager.pager('$link_previous ~2~ $link_next')} |
|
45 | ${c.forks_pager.pager('$link_previous ~2~ $link_next')} | |
44 | </div> |
|
46 | </div> | |
45 | % else: |
|
47 | % else: | |
46 | ${_('There are no forks yet')} |
|
48 | ${_('There are no forks yet')} | |
47 | % endif |
|
49 | % endif |
@@ -1,568 +1,568 b'' | |||||
1 | <%inherit file="/base/base.html"/> |
|
1 | <%inherit file="/base/base.html"/> | |
2 |
|
2 | |||
3 | <%def name="title()"> |
|
3 | <%def name="title()"> | |
4 | ${_('%s Pull Request #%s') % (c.repo_name, c.pull_request.pull_request_id)} |
|
4 | ${_('%s Pull Request #%s') % (c.repo_name, c.pull_request.pull_request_id)} | |
5 | %if c.rhodecode_name: |
|
5 | %if c.rhodecode_name: | |
6 | · ${h.branding(c.rhodecode_name)} |
|
6 | · ${h.branding(c.rhodecode_name)} | |
7 | %endif |
|
7 | %endif | |
8 | </%def> |
|
8 | </%def> | |
9 |
|
9 | |||
10 | <%def name="breadcrumbs_links()"> |
|
10 | <%def name="breadcrumbs_links()"> | |
11 | <span id="pr-title"> |
|
11 | <span id="pr-title"> | |
12 | ${c.pull_request.title} |
|
12 | ${c.pull_request.title} | |
13 | %if c.pull_request.is_closed(): |
|
13 | %if c.pull_request.is_closed(): | |
14 | (${_('Closed')}) |
|
14 | (${_('Closed')}) | |
15 | %endif |
|
15 | %endif | |
16 | </span> |
|
16 | </span> | |
17 | <div id="pr-title-edit" class="input" style="display: none;"> |
|
17 | <div id="pr-title-edit" class="input" style="display: none;"> | |
18 | ${h.text('pullrequest_title', id_="pr-title-input", class_="large", value=c.pull_request.title)} |
|
18 | ${h.text('pullrequest_title', id_="pr-title-input", class_="large", value=c.pull_request.title)} | |
19 | </div> |
|
19 | </div> | |
20 | </%def> |
|
20 | </%def> | |
21 |
|
21 | |||
22 | <%def name="menu_bar_nav()"> |
|
22 | <%def name="menu_bar_nav()"> | |
23 | ${self.menu_items(active='repositories')} |
|
23 | ${self.menu_items(active='repositories')} | |
24 | </%def> |
|
24 | </%def> | |
25 |
|
25 | |||
26 | <%def name="menu_bar_subnav()"> |
|
26 | <%def name="menu_bar_subnav()"> | |
27 | ${self.repo_menu(active='showpullrequest')} |
|
27 | ${self.repo_menu(active='showpullrequest')} | |
28 | </%def> |
|
28 | </%def> | |
29 |
|
29 | |||
30 | <%def name="main()"> |
|
30 | <%def name="main()"> | |
31 | <script type="text/javascript"> |
|
31 | <script type="text/javascript"> | |
32 | // TODO: marcink switch this to pyroutes |
|
32 | // TODO: marcink switch this to pyroutes | |
33 | AJAX_COMMENT_DELETE_URL = "${url('pullrequest_comment_delete',repo_name=c.repo_name,comment_id='__COMMENT_ID__')}"; |
|
33 | AJAX_COMMENT_DELETE_URL = "${url('pullrequest_comment_delete',repo_name=c.repo_name,comment_id='__COMMENT_ID__')}"; | |
34 | templateContext.pull_request_data.pull_request_id = ${c.pull_request.pull_request_id}; |
|
34 | templateContext.pull_request_data.pull_request_id = ${c.pull_request.pull_request_id}; | |
35 | </script> |
|
35 | </script> | |
36 | <div class="box"> |
|
36 | <div class="box"> | |
37 | <div class="title"> |
|
37 | <div class="title"> | |
38 | ${self.repo_page_title(c.rhodecode_db_repo)} |
|
38 | ${self.repo_page_title(c.rhodecode_db_repo)} | |
39 | </div> |
|
39 | </div> | |
40 |
|
40 | |||
41 | ${self.breadcrumbs()} |
|
41 | ${self.breadcrumbs()} | |
42 |
|
42 | |||
43 |
|
43 | |||
44 | <div class="box pr-summary"> |
|
44 | <div class="box pr-summary"> | |
45 | <div class="summary-details block-left"> |
|
45 | <div class="summary-details block-left"> | |
46 | <%summary = lambda n:{False:'summary-short'}.get(n)%> |
|
46 | <%summary = lambda n:{False:'summary-short'}.get(n)%> | |
47 | <div class="pr-details-title"> |
|
47 | <div class="pr-details-title"> | |
48 | ${_('Pull request #%s') % c.pull_request.pull_request_id} ${_('From')} ${h.format_date(c.pull_request.created_on)} |
|
48 | ${_('Pull request #%s') % c.pull_request.pull_request_id} ${_('From')} ${h.format_date(c.pull_request.created_on)} | |
49 | %if c.allowed_to_update: |
|
49 | %if c.allowed_to_update: | |
50 | <span id="open_edit_pullrequest" class="block-right action_button">${_('Edit')}</span> |
|
50 | <span id="open_edit_pullrequest" class="block-right action_button">${_('Edit')}</span> | |
51 | <span id="close_edit_pullrequest" class="block-right action_button" style="display: none;">${_('Close')}</span> |
|
51 | <span id="close_edit_pullrequest" class="block-right action_button" style="display: none;">${_('Close')}</span> | |
52 | %endif |
|
52 | %endif | |
53 | </div> |
|
53 | </div> | |
54 |
|
54 | |||
55 | <div id="summary" class="fields pr-details-content"> |
|
55 | <div id="summary" class="fields pr-details-content"> | |
56 | <div class="field"> |
|
56 | <div class="field"> | |
57 | <div class="label-summary"> |
|
57 | <div class="label-summary"> | |
58 | <label>${_('Origin')}:</label> |
|
58 | <label>${_('Origin')}:</label> | |
59 | </div> |
|
59 | </div> | |
60 | <div class="input"> |
|
60 | <div class="input"> | |
61 | <div class="pr-origininfo"> |
|
61 | <div class="pr-origininfo"> | |
62 | ## branch link is only valid if it is a branch |
|
62 | ## branch link is only valid if it is a branch | |
63 | <span class="tag"> |
|
63 | <span class="tag"> | |
64 | %if c.pull_request.source_ref_parts.type == 'branch': |
|
64 | %if c.pull_request.source_ref_parts.type == 'branch': | |
65 | <a href="${h.url('changelog_home', repo_name=c.pull_request.source_repo.repo_name, branch=c.pull_request.source_ref_parts.name)}">${c.pull_request.source_ref_parts.type}: ${c.pull_request.source_ref_parts.name}</a> |
|
65 | <a href="${h.url('changelog_home', repo_name=c.pull_request.source_repo.repo_name, branch=c.pull_request.source_ref_parts.name)}">${c.pull_request.source_ref_parts.type}: ${c.pull_request.source_ref_parts.name}</a> | |
66 | %else: |
|
66 | %else: | |
67 | ${c.pull_request.source_ref_parts.type}: ${c.pull_request.source_ref_parts.name} |
|
67 | ${c.pull_request.source_ref_parts.type}: ${c.pull_request.source_ref_parts.name} | |
68 | %endif |
|
68 | %endif | |
69 | </span> |
|
69 | </span> | |
70 | <span class="clone-url"> |
|
70 | <span class="clone-url"> | |
71 | <a href="${h.url('summary_home', repo_name=c.pull_request.source_repo.repo_name)}">${c.pull_request.source_repo.clone_url()}</a> |
|
71 | <a href="${h.url('summary_home', repo_name=c.pull_request.source_repo.repo_name)}">${c.pull_request.source_repo.clone_url()}</a> | |
72 | </span> |
|
72 | </span> | |
73 | </div> |
|
73 | </div> | |
74 | <div class="pr-pullinfo"> |
|
74 | <div class="pr-pullinfo"> | |
75 | %if h.is_hg(c.pull_request.source_repo): |
|
75 | %if h.is_hg(c.pull_request.source_repo): | |
76 | <input type="text" value="hg pull -r ${h.short_id(c.source_ref)} ${c.pull_request.source_repo.clone_url()}" readonly="readonly"> |
|
76 | <input type="text" value="hg pull -r ${h.short_id(c.source_ref)} ${c.pull_request.source_repo.clone_url()}" readonly="readonly"> | |
77 | %elif h.is_git(c.pull_request.source_repo): |
|
77 | %elif h.is_git(c.pull_request.source_repo): | |
78 | <input type="text" value="git pull ${c.pull_request.source_repo.clone_url()} ${c.pull_request.source_ref_parts.name}" readonly="readonly"> |
|
78 | <input type="text" value="git pull ${c.pull_request.source_repo.clone_url()} ${c.pull_request.source_ref_parts.name}" readonly="readonly"> | |
79 | %endif |
|
79 | %endif | |
80 | </div> |
|
80 | </div> | |
81 | </div> |
|
81 | </div> | |
82 | </div> |
|
82 | </div> | |
83 | <div class="field"> |
|
83 | <div class="field"> | |
84 | <div class="label-summary"> |
|
84 | <div class="label-summary"> | |
85 | <label>${_('Target')}:</label> |
|
85 | <label>${_('Target')}:</label> | |
86 | </div> |
|
86 | </div> | |
87 | <div class="input"> |
|
87 | <div class="input"> | |
88 | <div class="pr-targetinfo"> |
|
88 | <div class="pr-targetinfo"> | |
89 | ## branch link is only valid if it is a branch |
|
89 | ## branch link is only valid if it is a branch | |
90 | <span class="tag"> |
|
90 | <span class="tag"> | |
91 | %if c.pull_request.target_ref_parts.type == 'branch': |
|
91 | %if c.pull_request.target_ref_parts.type == 'branch': | |
92 | <a href="${h.url('changelog_home', repo_name=c.pull_request.target_repo.repo_name, branch=c.pull_request.target_ref_parts.name)}">${c.pull_request.target_ref_parts.type}: ${c.pull_request.target_ref_parts.name}</a> |
|
92 | <a href="${h.url('changelog_home', repo_name=c.pull_request.target_repo.repo_name, branch=c.pull_request.target_ref_parts.name)}">${c.pull_request.target_ref_parts.type}: ${c.pull_request.target_ref_parts.name}</a> | |
93 | %else: |
|
93 | %else: | |
94 | ${c.pull_request.target_ref_parts.type}: ${c.pull_request.target_ref_parts.name} |
|
94 | ${c.pull_request.target_ref_parts.type}: ${c.pull_request.target_ref_parts.name} | |
95 | %endif |
|
95 | %endif | |
96 | </span> |
|
96 | </span> | |
97 | <span class="clone-url"> |
|
97 | <span class="clone-url"> | |
98 | <a href="${h.url('summary_home', repo_name=c.pull_request.target_repo.repo_name)}">${c.pull_request.target_repo.clone_url()}</a> |
|
98 | <a href="${h.url('summary_home', repo_name=c.pull_request.target_repo.repo_name)}">${c.pull_request.target_repo.clone_url()}</a> | |
99 | </span> |
|
99 | </span> | |
100 | </div> |
|
100 | </div> | |
101 | </div> |
|
101 | </div> | |
102 | </div> |
|
102 | </div> | |
103 | <div class="field"> |
|
103 | <div class="field"> | |
104 | <div class="label-summary"> |
|
104 | <div class="label-summary"> | |
105 | <label>${_('Review')}:</label> |
|
105 | <label>${_('Review')}:</label> | |
106 | </div> |
|
106 | </div> | |
107 | <div class="input"> |
|
107 | <div class="input"> | |
108 | %if c.pull_request_review_status: |
|
108 | %if c.pull_request_review_status: | |
109 | <div class="${'flag_status %s' % c.pull_request_review_status} tooltip pull-left"></div> |
|
109 | <div class="${'flag_status %s' % c.pull_request_review_status} tooltip pull-left"></div> | |
110 | <span class="changeset-status-lbl tooltip"> |
|
110 | <span class="changeset-status-lbl tooltip"> | |
111 | %if c.pull_request.is_closed(): |
|
111 | %if c.pull_request.is_closed(): | |
112 | ${_('Closed')}, |
|
112 | ${_('Closed')}, | |
113 | %endif |
|
113 | %endif | |
114 | ${h.commit_status_lbl(c.pull_request_review_status)} |
|
114 | ${h.commit_status_lbl(c.pull_request_review_status)} | |
115 | </span> |
|
115 | </span> | |
116 | - ${ungettext('calculated based on %s reviewer vote', 'calculated based on %s reviewers votes', len(c.pull_request_reviewers)) % len(c.pull_request_reviewers)} |
|
116 | - ${ungettext('calculated based on %s reviewer vote', 'calculated based on %s reviewers votes', len(c.pull_request_reviewers)) % len(c.pull_request_reviewers)} | |
117 | %endif |
|
117 | %endif | |
118 | </div> |
|
118 | </div> | |
119 | </div> |
|
119 | </div> | |
120 | <div class="field"> |
|
120 | <div class="field"> | |
121 | <div class="pr-description-label label-summary"> |
|
121 | <div class="pr-description-label label-summary"> | |
122 | <label>${_('Description')}:</label> |
|
122 | <label>${_('Description')}:</label> | |
123 | </div> |
|
123 | </div> | |
124 | <div id="pr-desc" class="input"> |
|
124 | <div id="pr-desc" class="input"> | |
125 | <div class="pr-description">${h.urlify_commit_message(c.pull_request.description, c.repo_name)}</div> |
|
125 | <div class="pr-description">${h.urlify_commit_message(c.pull_request.description, c.repo_name)}</div> | |
126 | </div> |
|
126 | </div> | |
127 | <div id="pr-desc-edit" class="input textarea editor" style="display: none;"> |
|
127 | <div id="pr-desc-edit" class="input textarea editor" style="display: none;"> | |
128 | <textarea id="pr-description-input" size="30">${c.pull_request.description}</textarea> |
|
128 | <textarea id="pr-description-input" size="30">${c.pull_request.description}</textarea> | |
129 | </div> |
|
129 | </div> | |
130 | </div> |
|
130 | </div> | |
131 | <div class="field"> |
|
131 | <div class="field"> | |
132 | <div class="label-summary"> |
|
132 | <div class="label-summary"> | |
133 | <label>${_('Comments')}:</label> |
|
133 | <label>${_('Comments')}:</label> | |
134 | </div> |
|
134 | </div> | |
135 | <div class="input"> |
|
135 | <div class="input"> | |
136 | <div> |
|
136 | <div> | |
137 | <div class="comments-number"> |
|
137 | <div class="comments-number"> | |
138 | %if c.comments: |
|
138 | %if c.comments: | |
139 | <a href="#comments">${ungettext("%d Pull request comment", "%d Pull request comments", len(c.comments)) % len(c.comments)}</a>, |
|
139 | <a href="#comments">${ungettext("%d Pull request comment", "%d Pull request comments", len(c.comments)) % len(c.comments)}</a>, | |
140 | %else: |
|
140 | %else: | |
141 | ${ungettext("%d Pull request comment", "%d Pull request comments", len(c.comments)) % len(c.comments)} |
|
141 | ${ungettext("%d Pull request comment", "%d Pull request comments", len(c.comments)) % len(c.comments)} | |
142 | %endif |
|
142 | %endif | |
143 | %if c.inline_cnt: |
|
143 | %if c.inline_cnt: | |
144 | ## this is replaced with a proper link to first comment via JS linkifyComments() func |
|
144 | ## this is replaced with a proper link to first comment via JS linkifyComments() func | |
145 | <a href="#inline-comments" id="inline-comments-counter">${ungettext("%d Inline Comment", "%d Inline Comments", c.inline_cnt) % c.inline_cnt}</a> |
|
145 | <a href="#inline-comments" id="inline-comments-counter">${ungettext("%d Inline Comment", "%d Inline Comments", c.inline_cnt) % c.inline_cnt}</a> | |
146 | %else: |
|
146 | %else: | |
147 | ${ungettext("%d Inline Comment", "%d Inline Comments", c.inline_cnt) % c.inline_cnt} |
|
147 | ${ungettext("%d Inline Comment", "%d Inline Comments", c.inline_cnt) % c.inline_cnt} | |
148 | %endif |
|
148 | %endif | |
149 |
|
149 | |||
150 | % if c.outdated_cnt: |
|
150 | % if c.outdated_cnt: | |
151 | ,${ungettext("%d Outdated Comment", "%d Outdated Comments", c.outdated_cnt) % c.outdated_cnt} <span id="show-outdated-comments" class="btn btn-link">${_('(Show)')}</span> |
|
151 | ,${ungettext("%d Outdated Comment", "%d Outdated Comments", c.outdated_cnt) % c.outdated_cnt} <span id="show-outdated-comments" class="btn btn-link">${_('(Show)')}</span> | |
152 | % endif |
|
152 | % endif | |
153 | </div> |
|
153 | </div> | |
154 | </div> |
|
154 | </div> | |
155 | </div> |
|
155 | </div> | |
156 | </div> |
|
156 | </div> | |
157 | <div id="pr-save" class="field" style="display: none;"> |
|
157 | <div id="pr-save" class="field" style="display: none;"> | |
158 | <div class="label-summary"></div> |
|
158 | <div class="label-summary"></div> | |
159 | <div class="input"> |
|
159 | <div class="input"> | |
160 | <span id="edit_pull_request" class="btn btn-small">${_('Save Changes')}</span> |
|
160 | <span id="edit_pull_request" class="btn btn-small">${_('Save Changes')}</span> | |
161 | </div> |
|
161 | </div> | |
162 | </div> |
|
162 | </div> | |
163 | </div> |
|
163 | </div> | |
164 | </div> |
|
164 | </div> | |
165 | <div> |
|
165 | <div> | |
166 | ## AUTHOR |
|
166 | ## AUTHOR | |
167 | <div class="reviewers-title block-right"> |
|
167 | <div class="reviewers-title block-right"> | |
168 | <div class="pr-details-title"> |
|
168 | <div class="pr-details-title"> | |
169 | ${_('Author')} |
|
169 | ${_('Author')} | |
170 | </div> |
|
170 | </div> | |
171 | </div> |
|
171 | </div> | |
172 | <div class="block-right pr-details-content reviewers"> |
|
172 | <div class="block-right pr-details-content reviewers"> | |
173 | <ul class="group_members"> |
|
173 | <ul class="group_members"> | |
174 | <li> |
|
174 | <li> | |
175 | ${self.gravatar_with_user(c.pull_request.author.email, 16)} |
|
175 | ${self.gravatar_with_user(c.pull_request.author.email, 16)} | |
176 | </li> |
|
176 | </li> | |
177 | </ul> |
|
177 | </ul> | |
178 | </div> |
|
178 | </div> | |
179 | ## REVIEWERS |
|
179 | ## REVIEWERS | |
180 | <div class="reviewers-title block-right"> |
|
180 | <div class="reviewers-title block-right"> | |
181 | <div class="pr-details-title"> |
|
181 | <div class="pr-details-title"> | |
182 | ${_('Pull request reviewers')} |
|
182 | ${_('Pull request reviewers')} | |
183 | %if c.allowed_to_update: |
|
183 | %if c.allowed_to_update: | |
184 | <span id="open_edit_reviewers" class="block-right action_button">${_('Edit')}</span> |
|
184 | <span id="open_edit_reviewers" class="block-right action_button">${_('Edit')}</span> | |
185 | <span id="close_edit_reviewers" class="block-right action_button" style="display: none;">${_('Close')}</span> |
|
185 | <span id="close_edit_reviewers" class="block-right action_button" style="display: none;">${_('Close')}</span> | |
186 | %endif |
|
186 | %endif | |
187 | </div> |
|
187 | </div> | |
188 | </div> |
|
188 | </div> | |
189 | <div id="reviewers" class="block-right pr-details-content reviewers"> |
|
189 | <div id="reviewers" class="block-right pr-details-content reviewers"> | |
190 | ## members goes here ! |
|
190 | ## members goes here ! | |
191 | <ul id="review_members" class="group_members"> |
|
191 | <ul id="review_members" class="group_members"> | |
192 | %for member,status in c.pull_request_reviewers: |
|
192 | %for member,status in c.pull_request_reviewers: | |
193 | <li id="reviewer_${member.user_id}"> |
|
193 | <li id="reviewer_${member.user_id}"> | |
194 | <div class="reviewers_member"> |
|
194 | <div class="reviewers_member"> | |
195 | <div class="reviewer_status tooltip" title="${h.tooltip(h.commit_status_lbl(status[0][1].status if status else 'not_reviewed'))}"> |
|
195 | <div class="reviewer_status tooltip" title="${h.tooltip(h.commit_status_lbl(status[0][1].status if status else 'not_reviewed'))}"> | |
196 | <div class="${'flag_status %s' % (status[0][1].status if status else 'not_reviewed')} pull-left reviewer_member_status"></div> |
|
196 | <div class="${'flag_status %s' % (status[0][1].status if status else 'not_reviewed')} pull-left reviewer_member_status"></div> | |
197 | </div> |
|
197 | </div> | |
198 |
< |
|
198 | <div id="reviewer_${member.user_id}_name" class="reviewer_name"> | |
199 | ${self.gravatar_with_user(member.email, 16)} |
|
199 | ${self.gravatar_with_user(member.email, 16)} <div class="reviewer">(${_('owner') if c.pull_request.user_id == member.user_id else _('reviewer')})</div> | |
200 | (${_('owner') if c.pull_request.user_id == member.user_id else _('reviewer')})</span> |
|
200 | </div> | |
201 | <input id="reviewer_${member.user_id}_input" type="hidden" value="${member.user_id}" name="review_members" /> |
|
201 | <input id="reviewer_${member.user_id}_input" type="hidden" value="${member.user_id}" name="review_members" /> | |
202 | %if c.allowed_to_update: |
|
202 | %if c.allowed_to_update: | |
203 | <div class="reviewer_member_remove action_button" onclick="removeReviewMember(${member.user_id}, true)" style="visibility: hidden;"> |
|
203 | <div class="reviewer_member_remove action_button" onclick="removeReviewMember(${member.user_id}, true)" style="visibility: hidden;"> | |
204 | <i class="icon-remove-sign" ></i> |
|
204 | <i class="icon-remove-sign" ></i> | |
205 | </div> |
|
205 | </div> | |
206 | %endif |
|
206 | %endif | |
207 | </div> |
|
207 | </div> | |
208 | </li> |
|
208 | </li> | |
209 | %endfor |
|
209 | %endfor | |
210 | </ul> |
|
210 | </ul> | |
211 | %if not c.pull_request.is_closed(): |
|
211 | %if not c.pull_request.is_closed(): | |
212 | <div id="add_reviewer_input" class='ac' style="display: none;"> |
|
212 | <div id="add_reviewer_input" class='ac' style="display: none;"> | |
213 | %if c.allowed_to_update: |
|
213 | %if c.allowed_to_update: | |
214 | <div class="reviewer_ac"> |
|
214 | <div class="reviewer_ac"> | |
215 | ${h.text('user', class_='ac-input', placeholder=_('Add reviewer'))} |
|
215 | ${h.text('user', class_='ac-input', placeholder=_('Add reviewer'))} | |
216 | <div id="reviewers_container"></div> |
|
216 | <div id="reviewers_container"></div> | |
217 | </div> |
|
217 | </div> | |
218 | <div> |
|
218 | <div> | |
219 | <span id="update_pull_request" class="btn btn-small">${_('Save Changes')}</span> |
|
219 | <span id="update_pull_request" class="btn btn-small">${_('Save Changes')}</span> | |
220 | </div> |
|
220 | </div> | |
221 | %endif |
|
221 | %endif | |
222 | </div> |
|
222 | </div> | |
223 | %endif |
|
223 | %endif | |
224 | </div> |
|
224 | </div> | |
225 | </div> |
|
225 | </div> | |
226 | </div> |
|
226 | </div> | |
227 | <div class="box"> |
|
227 | <div class="box"> | |
228 | ##DIFF |
|
228 | ##DIFF | |
229 | <div class="table" > |
|
229 | <div class="table" > | |
230 | <div id="changeset_compare_view_content"> |
|
230 | <div id="changeset_compare_view_content"> | |
231 | ##CS |
|
231 | ##CS | |
232 | % if c.missing_requirements: |
|
232 | % if c.missing_requirements: | |
233 | <div class="box"> |
|
233 | <div class="box"> | |
234 | <div class="alert alert-warning"> |
|
234 | <div class="alert alert-warning"> | |
235 | <div> |
|
235 | <div> | |
236 | <strong>${_('Missing requirements:')}</strong> |
|
236 | <strong>${_('Missing requirements:')}</strong> | |
237 | ${_('These commits cannot be displayed, because this repository uses the Mercurial largefiles extension, which was not enabled.')} |
|
237 | ${_('These commits cannot be displayed, because this repository uses the Mercurial largefiles extension, which was not enabled.')} | |
238 | </div> |
|
238 | </div> | |
239 | </div> |
|
239 | </div> | |
240 | </div> |
|
240 | </div> | |
241 | % elif c.missing_commits: |
|
241 | % elif c.missing_commits: | |
242 | <div class="box"> |
|
242 | <div class="box"> | |
243 | <div class="alert alert-warning"> |
|
243 | <div class="alert alert-warning"> | |
244 | <div> |
|
244 | <div> | |
245 | <strong>${_('Missing commits')}:</strong> |
|
245 | <strong>${_('Missing commits')}:</strong> | |
246 | ${_('This pull request cannot be displayed, because one or more commits no longer exist in the source repository.')} |
|
246 | ${_('This pull request cannot be displayed, because one or more commits no longer exist in the source repository.')} | |
247 | ${_('Please update this pull request, push the commits back into the source repository, or consider closing this pull request.')} |
|
247 | ${_('Please update this pull request, push the commits back into the source repository, or consider closing this pull request.')} | |
248 | </div> |
|
248 | </div> | |
249 | </div> |
|
249 | </div> | |
250 | </div> |
|
250 | </div> | |
251 | % endif |
|
251 | % endif | |
252 | <div class="compare_view_commits_title"> |
|
252 | <div class="compare_view_commits_title"> | |
253 | % if c.allowed_to_update and not c.pull_request.is_closed(): |
|
253 | % if c.allowed_to_update and not c.pull_request.is_closed(): | |
254 | <button id="update_commits" class="btn btn-small">${_('Update commits')}</button> |
|
254 | <button id="update_commits" class="btn btn-small">${_('Update commits')}</button> | |
255 | % endif |
|
255 | % endif | |
256 | % if len(c.commit_ranges): |
|
256 | % if len(c.commit_ranges): | |
257 | <h2>${ungettext('Compare View: %s commit','Compare View: %s commits', len(c.commit_ranges)) % len(c.commit_ranges)}</h2> |
|
257 | <h2>${ungettext('Compare View: %s commit','Compare View: %s commits', len(c.commit_ranges)) % len(c.commit_ranges)}</h2> | |
258 | % endif |
|
258 | % endif | |
259 | </div> |
|
259 | </div> | |
260 | % if not c.missing_commits: |
|
260 | % if not c.missing_commits: | |
261 | <%include file="/compare/compare_commits.html" /> |
|
261 | <%include file="/compare/compare_commits.html" /> | |
262 | ## FILES |
|
262 | ## FILES | |
263 | <div class="cs_files_title"> |
|
263 | <div class="cs_files_title"> | |
264 | <span class="cs_files_expand"> |
|
264 | <span class="cs_files_expand"> | |
265 | <span id="expand_all_files">${_('Expand All')}</span> | <span id="collapse_all_files">${_('Collapse All')}</span> |
|
265 | <span id="expand_all_files">${_('Expand All')}</span> | <span id="collapse_all_files">${_('Collapse All')}</span> | |
266 | </span> |
|
266 | </span> | |
267 | <h2> |
|
267 | <h2> | |
268 | ${diff_block.diff_summary_text(len(c.files), c.lines_added, c.lines_deleted, c.limited_diff)} |
|
268 | ${diff_block.diff_summary_text(len(c.files), c.lines_added, c.lines_deleted, c.limited_diff)} | |
269 | </h2> |
|
269 | </h2> | |
270 | </div> |
|
270 | </div> | |
271 | % endif |
|
271 | % endif | |
272 | <div class="cs_files"> |
|
272 | <div class="cs_files"> | |
273 | %if not c.files and not c.missing_commits: |
|
273 | %if not c.files and not c.missing_commits: | |
274 | <span class="empty_data">${_('No files')}</span> |
|
274 | <span class="empty_data">${_('No files')}</span> | |
275 | %endif |
|
275 | %endif | |
276 | <table class="compare_view_files"> |
|
276 | <table class="compare_view_files"> | |
277 | <%namespace name="diff_block" file="/changeset/diff_block.html"/> |
|
277 | <%namespace name="diff_block" file="/changeset/diff_block.html"/> | |
278 | %for FID, change, path, stats in c.files: |
|
278 | %for FID, change, path, stats in c.files: | |
279 | <tr class="cs_${change} collapse_file" fid="${FID}"> |
|
279 | <tr class="cs_${change} collapse_file" fid="${FID}"> | |
280 | <td class="cs_icon_td"> |
|
280 | <td class="cs_icon_td"> | |
281 | <span class="collapse_file_icon" fid="${FID}"></span> |
|
281 | <span class="collapse_file_icon" fid="${FID}"></span> | |
282 | </td> |
|
282 | </td> | |
283 | <td class="cs_icon_td"> |
|
283 | <td class="cs_icon_td"> | |
284 | <div class="flag_status not_reviewed hidden"></div> |
|
284 | <div class="flag_status not_reviewed hidden"></div> | |
285 | </td> |
|
285 | </td> | |
286 | <td class="cs_${change}" id="a_${FID}"> |
|
286 | <td class="cs_${change}" id="a_${FID}"> | |
287 | <div class="node"> |
|
287 | <div class="node"> | |
288 | <a href="#a_${FID}"> |
|
288 | <a href="#a_${FID}"> | |
289 | <i class="icon-file-${change.lower()}"></i> |
|
289 | <i class="icon-file-${change.lower()}"></i> | |
290 | ${h.safe_unicode(path)} |
|
290 | ${h.safe_unicode(path)} | |
291 | </a> |
|
291 | </a> | |
292 | </div> |
|
292 | </div> | |
293 | </td> |
|
293 | </td> | |
294 | <td> |
|
294 | <td> | |
295 | <div class="changes pull-right">${h.fancy_file_stats(stats)}</div> |
|
295 | <div class="changes pull-right">${h.fancy_file_stats(stats)}</div> | |
296 | <div class="comment-bubble pull-right" data-path="${path}"> |
|
296 | <div class="comment-bubble pull-right" data-path="${path}"> | |
297 | <i class="icon-comment"></i> |
|
297 | <i class="icon-comment"></i> | |
298 | </div> |
|
298 | </div> | |
299 | </td> |
|
299 | </td> | |
300 | </tr> |
|
300 | </tr> | |
301 | <tr fid="${FID}" id="diff_${FID}" class="diff_links"> |
|
301 | <tr fid="${FID}" id="diff_${FID}" class="diff_links"> | |
302 | <td></td> |
|
302 | <td></td> | |
303 | <td></td> |
|
303 | <td></td> | |
304 | <td class="cs_${change}"> |
|
304 | <td class="cs_${change}"> | |
305 | %if c.target_repo.repo_name == c.repo_name: |
|
305 | %if c.target_repo.repo_name == c.repo_name: | |
306 | ${diff_block.diff_menu(c.repo_name, h.safe_unicode(path), c.target_ref, c.source_ref, change)} |
|
306 | ${diff_block.diff_menu(c.repo_name, h.safe_unicode(path), c.target_ref, c.source_ref, change)} | |
307 | %else: |
|
307 | %else: | |
308 | ## this is slightly different case later, since the other repo can have this |
|
308 | ## this is slightly different case later, since the other repo can have this | |
309 | ## file in other state than the origin repo |
|
309 | ## file in other state than the origin repo | |
310 | ${diff_block.diff_menu(c.target_repo.repo_name, h.safe_unicode(path), c.target_ref, c.source_ref, change)} |
|
310 | ${diff_block.diff_menu(c.target_repo.repo_name, h.safe_unicode(path), c.target_ref, c.source_ref, change)} | |
311 | %endif |
|
311 | %endif | |
312 | </td> |
|
312 | </td> | |
313 | <td class="td-actions rc-form"> |
|
313 | <td class="td-actions rc-form"> | |
314 | </td> |
|
314 | </td> | |
315 | </tr> |
|
315 | </tr> | |
316 | <tr id="tr_${FID}"> |
|
316 | <tr id="tr_${FID}"> | |
317 | <td></td> |
|
317 | <td></td> | |
318 | <td></td> |
|
318 | <td></td> | |
319 | <td class="injected_diff" colspan="2"> |
|
319 | <td class="injected_diff" colspan="2"> | |
320 | ${diff_block.diff_block_simple([c.changes[FID]])} |
|
320 | ${diff_block.diff_block_simple([c.changes[FID]])} | |
321 | </td> |
|
321 | </td> | |
322 | </tr> |
|
322 | </tr> | |
323 |
|
323 | |||
324 | ## Loop through inline comments |
|
324 | ## Loop through inline comments | |
325 | % if c.outdated_comments.get(path,False): |
|
325 | % if c.outdated_comments.get(path,False): | |
326 | <tr class="outdated"> |
|
326 | <tr class="outdated"> | |
327 | <td></td> |
|
327 | <td></td> | |
328 | <td></td> |
|
328 | <td></td> | |
329 | <td colspan="2"> |
|
329 | <td colspan="2"> | |
330 | <p>${_('Outdated Inline Comments')}:</p> |
|
330 | <p>${_('Outdated Inline Comments')}:</p> | |
331 | </td> |
|
331 | </td> | |
332 | </tr> |
|
332 | </tr> | |
333 | <tr class="outdated"> |
|
333 | <tr class="outdated"> | |
334 | <td></td> |
|
334 | <td></td> | |
335 | <td></td> |
|
335 | <td></td> | |
336 | <td colspan="2" class="outdated_comment_block"> |
|
336 | <td colspan="2" class="outdated_comment_block"> | |
337 | % for line, comments in c.outdated_comments[path].iteritems(): |
|
337 | % for line, comments in c.outdated_comments[path].iteritems(): | |
338 | <div class="inline-comment-placeholder" path="${path}" target_id="${h.safeid(h.safe_unicode(path))}"> |
|
338 | <div class="inline-comment-placeholder" path="${path}" target_id="${h.safeid(h.safe_unicode(path))}"> | |
339 | % for co in comments: |
|
339 | % for co in comments: | |
340 | ${comment.comment_block_outdated(co)} |
|
340 | ${comment.comment_block_outdated(co)} | |
341 | % endfor |
|
341 | % endfor | |
342 | </div> |
|
342 | </div> | |
343 | % endfor |
|
343 | % endfor | |
344 | </td> |
|
344 | </td> | |
345 | </tr> |
|
345 | </tr> | |
346 | % endif |
|
346 | % endif | |
347 | %endfor |
|
347 | %endfor | |
348 | ## Loop through inline comments for deleted files |
|
348 | ## Loop through inline comments for deleted files | |
349 | %for path in c.deleted_files: |
|
349 | %for path in c.deleted_files: | |
350 | <tr class="outdated deleted"> |
|
350 | <tr class="outdated deleted"> | |
351 | <td></td> |
|
351 | <td></td> | |
352 | <td></td> |
|
352 | <td></td> | |
353 | <td>${path}</td> |
|
353 | <td>${path}</td> | |
354 | </tr> |
|
354 | </tr> | |
355 | <tr class="outdated deleted"> |
|
355 | <tr class="outdated deleted"> | |
356 | <td></td> |
|
356 | <td></td> | |
357 | <td></td> |
|
357 | <td></td> | |
358 | <td>(${_('Removed')})</td> |
|
358 | <td>(${_('Removed')})</td> | |
359 | </tr> |
|
359 | </tr> | |
360 | % if path in c.outdated_comments: |
|
360 | % if path in c.outdated_comments: | |
361 | <tr class="outdated deleted"> |
|
361 | <tr class="outdated deleted"> | |
362 | <td></td> |
|
362 | <td></td> | |
363 | <td></td> |
|
363 | <td></td> | |
364 | <td colspan="2"> |
|
364 | <td colspan="2"> | |
365 | <p>${_('Outdated Inline Comments')}:</p> |
|
365 | <p>${_('Outdated Inline Comments')}:</p> | |
366 | </td> |
|
366 | </td> | |
367 | </tr> |
|
367 | </tr> | |
368 | <tr class="outdated"> |
|
368 | <tr class="outdated"> | |
369 | <td></td> |
|
369 | <td></td> | |
370 | <td></td> |
|
370 | <td></td> | |
371 | <td colspan="2" class="outdated_comment_block"> |
|
371 | <td colspan="2" class="outdated_comment_block"> | |
372 | % for line, comments in c.outdated_comments[path].iteritems(): |
|
372 | % for line, comments in c.outdated_comments[path].iteritems(): | |
373 | <div class="inline-comment-placeholder" path="${path}" target_id="${h.safeid(h.safe_unicode(path))}"> |
|
373 | <div class="inline-comment-placeholder" path="${path}" target_id="${h.safeid(h.safe_unicode(path))}"> | |
374 | % for co in comments: |
|
374 | % for co in comments: | |
375 | ${comment.comment_block_outdated(co)} |
|
375 | ${comment.comment_block_outdated(co)} | |
376 | % endfor |
|
376 | % endfor | |
377 | </div> |
|
377 | </div> | |
378 | % endfor |
|
378 | % endfor | |
379 | </td> |
|
379 | </td> | |
380 | </tr> |
|
380 | </tr> | |
381 | % endif |
|
381 | % endif | |
382 | %endfor |
|
382 | %endfor | |
383 | </table> |
|
383 | </table> | |
384 | </div> |
|
384 | </div> | |
385 | % if c.limited_diff: |
|
385 | % if c.limited_diff: | |
386 | <h5>${_('Commit was too big and was cut off...')} <a href="${h.url.current(fulldiff=1, **request.GET.mixed())}" onclick="return confirm('${_("Showing a huge diff might take some time and resources")}')">${_('Show full diff')}</a></h5> |
|
386 | <h5>${_('Commit was too big and was cut off...')} <a href="${h.url.current(fulldiff=1, **request.GET.mixed())}" onclick="return confirm('${_("Showing a huge diff might take some time and resources")}')">${_('Show full diff')}</a></h5> | |
387 | % endif |
|
387 | % endif | |
388 | </div> |
|
388 | </div> | |
389 | </div> |
|
389 | </div> | |
390 |
|
390 | |||
391 | % if c.limited_diff: |
|
391 | % if c.limited_diff: | |
392 | <p>${_('Commit was too big and was cut off...')} <a href="${h.url.current(fulldiff=1, **request.GET.mixed())}" onclick="return confirm('${_("Showing a huge diff might take some time and resources")}')">${_('Show full diff')}</a></p> |
|
392 | <p>${_('Commit was too big and was cut off...')} <a href="${h.url.current(fulldiff=1, **request.GET.mixed())}" onclick="return confirm('${_("Showing a huge diff might take some time and resources")}')">${_('Show full diff')}</a></p> | |
393 | % endif |
|
393 | % endif | |
394 |
|
394 | |||
395 | ## template for inline comment form |
|
395 | ## template for inline comment form | |
396 | <%namespace name="comment" file="/changeset/changeset_file_comment.html"/> |
|
396 | <%namespace name="comment" file="/changeset/changeset_file_comment.html"/> | |
397 | ${comment.comment_inline_form()} |
|
397 | ${comment.comment_inline_form()} | |
398 |
|
398 | |||
399 | ## render comments and inlines |
|
399 | ## render comments and inlines | |
400 | ${comment.generate_comments(include_pull_request=True, is_pull_request=True)} |
|
400 | ${comment.generate_comments(include_pull_request=True, is_pull_request=True)} | |
401 |
|
401 | |||
402 | % if not c.pull_request.is_closed(): |
|
402 | % if not c.pull_request.is_closed(): | |
403 | ## main comment form and it status |
|
403 | ## main comment form and it status | |
404 | ${comment.comments(h.url('pullrequest_comment', repo_name=c.repo_name, |
|
404 | ${comment.comments(h.url('pullrequest_comment', repo_name=c.repo_name, | |
405 | pull_request_id=c.pull_request.pull_request_id), |
|
405 | pull_request_id=c.pull_request.pull_request_id), | |
406 | c.pull_request_review_status, |
|
406 | c.pull_request_review_status, | |
407 | is_pull_request=True, change_status=c.allowed_to_change_status)} |
|
407 | is_pull_request=True, change_status=c.allowed_to_change_status)} | |
408 | %endif |
|
408 | %endif | |
409 |
|
409 | |||
410 | <script type="text/javascript"> |
|
410 | <script type="text/javascript"> | |
411 | if (location.href.indexOf('#') != -1) { |
|
411 | if (location.href.indexOf('#') != -1) { | |
412 | var id = '#'+location.href.substring(location.href.indexOf('#') + 1).split('#'); |
|
412 | var id = '#'+location.href.substring(location.href.indexOf('#') + 1).split('#'); | |
413 | var line = $('html').find(id); |
|
413 | var line = $('html').find(id); | |
414 | offsetScroll(line, 70); |
|
414 | offsetScroll(line, 70); | |
415 | } |
|
415 | } | |
416 | $(function(){ |
|
416 | $(function(){ | |
417 | ReviewerAutoComplete('user'); |
|
417 | ReviewerAutoComplete('user'); | |
418 | // custom code mirror |
|
418 | // custom code mirror | |
419 | var codeMirrorInstance = initPullRequestsCodeMirror('#pr-description-input'); |
|
419 | var codeMirrorInstance = initPullRequestsCodeMirror('#pr-description-input'); | |
420 |
|
420 | |||
421 | var PRDetails = { |
|
421 | var PRDetails = { | |
422 | editButton: $('#open_edit_pullrequest'), |
|
422 | editButton: $('#open_edit_pullrequest'), | |
423 | closeButton: $('#close_edit_pullrequest'), |
|
423 | closeButton: $('#close_edit_pullrequest'), | |
424 | viewFields: $('#pr-desc, #pr-title'), |
|
424 | viewFields: $('#pr-desc, #pr-title'), | |
425 | editFields: $('#pr-desc-edit, #pr-title-edit, #pr-save'), |
|
425 | editFields: $('#pr-desc-edit, #pr-title-edit, #pr-save'), | |
426 |
|
426 | |||
427 | init: function() { |
|
427 | init: function() { | |
428 | var that = this; |
|
428 | var that = this; | |
429 | this.editButton.on('click', function(e) { that.edit(); }); |
|
429 | this.editButton.on('click', function(e) { that.edit(); }); | |
430 | this.closeButton.on('click', function(e) { that.view(); }); |
|
430 | this.closeButton.on('click', function(e) { that.view(); }); | |
431 | }, |
|
431 | }, | |
432 |
|
432 | |||
433 | edit: function(event) { |
|
433 | edit: function(event) { | |
434 | this.viewFields.hide(); |
|
434 | this.viewFields.hide(); | |
435 | this.editButton.hide(); |
|
435 | this.editButton.hide(); | |
436 | this.editFields.show(); |
|
436 | this.editFields.show(); | |
437 | codeMirrorInstance.refresh(); |
|
437 | codeMirrorInstance.refresh(); | |
438 | }, |
|
438 | }, | |
439 |
|
439 | |||
440 | view: function(event) { |
|
440 | view: function(event) { | |
441 | this.editFields.hide(); |
|
441 | this.editFields.hide(); | |
442 | this.closeButton.hide(); |
|
442 | this.closeButton.hide(); | |
443 | this.viewFields.show(); |
|
443 | this.viewFields.show(); | |
444 | } |
|
444 | } | |
445 | }; |
|
445 | }; | |
446 |
|
446 | |||
447 | var ReviewersPanel = { |
|
447 | var ReviewersPanel = { | |
448 | editButton: $('#open_edit_reviewers'), |
|
448 | editButton: $('#open_edit_reviewers'), | |
449 | closeButton: $('#close_edit_reviewers'), |
|
449 | closeButton: $('#close_edit_reviewers'), | |
450 | addButton: $('#add_reviewer_input'), |
|
450 | addButton: $('#add_reviewer_input'), | |
451 | removeButtons: $('.reviewer_member_remove'), |
|
451 | removeButtons: $('.reviewer_member_remove'), | |
452 |
|
452 | |||
453 | init: function() { |
|
453 | init: function() { | |
454 | var that = this; |
|
454 | var that = this; | |
455 | this.editButton.on('click', function(e) { that.edit(); }); |
|
455 | this.editButton.on('click', function(e) { that.edit(); }); | |
456 | this.closeButton.on('click', function(e) { that.close(); }); |
|
456 | this.closeButton.on('click', function(e) { that.close(); }); | |
457 | }, |
|
457 | }, | |
458 |
|
458 | |||
459 | edit: function(event) { |
|
459 | edit: function(event) { | |
460 | this.editButton.hide(); |
|
460 | this.editButton.hide(); | |
461 | this.closeButton.show(); |
|
461 | this.closeButton.show(); | |
462 | this.addButton.show(); |
|
462 | this.addButton.show(); | |
463 | this.removeButtons.css('visibility', 'visible'); |
|
463 | this.removeButtons.css('visibility', 'visible'); | |
464 | }, |
|
464 | }, | |
465 |
|
465 | |||
466 | close: function(event) { |
|
466 | close: function(event) { | |
467 | this.editButton.show(); |
|
467 | this.editButton.show(); | |
468 | this.closeButton.hide(); |
|
468 | this.closeButton.hide(); | |
469 | this.addButton.hide(); |
|
469 | this.addButton.hide(); | |
470 | this.removeButtons.css('visibility', 'hidden'); |
|
470 | this.removeButtons.css('visibility', 'hidden'); | |
471 | } |
|
471 | } | |
472 | }; |
|
472 | }; | |
473 |
|
473 | |||
474 | PRDetails.init(); |
|
474 | PRDetails.init(); | |
475 | ReviewersPanel.init(); |
|
475 | ReviewersPanel.init(); | |
476 |
|
476 | |||
477 | $('#show-outdated-comments').on('click', function(e){ |
|
477 | $('#show-outdated-comments').on('click', function(e){ | |
478 | var button = $(this); |
|
478 | var button = $(this); | |
479 | var outdated = $('.outdated'); |
|
479 | var outdated = $('.outdated'); | |
480 | if (button.html() === "(Show)") { |
|
480 | if (button.html() === "(Show)") { | |
481 | button.html("(Hide)"); |
|
481 | button.html("(Hide)"); | |
482 | outdated.show(); |
|
482 | outdated.show(); | |
483 | } else { |
|
483 | } else { | |
484 | button.html("(Show)"); |
|
484 | button.html("(Show)"); | |
485 | outdated.hide(); |
|
485 | outdated.hide(); | |
486 | } |
|
486 | } | |
487 | }); |
|
487 | }); | |
488 |
|
488 | |||
489 | $('.show-inline-comments').on('change', function(e){ |
|
489 | $('.show-inline-comments').on('change', function(e){ | |
490 | var show = 'none'; |
|
490 | var show = 'none'; | |
491 | var target = e.currentTarget; |
|
491 | var target = e.currentTarget; | |
492 | if(target.checked){ |
|
492 | if(target.checked){ | |
493 | show = '' |
|
493 | show = '' | |
494 | } |
|
494 | } | |
495 | var boxid = $(target).attr('id_for'); |
|
495 | var boxid = $(target).attr('id_for'); | |
496 | var comments = $('#{0} .inline-comments'.format(boxid)); |
|
496 | var comments = $('#{0} .inline-comments'.format(boxid)); | |
497 | var fn_display = function(idx){ |
|
497 | var fn_display = function(idx){ | |
498 | $(this).css('display', show); |
|
498 | $(this).css('display', show); | |
499 | }; |
|
499 | }; | |
500 | $(comments).each(fn_display); |
|
500 | $(comments).each(fn_display); | |
501 | var btns = $('#{0} .inline-comments-button'.format(boxid)); |
|
501 | var btns = $('#{0} .inline-comments-button'.format(boxid)); | |
502 | $(btns).each(fn_display); |
|
502 | $(btns).each(fn_display); | |
503 | }); |
|
503 | }); | |
504 |
|
504 | |||
505 | // inject comments into their proper positions |
|
505 | // inject comments into their proper positions | |
506 | var file_comments = $('.inline-comment-placeholder'); |
|
506 | var file_comments = $('.inline-comment-placeholder'); | |
507 | %if c.pull_request.is_closed(): |
|
507 | %if c.pull_request.is_closed(): | |
508 | renderInlineComments(file_comments, false); |
|
508 | renderInlineComments(file_comments, false); | |
509 | %else: |
|
509 | %else: | |
510 | renderInlineComments(file_comments, true); |
|
510 | renderInlineComments(file_comments, true); | |
511 | %endif |
|
511 | %endif | |
512 | var commentTotals = {}; |
|
512 | var commentTotals = {}; | |
513 | $.each(file_comments, function(i, comment) { |
|
513 | $.each(file_comments, function(i, comment) { | |
514 | var path = $(comment).attr('path'); |
|
514 | var path = $(comment).attr('path'); | |
515 | var comms = $(comment).children().length; |
|
515 | var comms = $(comment).children().length; | |
516 | if (path in commentTotals) { |
|
516 | if (path in commentTotals) { | |
517 | commentTotals[path] += comms; |
|
517 | commentTotals[path] += comms; | |
518 | } else { |
|
518 | } else { | |
519 | commentTotals[path] = comms; |
|
519 | commentTotals[path] = comms; | |
520 | } |
|
520 | } | |
521 | }); |
|
521 | }); | |
522 | $.each(commentTotals, function(path, total) { |
|
522 | $.each(commentTotals, function(path, total) { | |
523 | var elem = $('.comment-bubble[data-path="'+ path +'"]'); |
|
523 | var elem = $('.comment-bubble[data-path="'+ path +'"]'); | |
524 | elem.css('visibility', 'visible'); |
|
524 | elem.css('visibility', 'visible'); | |
525 | elem.html(elem.html() + ' ' + total ); |
|
525 | elem.html(elem.html() + ' ' + total ); | |
526 | }); |
|
526 | }); | |
527 |
|
527 | |||
528 | $('#merge_pull_request_form').submit(function() { |
|
528 | $('#merge_pull_request_form').submit(function() { | |
529 | if (!$('#merge_pull_request').attr('disabled')) { |
|
529 | if (!$('#merge_pull_request').attr('disabled')) { | |
530 | $('#merge_pull_request').attr('disabled', 'disabled'); |
|
530 | $('#merge_pull_request').attr('disabled', 'disabled'); | |
531 | } |
|
531 | } | |
532 | return true; |
|
532 | return true; | |
533 | }); |
|
533 | }); | |
534 |
|
534 | |||
535 | $('#edit_pull_request').on('click', function(e){ |
|
535 | $('#edit_pull_request').on('click', function(e){ | |
536 | var title = $('#pr-title-input').val(); |
|
536 | var title = $('#pr-title-input').val(); | |
537 | var description = codeMirrorInstance.getValue(); |
|
537 | var description = codeMirrorInstance.getValue(); | |
538 | editPullRequest( |
|
538 | editPullRequest( | |
539 | "${c.repo_name}", "${c.pull_request.pull_request_id}", |
|
539 | "${c.repo_name}", "${c.pull_request.pull_request_id}", | |
540 | title, description); |
|
540 | title, description); | |
541 | }); |
|
541 | }); | |
542 |
|
542 | |||
543 | $('#update_pull_request').on('click', function(e){ |
|
543 | $('#update_pull_request').on('click', function(e){ | |
544 | updateReviewers(undefined, "${c.repo_name}", "${c.pull_request.pull_request_id}"); |
|
544 | updateReviewers(undefined, "${c.repo_name}", "${c.pull_request.pull_request_id}"); | |
545 | }); |
|
545 | }); | |
546 |
|
546 | |||
547 | $('#update_commits').on('click', function(e){ |
|
547 | $('#update_commits').on('click', function(e){ | |
548 | var isDisabled = !$(e.currentTarget).attr('disabled'); |
|
548 | var isDisabled = !$(e.currentTarget).attr('disabled'); | |
549 | $(e.currentTarget).text(_TM['Updating...']); |
|
549 | $(e.currentTarget).text(_TM['Updating...']); | |
550 | $(e.currentTarget).attr('disabled', 'disabled'); |
|
550 | $(e.currentTarget).attr('disabled', 'disabled'); | |
551 | if(isDisabled){ |
|
551 | if(isDisabled){ | |
552 | updateCommits("${c.repo_name}", "${c.pull_request.pull_request_id}"); |
|
552 | updateCommits("${c.repo_name}", "${c.pull_request.pull_request_id}"); | |
553 | } |
|
553 | } | |
554 |
|
554 | |||
555 | }); |
|
555 | }); | |
556 | // fixing issue with caches on firefox |
|
556 | // fixing issue with caches on firefox | |
557 | $('#update_commits').removeAttr("disabled"); |
|
557 | $('#update_commits').removeAttr("disabled"); | |
558 |
|
558 | |||
559 | $('#close_pull_request').on('click', function(e){ |
|
559 | $('#close_pull_request').on('click', function(e){ | |
560 | closePullRequest("${c.repo_name}", "${c.pull_request.pull_request_id}"); |
|
560 | closePullRequest("${c.repo_name}", "${c.pull_request.pull_request_id}"); | |
561 | }); |
|
561 | }); | |
562 | }) |
|
562 | }) | |
563 | </script> |
|
563 | </script> | |
564 |
|
564 | |||
565 | </div> |
|
565 | </div> | |
566 | </div> |
|
566 | </div> | |
567 |
|
567 | |||
568 | </%def> |
|
568 | </%def> |
@@ -1,241 +1,243 b'' | |||||
1 | # -*- coding: utf-8 -*- |
|
1 | # -*- coding: utf-8 -*- | |
2 |
|
2 | |||
3 | # Import early to make sure things are patched up properly |
|
3 | # Import early to make sure things are patched up properly | |
4 | from setuptools import setup, find_packages |
|
4 | from setuptools import setup, find_packages | |
5 |
|
5 | |||
6 | import os |
|
6 | import os | |
7 | import sys |
|
7 | import sys | |
8 | import platform |
|
8 | import platform | |
9 |
|
9 | |||
10 | if sys.version_info < (2, 7): |
|
10 | if sys.version_info < (2, 7): | |
11 | raise Exception('RhodeCode requires Python 2.7 or later') |
|
11 | raise Exception('RhodeCode requires Python 2.7 or later') | |
12 |
|
12 | |||
13 |
|
13 | |||
14 | here = os.path.abspath(os.path.dirname(__file__)) |
|
14 | here = os.path.abspath(os.path.dirname(__file__)) | |
15 |
|
15 | |||
16 |
|
16 | |||
17 | def _get_meta_var(name, data, callback_handler=None): |
|
17 | def _get_meta_var(name, data, callback_handler=None): | |
18 | import re |
|
18 | import re | |
19 | matches = re.compile(r'(?:%s)\s*=\s*(.*)' % name).search(data) |
|
19 | matches = re.compile(r'(?:%s)\s*=\s*(.*)' % name).search(data) | |
20 | if matches: |
|
20 | if matches: | |
21 | if not callable(callback_handler): |
|
21 | if not callable(callback_handler): | |
22 | callback_handler = lambda v: v |
|
22 | callback_handler = lambda v: v | |
23 |
|
23 | |||
24 | return callback_handler(eval(matches.groups()[0])) |
|
24 | return callback_handler(eval(matches.groups()[0])) | |
25 |
|
25 | |||
26 | _meta = open(os.path.join(here, 'rhodecode', '__init__.py'), 'rb') |
|
26 | _meta = open(os.path.join(here, 'rhodecode', '__init__.py'), 'rb') | |
27 | _metadata = _meta.read() |
|
27 | _metadata = _meta.read() | |
28 | _meta.close() |
|
28 | _meta.close() | |
29 |
|
29 | |||
30 | callback = lambda V: ('.'.join(map(str, V[:3])) + '.'.join(V[3:])) |
|
30 | callback = lambda V: ('.'.join(map(str, V[:3])) + '.'.join(V[3:])) | |
31 | __version__ = open(os.path.join('rhodecode', 'VERSION')).read().strip() |
|
31 | __version__ = open(os.path.join('rhodecode', 'VERSION')).read().strip() | |
32 | __license__ = _get_meta_var('__license__', _metadata) |
|
32 | __license__ = _get_meta_var('__license__', _metadata) | |
33 | __author__ = _get_meta_var('__author__', _metadata) |
|
33 | __author__ = _get_meta_var('__author__', _metadata) | |
34 | __url__ = _get_meta_var('__url__', _metadata) |
|
34 | __url__ = _get_meta_var('__url__', _metadata) | |
35 | # defines current platform |
|
35 | # defines current platform | |
36 | __platform__ = platform.system() |
|
36 | __platform__ = platform.system() | |
37 |
|
37 | |||
38 | # Cygwin has different platform identifiers, but they all contain the |
|
38 | # Cygwin has different platform identifiers, but they all contain the | |
39 | # term "CYGWIN" |
|
39 | # term "CYGWIN" | |
40 | is_windows = __platform__ == 'Windows' or 'CYGWIN' in __platform__ |
|
40 | is_windows = __platform__ == 'Windows' or 'CYGWIN' in __platform__ | |
41 |
|
41 | |||
42 | requirements = [ |
|
42 | requirements = [ | |
43 | 'Babel', |
|
43 | 'Babel', | |
44 | 'Beaker', |
|
44 | 'Beaker', | |
45 | 'FormEncode', |
|
45 | 'FormEncode', | |
46 | 'Mako', |
|
46 | 'Mako', | |
47 | 'Markdown', |
|
47 | 'Markdown', | |
48 | 'MarkupSafe', |
|
48 | 'MarkupSafe', | |
49 | 'MySQL-python', |
|
49 | 'MySQL-python', | |
50 | 'Paste', |
|
50 | 'Paste', | |
51 | 'PasteDeploy', |
|
51 | 'PasteDeploy', | |
52 | 'PasteScript', |
|
52 | 'PasteScript', | |
53 | 'Pygments', |
|
53 | 'Pygments', | |
54 | 'Pylons', |
|
54 | 'Pylons', | |
55 | 'Pyro4', |
|
55 | 'Pyro4', | |
56 | 'Routes', |
|
56 | 'Routes', | |
57 | 'SQLAlchemy', |
|
57 | 'SQLAlchemy', | |
58 | 'Tempita', |
|
58 | 'Tempita', | |
59 | 'URLObject', |
|
59 | 'URLObject', | |
60 | 'WebError', |
|
60 | 'WebError', | |
61 | 'WebHelpers', |
|
61 | 'WebHelpers', | |
62 | 'WebHelpers2', |
|
62 | 'WebHelpers2', | |
63 | 'WebOb', |
|
63 | 'WebOb', | |
64 | 'WebTest', |
|
64 | 'WebTest', | |
65 | 'Whoosh', |
|
65 | 'Whoosh', | |
66 | 'alembic', |
|
66 | 'alembic', | |
67 | 'amqplib', |
|
67 | 'amqplib', | |
68 | 'anyjson', |
|
68 | 'anyjson', | |
69 | 'appenlight-client', |
|
69 | 'appenlight-client', | |
70 | 'authomatic', |
|
70 | 'authomatic', | |
71 | 'backport_ipaddress', |
|
71 | 'backport_ipaddress', | |
72 | 'celery', |
|
72 | 'celery', | |
73 | 'colander', |
|
73 | 'colander', | |
74 | 'decorator', |
|
74 | 'decorator', | |
75 | 'docutils', |
|
75 | 'docutils', | |
|
76 | 'gunicorn', | |||
76 | 'infrae.cache', |
|
77 | 'infrae.cache', | |
77 | 'ipython', |
|
78 | 'ipython', | |
78 | 'iso8601', |
|
79 | 'iso8601', | |
79 | 'kombu', |
|
80 | 'kombu', | |
80 | 'msgpack-python', |
|
81 | 'msgpack-python', | |
81 | 'packaging', |
|
82 | 'packaging', | |
82 | 'psycopg2', |
|
83 | 'psycopg2', | |
83 | 'pycrypto', |
|
84 | 'pycrypto', | |
84 | 'pycurl', |
|
85 | 'pycurl', | |
85 | 'pyparsing', |
|
86 | 'pyparsing', | |
86 | 'pyramid', |
|
87 | 'pyramid', | |
87 | 'pyramid-debugtoolbar', |
|
88 | 'pyramid-debugtoolbar', | |
88 | 'pyramid-mako', |
|
89 | 'pyramid-mako', | |
89 | 'pyramid-beaker', |
|
90 | 'pyramid-beaker', | |
90 | 'pysqlite', |
|
91 | 'pysqlite', | |
91 | 'python-dateutil', |
|
92 | 'python-dateutil', | |
92 | 'python-ldap', |
|
93 | 'python-ldap', | |
93 | 'python-memcached', |
|
94 | 'python-memcached', | |
94 | 'python-pam', |
|
95 | 'python-pam', | |
95 | 'recaptcha-client', |
|
96 | 'recaptcha-client', | |
96 | 'repoze.lru', |
|
97 | 'repoze.lru', | |
97 | 'requests', |
|
98 | 'requests', | |
98 | 'simplejson', |
|
99 | 'simplejson', | |
99 | 'waitress', |
|
100 | 'waitress', | |
100 | 'zope.cachedescriptors', |
|
101 | 'zope.cachedescriptors', | |
101 | ] |
|
102 | ] | |
102 |
|
103 | |||
103 | if is_windows: |
|
104 | if is_windows: | |
104 | pass |
|
105 | pass | |
105 | else: |
|
106 | else: | |
106 | requirements.append('psutil') |
|
107 | requirements.append('psutil') | |
107 | requirements.append('py-bcrypt') |
|
108 | requirements.append('py-bcrypt') | |
108 |
|
109 | |||
109 | test_requirements = [ |
|
110 | test_requirements = [ | |
110 | 'WebTest', |
|
111 | 'WebTest', | |
111 | 'configobj', |
|
112 | 'configobj', | |
112 | 'cssselect', |
|
113 | 'cssselect', | |
113 | 'flake8', |
|
114 | 'flake8', | |
114 | 'lxml', |
|
115 | 'lxml', | |
115 | 'mock', |
|
116 | 'mock', | |
116 | 'pytest', |
|
117 | 'pytest', | |
|
118 | 'pytest-cov', | |||
117 | 'pytest-runner', |
|
119 | 'pytest-runner', | |
118 | ] |
|
120 | ] | |
119 |
|
121 | |||
120 | setup_requirements = [ |
|
122 | setup_requirements = [ | |
121 | 'PasteScript', |
|
123 | 'PasteScript', | |
122 | 'pytest-runner', |
|
124 | 'pytest-runner', | |
123 | ] |
|
125 | ] | |
124 |
|
126 | |||
125 | dependency_links = [ |
|
127 | dependency_links = [ | |
126 | ] |
|
128 | ] | |
127 |
|
129 | |||
128 | classifiers = [ |
|
130 | classifiers = [ | |
129 | 'Development Status :: 6 - Mature', |
|
131 | 'Development Status :: 6 - Mature', | |
130 | 'Environment :: Web Environment', |
|
132 | 'Environment :: Web Environment', | |
131 | 'Framework :: Pylons', |
|
133 | 'Framework :: Pylons', | |
132 | 'Intended Audience :: Developers', |
|
134 | 'Intended Audience :: Developers', | |
133 | 'Operating System :: OS Independent', |
|
135 | 'Operating System :: OS Independent', | |
134 | 'Programming Language :: Python', |
|
136 | 'Programming Language :: Python', | |
135 | 'Programming Language :: Python :: 2.7', |
|
137 | 'Programming Language :: Python :: 2.7', | |
136 | ] |
|
138 | ] | |
137 |
|
139 | |||
138 |
|
140 | |||
139 | # additional files from project that goes somewhere in the filesystem |
|
141 | # additional files from project that goes somewhere in the filesystem | |
140 | # relative to sys.prefix |
|
142 | # relative to sys.prefix | |
141 | data_files = [] |
|
143 | data_files = [] | |
142 |
|
144 | |||
143 | # additional files that goes into package itself |
|
145 | # additional files that goes into package itself | |
144 | package_data = {'rhodecode': ['i18n/*/LC_MESSAGES/*.mo', ], } |
|
146 | package_data = {'rhodecode': ['i18n/*/LC_MESSAGES/*.mo', ], } | |
145 |
|
147 | |||
146 | description = ('RhodeCode is a fast and powerful management tool ' |
|
148 | description = ('RhodeCode is a fast and powerful management tool ' | |
147 | 'for Mercurial and GIT with a built in push/pull server, ' |
|
149 | 'for Mercurial and GIT with a built in push/pull server, ' | |
148 | 'full text search and code-review.') |
|
150 | 'full text search and code-review.') | |
149 |
|
151 | |||
150 | keywords = ' '.join([ |
|
152 | keywords = ' '.join([ | |
151 | 'rhodecode', 'rhodiumcode', 'mercurial', 'git', 'code review', |
|
153 | 'rhodecode', 'rhodiumcode', 'mercurial', 'git', 'code review', | |
152 | 'repo groups', 'ldap', 'repository management', 'hgweb replacement', |
|
154 | 'repo groups', 'ldap', 'repository management', 'hgweb replacement', | |
153 | 'hgwebdir', 'gitweb replacement', 'serving hgweb', |
|
155 | 'hgwebdir', 'gitweb replacement', 'serving hgweb', | |
154 | ]) |
|
156 | ]) | |
155 |
|
157 | |||
156 | # long description |
|
158 | # long description | |
157 | README_FILE = 'README.rst' |
|
159 | README_FILE = 'README.rst' | |
158 | CHANGELOG_FILE = 'CHANGES.rst' |
|
160 | CHANGELOG_FILE = 'CHANGES.rst' | |
159 | try: |
|
161 | try: | |
160 | long_description = open(README_FILE).read() + '\n\n' + \ |
|
162 | long_description = open(README_FILE).read() + '\n\n' + \ | |
161 | open(CHANGELOG_FILE).read() |
|
163 | open(CHANGELOG_FILE).read() | |
162 |
|
164 | |||
163 | except IOError, err: |
|
165 | except IOError, err: | |
164 | sys.stderr.write( |
|
166 | sys.stderr.write( | |
165 | '[WARNING] Cannot find file specified as long_description (%s)\n or ' |
|
167 | '[WARNING] Cannot find file specified as long_description (%s)\n or ' | |
166 | 'changelog (%s) skipping that file' % (README_FILE, CHANGELOG_FILE) |
|
168 | 'changelog (%s) skipping that file' % (README_FILE, CHANGELOG_FILE) | |
167 | ) |
|
169 | ) | |
168 | long_description = description |
|
170 | long_description = description | |
169 |
|
171 | |||
170 | # packages |
|
172 | # packages | |
171 | packages = find_packages() |
|
173 | packages = find_packages() | |
172 |
|
174 | |||
173 | paster_commands = [ |
|
175 | paster_commands = [ | |
174 | 'make-config=rhodecode.lib.paster_commands.make_config:Command', |
|
176 | 'make-config=rhodecode.lib.paster_commands.make_config:Command', | |
175 | 'setup-rhodecode=rhodecode.lib.paster_commands.setup_rhodecode:Command', |
|
177 | 'setup-rhodecode=rhodecode.lib.paster_commands.setup_rhodecode:Command', | |
176 | 'update-repoinfo=rhodecode.lib.paster_commands.update_repoinfo:Command', |
|
178 | 'update-repoinfo=rhodecode.lib.paster_commands.update_repoinfo:Command', | |
177 | 'cache-keys=rhodecode.lib.paster_commands.cache_keys:Command', |
|
179 | 'cache-keys=rhodecode.lib.paster_commands.cache_keys:Command', | |
178 | 'ishell=rhodecode.lib.paster_commands.ishell:Command', |
|
180 | 'ishell=rhodecode.lib.paster_commands.ishell:Command', | |
179 | 'upgrade-db=rhodecode.lib.dbmigrate:UpgradeDb', |
|
181 | 'upgrade-db=rhodecode.lib.dbmigrate:UpgradeDb', | |
180 | 'celeryd=rhodecode.lib.celerypylons.commands:CeleryDaemonCommand', |
|
182 | 'celeryd=rhodecode.lib.celerypylons.commands:CeleryDaemonCommand', | |
181 | ] |
|
183 | ] | |
182 |
|
184 | |||
183 | setup( |
|
185 | setup( | |
184 | name='rhodecode-enterprise-ce', |
|
186 | name='rhodecode-enterprise-ce', | |
185 | version=__version__, |
|
187 | version=__version__, | |
186 | description=description, |
|
188 | description=description, | |
187 | long_description=long_description, |
|
189 | long_description=long_description, | |
188 | keywords=keywords, |
|
190 | keywords=keywords, | |
189 | license=__license__, |
|
191 | license=__license__, | |
190 | author=__author__, |
|
192 | author=__author__, | |
191 | author_email='marcin@rhodecode.com', |
|
193 | author_email='marcin@rhodecode.com', | |
192 | dependency_links=dependency_links, |
|
194 | dependency_links=dependency_links, | |
193 | url=__url__, |
|
195 | url=__url__, | |
194 | install_requires=requirements, |
|
196 | install_requires=requirements, | |
195 | tests_require=test_requirements, |
|
197 | tests_require=test_requirements, | |
196 | classifiers=classifiers, |
|
198 | classifiers=classifiers, | |
197 | setup_requires=setup_requirements, |
|
199 | setup_requires=setup_requirements, | |
198 | data_files=data_files, |
|
200 | data_files=data_files, | |
199 | packages=packages, |
|
201 | packages=packages, | |
200 | include_package_data=True, |
|
202 | include_package_data=True, | |
201 | package_data=package_data, |
|
203 | package_data=package_data, | |
202 | message_extractors={ |
|
204 | message_extractors={ | |
203 | 'rhodecode': [ |
|
205 | 'rhodecode': [ | |
204 | ('**.py', 'python', None), |
|
206 | ('**.py', 'python', None), | |
205 | ('templates/**.mako', 'mako', {'input_encoding': 'utf-8'}), |
|
207 | ('templates/**.mako', 'mako', {'input_encoding': 'utf-8'}), | |
206 | ('templates/**.html', 'mako', {'input_encoding': 'utf-8'}), |
|
208 | ('templates/**.html', 'mako', {'input_encoding': 'utf-8'}), | |
207 | ('public/**', 'ignore', None), |
|
209 | ('public/**', 'ignore', None), | |
208 | ] |
|
210 | ] | |
209 | }, |
|
211 | }, | |
210 | zip_safe=False, |
|
212 | zip_safe=False, | |
211 | paster_plugins=['PasteScript', 'Pylons'], |
|
213 | paster_plugins=['PasteScript', 'Pylons'], | |
212 | entry_points={ |
|
214 | entry_points={ | |
213 | 'enterprise.plugins1': [ |
|
215 | 'enterprise.plugins1': [ | |
214 | 'crowd=rhodecode.authentication.plugins.auth_crowd:plugin_factory', |
|
216 | 'crowd=rhodecode.authentication.plugins.auth_crowd:plugin_factory', | |
215 | 'jasig_cas=rhodecode.authentication.plugins.auth_jasig_cas:plugin_factory', |
|
217 | 'jasig_cas=rhodecode.authentication.plugins.auth_jasig_cas:plugin_factory', | |
216 | 'ldap=rhodecode.authentication.plugins.auth_ldap:plugin_factory', |
|
218 | 'ldap=rhodecode.authentication.plugins.auth_ldap:plugin_factory', | |
217 | 'pam=rhodecode.authentication.plugins.auth_pam:plugin_factory', |
|
219 | 'pam=rhodecode.authentication.plugins.auth_pam:plugin_factory', | |
218 | 'rhodecode=rhodecode.authentication.plugins.auth_rhodecode:plugin_factory', |
|
220 | 'rhodecode=rhodecode.authentication.plugins.auth_rhodecode:plugin_factory', | |
219 | ], |
|
221 | ], | |
220 | 'paste.app_factory': [ |
|
222 | 'paste.app_factory': [ | |
221 | 'main=rhodecode.config.middleware:make_pyramid_app', |
|
223 | 'main=rhodecode.config.middleware:make_pyramid_app', | |
222 | 'pylons=rhodecode.config.middleware:make_app', |
|
224 | 'pylons=rhodecode.config.middleware:make_app', | |
223 | ], |
|
225 | ], | |
224 | 'paste.app_install': [ |
|
226 | 'paste.app_install': [ | |
225 | 'main=pylons.util:PylonsInstaller', |
|
227 | 'main=pylons.util:PylonsInstaller', | |
226 | 'pylons=pylons.util:PylonsInstaller', |
|
228 | 'pylons=pylons.util:PylonsInstaller', | |
227 | ], |
|
229 | ], | |
228 | 'paste.global_paster_command': paster_commands, |
|
230 | 'paste.global_paster_command': paster_commands, | |
229 | 'pytest11': [ |
|
231 | 'pytest11': [ | |
230 | 'pylons=rhodecode.tests.pylons_plugin', |
|
232 | 'pylons=rhodecode.tests.pylons_plugin', | |
231 | 'enterprise=rhodecode.tests.plugin', |
|
233 | 'enterprise=rhodecode.tests.plugin', | |
232 | ], |
|
234 | ], | |
233 | 'console_scripts': [ |
|
235 | 'console_scripts': [ | |
234 | 'rcserver=rhodecode.rcserver:main', |
|
236 | 'rcserver=rhodecode.rcserver:main', | |
235 | ], |
|
237 | ], | |
236 | 'beaker.backends': [ |
|
238 | 'beaker.backends': [ | |
237 | 'memorylru_base=rhodecode.lib.memory_lru_debug:MemoryLRUNamespaceManagerBase', |
|
239 | 'memorylru_base=rhodecode.lib.memory_lru_debug:MemoryLRUNamespaceManagerBase', | |
238 | 'memorylru_debug=rhodecode.lib.memory_lru_debug:MemoryLRUNamespaceManagerDebug' |
|
240 | 'memorylru_debug=rhodecode.lib.memory_lru_debug:MemoryLRUNamespaceManagerDebug' | |
239 | ] |
|
241 | ] | |
240 | }, |
|
242 | }, | |
241 | ) |
|
243 | ) |
General Comments 0
You need to be logged in to leave comments.
Login now