##// END OF EJS Templates
configs: refactor and updated for python3 migrations
super-admin -
r5060:bbd1552d default
parent child Browse files
Show More
@@ -1,1943 +1,1921 b''
1 [
1 [
2 {
2 {
3 "license": [
3 "license": [
4 {
4 {
5 "fullName": "Python Software Foundation License version 2",
5 "fullName": "Python Software Foundation License version 2",
6 "shortName": "psfl",
6 "shortName": "psfl",
7 "spdxId": "Python-2.0",
7 "spdxId": "Python-2.0",
8 "url": "http://spdx.org/licenses/Python-2.0.html"
8 "url": "http://spdx.org/licenses/Python-2.0.html"
9 },
9 },
10 {
10 {
11 "fullName": "Zope Public License 2.0",
11 "fullName": "Zope Public License 2.0",
12 "shortName": "zpl20",
12 "shortName": "zpl20",
13 "spdxId": "ZPL-2.0",
13 "spdxId": "ZPL-2.0",
14 "url": "http://spdx.org/licenses/ZPL-2.0.html"
14 "url": "http://spdx.org/licenses/ZPL-2.0.html"
15 }
15 }
16 ],
16 ],
17 "name": "python2.7-setuptools-38.4.0"
17 "name": "python2.7-setuptools-38.4.0"
18 },
18 },
19 {
19 {
20 "license": {
20 "license": {
21 "fullName": "Python Software Foundation License version 2",
21 "fullName": "Python Software Foundation License version 2",
22 "shortName": "psfl",
22 "shortName": "psfl",
23 "spdxId": "Python-2.0",
23 "spdxId": "Python-2.0",
24 "url": "http://spdx.org/licenses/Python-2.0.html"
24 "url": "http://spdx.org/licenses/Python-2.0.html"
25 },
25 },
26 "name": "python-2.7.15"
26 "name": "python-2.7.15"
27 },
27 },
28 {
28 {
29 "license": [
29 "license": [
30 {
30 {
31 "fullName": "MIT License",
31 "fullName": "MIT License",
32 "shortName": "mit",
32 "shortName": "mit",
33 "spdxId": "MIT",
33 "spdxId": "MIT",
34 "url": "http://spdx.org/licenses/MIT.html"
34 "url": "http://spdx.org/licenses/MIT.html"
35 }
35 }
36 ],
36 ],
37 "name": "python2.7-beautifulsoup4-4.6.3"
37 "name": "python2.7-beautifulsoup4-4.6.3"
38 },
38 },
39 {
39 {
40 "license": "UNKNOWN",
40 "license": "UNKNOWN",
41 "name": "python2.7-bootstrapped-pip-9.0.1"
41 "name": "python2.7-bootstrapped-pip-9.0.1"
42 },
42 },
43 {
43 {
44 "license": [
44 "license": [
45 {
45 {
46 "fullName": "MIT License",
46 "fullName": "MIT License",
47 "shortName": "mit",
47 "shortName": "mit",
48 "spdxId": "MIT",
48 "spdxId": "MIT",
49 "url": "http://spdx.org/licenses/MIT.html"
49 "url": "http://spdx.org/licenses/MIT.html"
50 }
50 }
51 ],
51 ],
52 "name": "python2.7-webtest-2.0.33"
52 "name": "python2.7-webtest-2.0.33"
53 },
53 },
54 {
54 {
55 "license": [
55 "license": [
56 {
56 {
57 "fullName": "Zope Public License 2.1",
57 "fullName": "Zope Public License 2.1",
58 "shortName": "zpl21",
58 "shortName": "zpl21",
59 "spdxId": "ZPL-2.1",
59 "spdxId": "ZPL-2.1",
60 "url": "http://spdx.org/licenses/ZPL-2.1.html"
60 "url": "http://spdx.org/licenses/ZPL-2.1.html"
61 }
61 }
62 ],
62 ],
63 "name": "python2.7-waitress-1.3.1"
63 "name": "python2.7-waitress-1.3.1"
64 },
64 },
65 {
65 {
66 "license": [
66 "license": [
67 {
67 {
68 "fullName": "MIT License",
68 "fullName": "MIT License",
69 "shortName": "mit",
69 "shortName": "mit",
70 "spdxId": "MIT",
70 "spdxId": "MIT",
71 "url": "http://spdx.org/licenses/MIT.html"
71 "url": "http://spdx.org/licenses/MIT.html"
72 }
72 }
73 ],
73 ],
74 "name": "python2.7-webob-1.8.5"
74 "name": "python2.7-webob-1.8.5"
75 },
75 },
76 {
76 {
77 "license": [
77 "license": [
78 {
78 {
79 "fullName": "MIT License",
79 "fullName": "MIT License",
80 "shortName": "mit",
80 "shortName": "mit",
81 "spdxId": "MIT",
81 "spdxId": "MIT",
82 "url": "http://spdx.org/licenses/MIT.html"
82 "url": "http://spdx.org/licenses/MIT.html"
83 }
83 }
84 ],
84 ],
85 "name": "python2.7-six-1.11.0"
85 "name": "python2.7-six-1.11.0"
86 },
86 },
87 {
87 {
88 "license": [
88 "license": [
89 {
89 {
90 "fullName": "Apache License 2.0",
90 "fullName": "Apache License 2.0",
91 "shortName": "asl20",
91 "shortName": "asl20",
92 "spdxId": "Apache-2.0",
92 "spdxId": "Apache-2.0",
93 "url": "http://spdx.org/licenses/Apache-2.0.html"
93 "url": "http://spdx.org/licenses/Apache-2.0.html"
94 }
94 }
95 ],
95 ],
96 "name": "python2.7-coverage-4.5.4"
96 "name": "python2.7-coverage-4.5.4"
97 },
97 },
98 {
98 {
99 "license": [
99 "license": [
100 {
100 {
101 "fullName": "MIT License",
101 "fullName": "MIT License",
102 "shortName": "mit",
102 "shortName": "mit",
103 "spdxId": "MIT",
103 "spdxId": "MIT",
104 "url": "http://spdx.org/licenses/MIT.html"
104 "url": "http://spdx.org/licenses/MIT.html"
105 }
105 }
106 ],
106 ],
107 "name": "python2.7-cov-core-1.15.0"
107 "name": "python2.7-cov-core-1.15.0"
108 },
108 },
109 {
109 {
110 "license": [
110 "license": [
111 {
111 {
112 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
112 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
113 "shortName": "bsdOriginal",
113 "shortName": "bsdOriginal",
114 "spdxId": "BSD-4-Clause",
114 "spdxId": "BSD-4-Clause",
115 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
115 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
116 },
116 },
117 {
117 {
118 "fullName": "OSI Approved :: BSD License"
118 "fullName": "OSI Approved :: BSD License"
119 }
119 }
120 ],
120 ],
121 "name": "python2.7-mock-3.0.5"
121 "name": "python2.7-mock-3.0.5"
122 },
122 },
123 {
123 {
124 "license": [
124 "license": [
125 {
125 {
126 "fullName": "ASL"
126 "fullName": "ASL"
127 },
127 },
128 {
128 {
129 "fullName": "Apache License 2.0",
129 "fullName": "Apache License 2.0",
130 "shortName": "asl20",
130 "shortName": "asl20",
131 "spdxId": "Apache-2.0",
131 "spdxId": "Apache-2.0",
132 "url": "http://spdx.org/licenses/Apache-2.0.html"
132 "url": "http://spdx.org/licenses/Apache-2.0.html"
133 }
133 }
134 ],
134 ],
135 "name": "python2.7-funcsigs-1.0.2"
135 "name": "python2.7-funcsigs-1.0.2"
136 },
136 },
137 {
137 {
138 "license": [
138 "license": [
139 {
139 {
140 "fullName": "GNU Lesser General Public License v3 or later (LGPLv3+)"
140 "fullName": "GNU Lesser General Public License v3 or later (LGPLv3+)"
141 },
141 },
142 {
142 {
143 "fullName": "LGPL"
143 "fullName": "LGPL"
144 }
144 }
145 ],
145 ],
146 "name": "python2.7-gprof2dot-2017.9.19"
146 "name": "python2.7-gprof2dot-2017.9.19"
147 },
147 },
148 {
148 {
149 "license": [
149 "license": [
150 {
150 {
151 "fullName": "MIT License",
151 "fullName": "MIT License",
152 "shortName": "mit",
152 "shortName": "mit",
153 "spdxId": "MIT",
153 "spdxId": "MIT",
154 "url": "http://spdx.org/licenses/MIT.html"
154 "url": "http://spdx.org/licenses/MIT.html"
155 },
155 },
156 {
156 {
157 "fullName": "DFSG approved"
157 "fullName": "DFSG approved"
158 }
158 }
159 ],
159 ],
160 "name": "python2.7-pytest-timeout-1.3.3"
160 "name": "python2.7-pytest-timeout-1.3.3"
161 },
161 },
162 {
162 {
163 "license": [
163 "license": [
164 {
164 {
165 "fullName": "MIT License",
165 "fullName": "MIT License",
166 "shortName": "mit",
166 "shortName": "mit",
167 "spdxId": "MIT",
167 "spdxId": "MIT",
168 "url": "http://spdx.org/licenses/MIT.html"
168 "url": "http://spdx.org/licenses/MIT.html"
169 }
169 }
170 ],
170 ],
171 "name": "python2.7-pytest-4.6.5"
171 "name": "python2.7-pytest-4.6.5"
172 },
172 },
173 {
173 {
174 "license": [
174 "license": [
175 {
175 {
176 "fullName": "MIT License",
176 "fullName": "MIT License",
177 "shortName": "mit",
177 "shortName": "mit",
178 "spdxId": "MIT",
178 "spdxId": "MIT",
179 "url": "http://spdx.org/licenses/MIT.html"
179 "url": "http://spdx.org/licenses/MIT.html"
180 }
180 }
181 ],
181 ],
182 "name": "python2.7-more-itertools-5.0.0"
182 "name": "python2.7-more-itertools-5.0.0"
183 },
183 },
184 {
184 {
185 "license": [
185 "license": [
186 {
186 {
187 "fullName": "MIT License",
188 "shortName": "mit",
189 "spdxId": "MIT",
190 "url": "http://spdx.org/licenses/MIT.html"
191 }
192 ],
193 "name": "python2.7-pathlib2-2.3.5"
194 },
195 {
196 "license": [
197 {
198 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
187 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
199 "shortName": "bsdOriginal",
188 "shortName": "bsdOriginal",
200 "spdxId": "BSD-4-Clause",
189 "spdxId": "BSD-4-Clause",
201 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
190 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
202 },
191 },
203 {
192 {
204 "fullName": "New BSD License"
193 "fullName": "New BSD License"
205 }
194 }
206 ],
195 ],
207 "name": "python2.7-scandir-1.10.0"
196 "name": "python2.7-scandir-1.10.0"
208 },
197 },
209 {
198 {
210 "license": [
199 "license": [
211 {
200 {
212 "fullName": "MIT License",
201 "fullName": "MIT License",
213 "shortName": "mit",
202 "shortName": "mit",
214 "spdxId": "MIT",
203 "spdxId": "MIT",
215 "url": "http://spdx.org/licenses/MIT.html"
204 "url": "http://spdx.org/licenses/MIT.html"
216 }
205 }
217 ],
206 ],
218 "name": "python2.7-wcwidth-0.1.7"
207 "name": "python2.7-wcwidth-0.1.7"
219 },
208 },
220 {
209 {
221 "license": [
210 "license": [
222 {
211 {
223 "fullName": "Apache License 2.0",
212 "fullName": "Apache License 2.0",
224 "shortName": "asl20",
213 "shortName": "asl20",
225 "spdxId": "Apache-2.0",
214 "spdxId": "Apache-2.0",
226 "url": "http://spdx.org/licenses/Apache-2.0.html"
215 "url": "http://spdx.org/licenses/Apache-2.0.html"
227 }
216 }
228 ],
217 ],
229 "name": "python2.7-importlib-metadata-0.23"
218 "name": "python2.7-importlib-metadata-0.23"
230 },
219 },
231 {
220 {
232 "license": [
221 "license": [
233 {
222 {
234 "fullName": "MIT License",
223 "fullName": "MIT License",
235 "shortName": "mit",
224 "shortName": "mit",
236 "spdxId": "MIT",
225 "spdxId": "MIT",
237 "url": "http://spdx.org/licenses/MIT.html"
226 "url": "http://spdx.org/licenses/MIT.html"
238 }
227 }
239 ],
228 ],
240 "name": "python2.7-configparser-4.0.2"
229 "name": "python2.7-configparser-4.0.2"
241 },
230 },
242 {
231 {
243 "license": [
232 "license": [
244 {
233 {
245 "fullName": "Python Software Foundation License version 2",
234 "fullName": "Python Software Foundation License version 2",
246 "shortName": "psfl",
235 "shortName": "psfl",
247 "spdxId": "Python-2.0",
236 "spdxId": "Python-2.0",
248 "url": "http://spdx.org/licenses/Python-2.0.html"
237 "url": "http://spdx.org/licenses/Python-2.0.html"
249 }
238 }
250 ],
239 ],
251 "name": "python2.7-contextlib2-0.6.0"
240 "name": "python2.7-contextlib2-0.6.0"
252 },
241 },
253 {
242 {
254 "license": [
243 "license": [
255 {
244 {
256 "fullName": "MIT License",
245 "fullName": "MIT License",
257 "shortName": "mit",
246 "shortName": "mit",
258 "spdxId": "MIT",
247 "spdxId": "MIT",
259 "url": "http://spdx.org/licenses/MIT.html"
248 "url": "http://spdx.org/licenses/MIT.html"
260 }
249 }
261 ],
250 ],
262 "name": "python2.7-zipp-0.6.0"
251 "name": "python2.7-zipp-0.6.0"
263 },
252 },
264 {
253 {
265 "license": [
254 "license": [
266 {
255 {
267 "fullName": "MIT License",
256 "fullName": "MIT License",
268 "shortName": "mit",
257 "shortName": "mit",
269 "spdxId": "MIT",
258 "spdxId": "MIT",
270 "url": "http://spdx.org/licenses/MIT.html"
259 "url": "http://spdx.org/licenses/MIT.html"
271 }
260 }
272 ],
261 ],
273 "name": "python2.7-pluggy-0.13.0"
262 "name": "python2.7-pluggy-0.13.0"
274 },
263 },
275 {
264 {
276 "license": [
265 "license": [
277 {
266 {
278 "fullName": "MIT License",
267 "fullName": "MIT License",
279 "shortName": "mit",
268 "shortName": "mit",
280 "spdxId": "MIT",
269 "spdxId": "MIT",
281 "url": "http://spdx.org/licenses/MIT.html"
270 "url": "http://spdx.org/licenses/MIT.html"
282 }
271 }
283 ],
272 ],
284 "name": "python2.7-atomicwrites-1.3.0"
273 "name": "python2.7-atomicwrites-1.3.0"
285 },
274 },
286 {
275 {
287 "license": [
276 "license": [
288 {
277 {
289 "fullName": "MIT License",
278 "fullName": "MIT License",
290 "shortName": "mit",
279 "shortName": "mit",
291 "spdxId": "MIT",
280 "spdxId": "MIT",
292 "url": "http://spdx.org/licenses/MIT.html"
281 "url": "http://spdx.org/licenses/MIT.html"
293 }
282 }
294 ],
283 ],
295 "name": "python2.7-attrs-19.1.0"
284 "name": "python2.7-attrs-19.1.0"
296 },
285 },
297 {
286 {
298 "license": [
287 "license": [
299 {
288 {
300 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
289 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
301 "shortName": "bsdOriginal",
290 "shortName": "bsdOriginal",
302 "spdxId": "BSD-4-Clause",
291 "spdxId": "BSD-4-Clause",
303 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
292 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
304 },
293 },
305 {
294 {
306 "fullName": "BSD or Apache License, Version 2.0"
295 "fullName": "BSD or Apache License, Version 2.0"
307 },
296 },
308 {
297 {
309 "fullName": "Apache License 2.0",
298 "fullName": "Apache License 2.0",
310 "shortName": "asl20",
299 "shortName": "asl20",
311 "spdxId": "Apache-2.0",
300 "spdxId": "Apache-2.0",
312 "url": "http://spdx.org/licenses/Apache-2.0.html"
301 "url": "http://spdx.org/licenses/Apache-2.0.html"
313 }
302 }
314 ],
303 ],
315 "name": "python2.7-packaging-19.2"
304 "name": "python2.7-packaging-19.2"
316 },
305 },
317 {
306 {
318 "license": [
307 "license": [
319 {
308 {
320 "fullName": "MIT License",
309 "fullName": "MIT License",
321 "shortName": "mit",
310 "shortName": "mit",
322 "spdxId": "MIT",
311 "spdxId": "MIT",
323 "url": "http://spdx.org/licenses/MIT.html"
312 "url": "http://spdx.org/licenses/MIT.html"
324 }
313 }
325 ],
314 ],
326 "name": "python2.7-pyparsing-2.4.2"
315 "name": "python2.7-pyparsing-2.4.2"
327 },
316 },
328 {
317 {
329 "license": [
318 "license": [
330 {
319 {
331 "fullName": "MIT License",
320 "fullName": "MIT License",
332 "shortName": "mit",
321 "shortName": "mit",
333 "spdxId": "MIT",
322 "spdxId": "MIT",
334 "url": "http://spdx.org/licenses/MIT.html"
323 "url": "http://spdx.org/licenses/MIT.html"
335 }
324 }
336 ],
325 ],
337 "name": "python2.7-py-1.8.0"
326 "name": "python2.7-py-1.8.0"
338 },
327 },
339 {
328 {
340 "license": [
329 "license": [
341 {
330 {
342 "fullName": "MIT License",
331 "fullName": "MIT License",
343 "shortName": "mit",
332 "shortName": "mit",
344 "spdxId": "MIT",
333 "spdxId": "MIT",
345 "url": "http://spdx.org/licenses/MIT.html"
334 "url": "http://spdx.org/licenses/MIT.html"
346 }
335 }
347 ],
336 ],
348 "name": "python2.7-pytest-profiling-1.7.0"
337 "name": "python2.7-pytest-profiling-1.7.0"
349 },
338 },
350 {
339 {
351 "license": [
340 "license": [
352 {
341 {
353 "fullName": "MIT License",
342 "fullName": "MIT License",
354 "shortName": "mit",
343 "shortName": "mit",
355 "spdxId": "MIT",
344 "spdxId": "MIT",
356 "url": "http://spdx.org/licenses/MIT.html"
345 "url": "http://spdx.org/licenses/MIT.html"
357 }
346 }
358 ],
347 ],
359 "name": "python2.7-pytest-runner-5.1"
348 "name": "python2.7-pytest-runner-5.1"
360 },
349 },
361 {
350 {
362 "license": [
351 "license": [
363 {
352 {
364 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
353 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
365 "shortName": "bsdOriginal",
354 "shortName": "bsdOriginal",
366 "spdxId": "BSD-4-Clause",
355 "spdxId": "BSD-4-Clause",
367 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
356 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
368 }
357 }
369 ],
358 ],
370 "name": "python2.7-pytest-sugar-0.9.2"
359 "name": "python2.7-pytest-sugar-0.9.2"
371 },
360 },
372 {
361 {
373 "license": [
362 "license": [
374 {
363 {
375 "fullName": "MIT License",
364 "fullName": "MIT License",
376 "shortName": "mit",
365 "shortName": "mit",
377 "spdxId": "MIT",
366 "spdxId": "MIT",
378 "url": "http://spdx.org/licenses/MIT.html"
367 "url": "http://spdx.org/licenses/MIT.html"
379 }
368 }
380 ],
369 ],
381 "name": "python2.7-termcolor-1.1.0"
370 "name": "python2.7-termcolor-1.1.0"
382 },
371 },
383 {
372 {
384 "license": [
373 "license": [
385 {
374 {
386 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
375 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
387 "shortName": "bsdOriginal",
376 "shortName": "bsdOriginal",
388 "spdxId": "BSD-4-Clause",
377 "spdxId": "BSD-4-Clause",
389 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
378 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
390 },
379 },
391 {
380 {
392 "fullName": "MIT License",
381 "fullName": "MIT License",
393 "shortName": "mit",
382 "shortName": "mit",
394 "spdxId": "MIT",
383 "spdxId": "MIT",
395 "url": "http://spdx.org/licenses/MIT.html"
384 "url": "http://spdx.org/licenses/MIT.html"
396 }
385 }
397 ],
386 ],
398 "name": "python2.7-pytest-cov-2.7.1"
387 "name": "python2.7-pytest-cov-2.7.1"
399 },
388 },
400 {
389 {
401 "license": [
390 "license": [
402 {
391 {
403 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
392 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
404 "shortName": "bsdOriginal",
393 "shortName": "bsdOriginal",
405 "spdxId": "BSD-4-Clause",
394 "spdxId": "BSD-4-Clause",
406 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
395 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
407 }
396 }
408 ],
397 ],
409 "name": "python2.7-appenlight-client-0.6.26"
398 "name": "python2.7-appenlight-client-0.6.26"
410 },
399 },
411 {
400 {
412 "license": [
401 "license": [
413 {
402 {
414 "fullName": "Apache License 2.0",
403 "fullName": "Apache License 2.0",
415 "shortName": "asl20",
404 "shortName": "asl20",
416 "spdxId": "Apache-2.0",
405 "spdxId": "Apache-2.0",
417 "url": "http://spdx.org/licenses/Apache-2.0.html"
406 "url": "http://spdx.org/licenses/Apache-2.0.html"
418 }
407 }
419 ],
408 ],
420 "name": "python2.7-requests-2.9.1"
409 "name": "python2.7-requests-2.9.1"
421 },
410 },
422 {
411 {
423 "license": [
412 "license": [
424 {
413 {
425 "fullName": "Apache 2.0 and Proprietary"
414 "fullName": "Apache 2.0 and Proprietary"
426 }
415 }
427 ],
416 ],
428 "name": "python2.7-rhodecode-tools-1.3.0"
417 "name": "python2.7-rhodecode-tools-1.3.0"
429 },
418 },
430 {
419 {
431 "license": [
420 "license": [
432 {
421 {
433 "fullName": "Apache License 2.0",
422 "fullName": "Apache License 2.0",
434 "shortName": "asl20",
423 "shortName": "asl20",
435 "spdxId": "Apache-2.0",
424 "spdxId": "Apache-2.0",
436 "url": "http://spdx.org/licenses/Apache-2.0.html"
425 "url": "http://spdx.org/licenses/Apache-2.0.html"
437 }
426 }
438 ],
427 ],
439 "name": "python2.7-elasticsearch1-dsl-0.0.12"
428 "name": "python2.7-elasticsearch1-dsl-0.0.12"
440 },
429 },
441 {
430 {
442 "license": [
431 "license": [
443 {
432 {
444 "fullName": "Apache License 2.0",
433 "fullName": "Apache License 2.0",
445 "shortName": "asl20",
434 "shortName": "asl20",
446 "spdxId": "Apache-2.0",
435 "spdxId": "Apache-2.0",
447 "url": "http://spdx.org/licenses/Apache-2.0.html"
436 "url": "http://spdx.org/licenses/Apache-2.0.html"
448 }
437 }
449 ],
438 ],
450 "name": "python2.7-elasticsearch1-1.10.0"
439 "name": "python2.7-elasticsearch1-1.10.0"
451 },
440 },
452 {
441 {
453 "license": [
442 "license": [
454 {
443 {
455 "fullName": "MIT License",
444 "fullName": "MIT License",
456 "shortName": "mit",
445 "shortName": "mit",
457 "spdxId": "MIT",
446 "spdxId": "MIT",
458 "url": "http://spdx.org/licenses/MIT.html"
447 "url": "http://spdx.org/licenses/MIT.html"
459 }
448 }
460 ],
449 ],
461 "name": "python2.7-urllib3-1.25.2"
450 "name": "python2.7-urllib3-1.25.2"
462 },
451 },
463 {
452 {
464 "license": [
453 "license": [
465 {
454 {
466 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
455 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
467 "shortName": "bsdOriginal",
456 "shortName": "bsdOriginal",
468 "spdxId": "BSD-4-Clause",
457 "spdxId": "BSD-4-Clause",
469 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
458 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
470 },
459 },
471 {
460 {
472 "fullName": "Apache License 2.0",
461 "fullName": "Apache License 2.0",
473 "shortName": "asl20",
462 "shortName": "asl20",
474 "spdxId": "Apache-2.0",
463 "spdxId": "Apache-2.0",
475 "url": "http://spdx.org/licenses/Apache-2.0.html"
464 "url": "http://spdx.org/licenses/Apache-2.0.html"
476 },
465 },
477 {
466 {
478 "fullName": "Dual License"
467 "fullName": "Dual License"
479 }
468 }
480 ],
469 ],
481 "name": "python2.7-python-dateutil-2.8.1"
470 "name": "python2.7-python-dateutil-2.8.1"
482 },
471 },
483 {
472 {
484 "license": [
473 "license": [
485 {
474 {
486 "fullName": "Apache License 2.0",
475 "fullName": "Apache License 2.0",
487 "shortName": "asl20",
476 "shortName": "asl20",
488 "spdxId": "Apache-2.0",
477 "spdxId": "Apache-2.0",
489 "url": "http://spdx.org/licenses/Apache-2.0.html"
478 "url": "http://spdx.org/licenses/Apache-2.0.html"
490 }
479 }
491 ],
480 ],
492 "name": "python2.7-elasticsearch2-2.5.1"
481 "name": "python2.7-elasticsearch2-2.5.1"
493 },
482 },
494 {
483 {
495 "license": [
484 "license": [
496 {
485 {
497 "fullName": "Apache License 2.0",
486 "fullName": "Apache License 2.0",
498 "shortName": "asl20",
487 "shortName": "asl20",
499 "spdxId": "Apache-2.0",
488 "spdxId": "Apache-2.0",
500 "url": "http://spdx.org/licenses/Apache-2.0.html"
489 "url": "http://spdx.org/licenses/Apache-2.0.html"
501 }
490 }
502 ],
491 ],
503 "name": "python2.7-elasticsearch-dsl-6.3.1"
492 "name": "python2.7-elasticsearch-dsl-6.3.1"
504 },
493 },
505 {
494 {
506 "license": [
495 "license": [
507 {
496 {
508 "fullName": "Python Software Foundation License version 2",
497 "fullName": "Python Software Foundation License version 2",
509 "shortName": "psfl",
498 "shortName": "psfl",
510 "spdxId": "Python-2.0",
499 "spdxId": "Python-2.0",
511 "url": "http://spdx.org/licenses/Python-2.0.html"
500 "url": "http://spdx.org/licenses/Python-2.0.html"
512 }
501 }
513 ],
502 ],
514 "name": "python2.7-ipaddress-1.0.23"
503 "name": "python2.7-ipaddress-1.0.23"
515 },
504 },
516 {
505 {
517 "license": [
506 "license": [
518 {
507 {
519 "fullName": "Apache License 2.0",
508 "fullName": "Apache License 2.0",
520 "shortName": "asl20",
509 "shortName": "asl20",
521 "spdxId": "Apache-2.0",
510 "spdxId": "Apache-2.0",
522 "url": "http://spdx.org/licenses/Apache-2.0.html"
511 "url": "http://spdx.org/licenses/Apache-2.0.html"
523 }
512 }
524 ],
513 ],
525 "name": "python2.7-elasticsearch-6.3.1"
514 "name": "python2.7-elasticsearch-6.3.1"
526 },
515 },
527 {
516 {
528 "license": [
517 "license": [
529 {
518 {
530 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
519 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
531 "shortName": "bsdOriginal",
520 "shortName": "bsdOriginal",
532 "spdxId": "BSD-4-Clause",
521 "spdxId": "BSD-4-Clause",
533 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
522 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
534 },
523 },
535 {
524 {
536 "fullName": "BSD 2-clause \"Simplified\" License",
525 "fullName": "BSD 2-clause \"Simplified\" License",
537 "shortName": "bsd2",
526 "shortName": "bsd2",
538 "spdxId": "BSD-2-Clause",
527 "spdxId": "BSD-2-Clause",
539 "url": "http://spdx.org/licenses/BSD-2-Clause.html"
528 "url": "http://spdx.org/licenses/BSD-2-Clause.html"
540 }
529 }
541 ],
530 ],
542 "name": "python2.7-whoosh-2.7.4"
531 "name": "python2.7-whoosh-2.7.4"
543 },
532 },
544 {
533 {
545 "license": [
534 "license": [
546 {
535 {
547 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
536 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
548 "shortName": "bsdOriginal",
537 "shortName": "bsdOriginal",
549 "spdxId": "BSD-4-Clause",
538 "spdxId": "BSD-4-Clause",
550 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
539 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
551 },
540 },
552 {
541 {
553 "fullName": "BSD 3-clause \"New\" or \"Revised\" License",
542 "fullName": "BSD 3-clause \"New\" or \"Revised\" License",
554 "shortName": "bsd3",
543 "shortName": "bsd3",
555 "spdxId": "BSD-3-Clause",
544 "spdxId": "BSD-3-Clause",
556 "url": "http://spdx.org/licenses/BSD-3-Clause.html"
545 "url": "http://spdx.org/licenses/BSD-3-Clause.html"
557 }
546 }
558 ],
547 ],
559 "name": "python2.7-markupsafe-1.1.1"
548 "name": "python2.7-markupsafe-1.1.1"
560 },
549 },
561 {
550 {
562 "license": [
551 "license": [
563 {
552 {
564 "fullName": "MIT License",
553 "fullName": "MIT License",
565 "shortName": "mit",
554 "shortName": "mit",
566 "spdxId": "MIT",
555 "spdxId": "MIT",
567 "url": "http://spdx.org/licenses/MIT.html"
556 "url": "http://spdx.org/licenses/MIT.html"
568 }
557 }
569 ],
558 ],
570 "name": "python2.7-mako-1.1.0"
559 "name": "python2.7-mako-1.1.0"
571 },
560 },
572 {
561 {
573 "license": [
562 "license": [
574 {
563 {
575 "fullName": "MIT License",
564 "fullName": "MIT License",
576 "shortName": "mit",
565 "shortName": "mit",
577 "spdxId": "MIT",
566 "spdxId": "MIT",
578 "url": "http://spdx.org/licenses/MIT.html"
567 "url": "http://spdx.org/licenses/MIT.html"
579 }
568 }
580 ],
569 ],
581 "name": "python2.7-future-0.14.3"
570 "name": "python2.7-future-0.14.3"
582 },
571 },
583 {
572 {
584 "license": [
573 "license": [
585 {
574 {
586 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
575 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
587 "shortName": "bsdOriginal",
576 "shortName": "bsdOriginal",
588 "spdxId": "BSD-4-Clause",
577 "spdxId": "BSD-4-Clause",
589 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
578 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
590 }
579 }
591 ],
580 ],
592 "name": "python2.7-click-7.0"
581 "name": "python2.7-click-7.0"
593 },
582 },
594 {
583 {
595 "license": [
584 "license": [
596 {
585 {
597 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
586 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
598 "shortName": "bsdOriginal",
587 "shortName": "bsdOriginal",
599 "spdxId": "BSD-4-Clause",
588 "spdxId": "BSD-4-Clause",
600 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
589 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
601 }
590 }
602 ],
591 ],
603 "name": "python2.7-ipython-5.1.0"
592 "name": "python2.7-ipython-5.1.0"
604 },
593 },
605 {
594 {
606 "license": [
595 "license": [
607 {
596 {
608 "fullName": "GNU General Public License v3 (GPLv3)"
597 "fullName": "GNU General Public License v3 (GPLv3)"
609 },
598 },
610 {
599 {
611 "fullName": "GNU General Public License v1.0 only",
600 "fullName": "GNU General Public License v1.0 only",
612 "shortName": "gpl1",
601 "shortName": "gpl1",
613 "spdxId": "GPL-1.0",
602 "spdxId": "GPL-1.0",
614 "url": "http://spdx.org/licenses/GPL-1.0.html"
603 "url": "http://spdx.org/licenses/GPL-1.0.html"
615 }
604 }
616 ],
605 ],
617 "name": "python2.7-gnureadline-6.3.8"
606 "name": "python2.7-gnureadline-6.3.8"
618 },
607 },
619 {
608 {
620 "license": [
609 "license": [
621 {
610 {
622 "fullName": "ISC License",
611 "fullName": "ISC License",
623 "shortName": "isc",
612 "shortName": "isc",
624 "spdxId": "ISC",
613 "spdxId": "ISC",
625 "url": "http://spdx.org/licenses/ISC.html"
614 "url": "http://spdx.org/licenses/ISC.html"
626 },
615 },
627 {
616 {
628 "fullName": "ISC License (ISCL)"
617 "fullName": "ISC License (ISCL)"
629 }
618 }
630 ],
619 ],
631 "name": "python2.7-pexpect-4.7.0"
620 "name": "python2.7-pexpect-4.7.0"
632 },
621 },
633 {
622 {
634 "license": [],
623 "license": [],
635 "name": "python2.7-ptyprocess-0.6.0"
624 "name": "python2.7-ptyprocess-0.6.0"
636 },
625 },
637 {
626 {
638 "license": [
627 "license": [
639 {
628 {
640 "fullName": "MIT License",
629 "fullName": "MIT License",
641 "shortName": "mit",
630 "shortName": "mit",
642 "spdxId": "MIT",
631 "spdxId": "MIT",
643 "url": "http://spdx.org/licenses/MIT.html"
632 "url": "http://spdx.org/licenses/MIT.html"
644 }
633 }
645 ],
634 ],
646 "name": "python2.7-backports.shutil-get-terminal-size-1.0.0"
635 "name": "python2.7-backports.shutil-get-terminal-size-1.0.0"
647 },
636 },
648 {
637 {
649 "license": [
638 "license": [
650 {
639 {
651 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
640 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
652 "shortName": "bsdOriginal",
641 "shortName": "bsdOriginal",
653 "spdxId": "BSD-4-Clause",
642 "spdxId": "BSD-4-Clause",
654 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
643 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
655 }
644 }
656 ],
645 ],
657 "name": "python2.7-pygments-2.4.2"
646 "name": "python2.7-pygments-2.4.2"
658 },
647 },
659 {
648 {
660 "license": [
649 "license": [
661 {
650 {
662 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
651 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
663 "shortName": "bsdOriginal",
652 "shortName": "bsdOriginal",
664 "spdxId": "BSD-4-Clause",
653 "spdxId": "BSD-4-Clause",
665 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
654 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
666 }
655 }
667 ],
656 ],
668 "name": "python2.7-prompt-toolkit-1.0.18"
657 "name": "python2.7-prompt-toolkit-1.0.18"
669 },
658 },
670 {
659 {
671 "license": [
660 "license": [
672 {
661 {
673 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
662 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
674 "shortName": "bsdOriginal",
663 "shortName": "bsdOriginal",
675 "spdxId": "BSD-4-Clause",
664 "spdxId": "BSD-4-Clause",
676 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
665 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
677 }
666 }
678 ],
667 ],
679 "name": "python2.7-traitlets-4.3.3"
668 "name": "python2.7-traitlets-4.3.3"
680 },
669 },
681 {
670 {
682 "license": [
671 "license": [
683 {
672 {
684 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
673 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
685 "shortName": "bsdOriginal",
674 "shortName": "bsdOriginal",
686 "spdxId": "BSD-4-Clause",
675 "spdxId": "BSD-4-Clause",
687 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
676 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
688 }
677 }
689 ],
678 ],
690 "name": "python2.7-enum34-1.1.6"
679 "name": "python2.7-enum34-1.1.6"
691 },
680 },
692 {
681 {
693 "license": [
682 "license": [
694 {
683 {
695 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
684 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
696 "shortName": "bsdOriginal",
685 "shortName": "bsdOriginal",
697 "spdxId": "BSD-4-Clause",
686 "spdxId": "BSD-4-Clause",
698 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
687 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
699 },
688 },
700 {
689 {
701 "fullName": "new BSD License"
690 "fullName": "new BSD License"
702 }
691 }
703 ],
692 ],
704 "name": "python2.7-decorator-4.1.2"
693 "name": "python2.7-decorator-4.1.2"
705 },
694 },
706 {
695 {
707 "license": [
696 "license": [
708 {
697 {
709 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
698 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
710 "shortName": "bsdOriginal",
699 "shortName": "bsdOriginal",
711 "spdxId": "BSD-4-Clause",
700 "spdxId": "BSD-4-Clause",
712 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
701 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
713 }
702 }
714 ],
703 ],
715 "name": "python2.7-ipython-genutils-0.2.0"
704 "name": "python2.7-ipython-genutils-0.2.0"
716 },
705 },
717 {
706 {
718 "license": [
707 "license": [
719 {
708 {
720 "fullName": "Zope Public License 2.1",
709 "fullName": "Zope Public License 2.1",
721 "shortName": "zpl21",
710 "shortName": "zpl21",
722 "spdxId": "ZPL-2.1",
711 "spdxId": "ZPL-2.1",
723 "url": "http://spdx.org/licenses/ZPL-2.1.html"
712 "url": "http://spdx.org/licenses/ZPL-2.1.html"
724 }
713 }
725 ],
714 ],
726 "name": "python2.7-simplegeneric-0.8.1"
715 "name": "python2.7-simplegeneric-0.8.1"
727 },
716 },
728 {
717 {
729 "license": [
718 "license": [
730 {
719 {
731 "fullName": "MIT License",
720 "fullName": "MIT License",
732 "shortName": "mit",
721 "shortName": "mit",
733 "spdxId": "MIT",
722 "spdxId": "MIT",
734 "url": "http://spdx.org/licenses/MIT.html"
723 "url": "http://spdx.org/licenses/MIT.html"
735 }
724 }
736 ],
725 ],
737 "name": "python2.7-pickleshare-0.7.5"
726 "name": "python2.7-pickleshare-0.7.5"
738 },
727 },
739 {
728 {
740 "license": [
729 "license": [
741 {
730 {
742 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
731 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
743 "shortName": "bsdOriginal",
732 "shortName": "bsdOriginal",
744 "spdxId": "BSD-4-Clause",
733 "spdxId": "BSD-4-Clause",
745 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
734 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
746 }
735 }
747 ],
736 ],
748 "name": "python2.7-ipdb-0.12"
737 "name": "python2.7-ipdb-0.12"
749 },
738 },
750 {
739 {
751 "license": [
740 "license": [
752 {
741 {
753 "fullName": "MIT License",
742 "fullName": "MIT License",
754 "shortName": "mit",
743 "shortName": "mit",
755 "spdxId": "MIT",
744 "spdxId": "MIT",
756 "url": "http://spdx.org/licenses/MIT.html"
745 "url": "http://spdx.org/licenses/MIT.html"
757 }
746 }
758 ],
747 ],
759 "name": "python2.7-gunicorn-19.9.0"
748 "name": "python2.7-gunicorn-19.9.0"
760 },
749 },
761 {
750 {
762 "license": [
751 "license": [
763 {
752 {
764 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
753 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
765 "shortName": "bsdOriginal",
754 "shortName": "bsdOriginal",
766 "spdxId": "BSD-4-Clause",
755 "spdxId": "BSD-4-Clause",
767 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
756 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
768 }
757 }
769 ],
758 ],
770 "name": "python2.7-futures-3.0.2"
759 "name": "python2.7-futures-3.0.2"
771 },
760 },
772 {
761 {
773 "license": [
762 "license": [
774 {
763 {
775 "fullName": "MIT License",
764 "fullName": "MIT License",
776 "shortName": "mit",
765 "shortName": "mit",
777 "spdxId": "MIT",
766 "spdxId": "MIT",
778 "url": "http://spdx.org/licenses/MIT.html"
767 "url": "http://spdx.org/licenses/MIT.html"
779 }
768 }
780 ],
769 ],
781 "name": "python2.7-greenlet-0.4.15"
770 "name": "python2.7-greenlet-0.4.15"
782 },
771 },
783 {
772 {
784 "license": [
773 "license": [
785 {
774 {
786 "fullName": "MIT License",
775 "fullName": "MIT License",
787 "shortName": "mit",
776 "shortName": "mit",
788 "spdxId": "MIT",
777 "spdxId": "MIT",
789 "url": "http://spdx.org/licenses/MIT.html"
778 "url": "http://spdx.org/licenses/MIT.html"
790 }
779 }
791 ],
780 ],
792 "name": "python2.7-gevent-1.4.0"
781 "name": "python2.7-gevent-1.4.0"
793 },
782 },
794 {
783 {
795 "license": [
784 "license": [
796 {
785 {
797 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
786 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
798 "shortName": "bsdOriginal",
787 "shortName": "bsdOriginal",
799 "spdxId": "BSD-4-Clause",
788 "spdxId": "BSD-4-Clause",
800 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
789 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
801 }
790 }
802 ],
791 ],
803 "name": "python2.7-psutil-5.6.5"
792 "name": "python2.7-psutil-5.6.5"
804 },
793 },
805 {
794 {
806 "license": [
795 "license": [
807 {
796 {
808 "fullName": "MIT License",
797 "fullName": "MIT License",
809 "shortName": "mit",
798 "shortName": "mit",
810 "spdxId": "MIT",
799 "spdxId": "MIT",
811 "url": "http://spdx.org/licenses/MIT.html"
800 "url": "http://spdx.org/licenses/MIT.html"
812 }
801 }
813 ],
802 ],
814 "name": "python2.7-bumpversion-0.5.3"
803 "name": "python2.7-bumpversion-0.5.3"
815 },
804 },
816 {
805 {
817 "license": [
806 "license": [
818 {
807 {
819 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
808 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
820 "shortName": "bsdOriginal",
809 "shortName": "bsdOriginal",
821 "spdxId": "BSD-4-Clause",
810 "spdxId": "BSD-4-Clause",
822 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
811 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
823 }
812 }
824 ],
813 ],
825 "name": "python2.7-invoke-0.13.0"
814 "name": "python2.7-invoke-0.13.0"
826 },
815 },
827 {
816 {
828 "license": [
817 "license": [
829 {
818 {
830 "fullName": "MIT License",
819 "fullName": "MIT License",
831 "shortName": "mit",
820 "shortName": "mit",
832 "spdxId": "MIT",
821 "spdxId": "MIT",
833 "url": "http://spdx.org/licenses/MIT.html"
822 "url": "http://spdx.org/licenses/MIT.html"
834 }
823 }
835 ],
824 ],
836 "name": "python2.7-alembic-1.3.1"
825 "name": "python2.7-alembic-1.3.1"
837 },
826 },
838 {
827 {
839 "license": {
828 "license": {
840 "fullName": "Apache License 2.0",
829 "fullName": "Apache License 2.0",
841 "shortName": "asl20",
830 "shortName": "asl20",
842 "spdxId": "Apache-2.0",
831 "spdxId": "Apache-2.0",
843 "url": "http://spdx.org/licenses/Apache-2.0.html"
832 "url": "http://spdx.org/licenses/Apache-2.0.html"
844 },
833 },
845 "name": "python2.7-python-editor-1.0.4"
834 "name": "python2.7-python-editor-1.0.4"
846 },
835 },
847 {
836 {
848 "license": [
837 "license": [
849 {
838 {
850 "fullName": "MIT License",
839 "fullName": "MIT License",
851 "shortName": "mit",
840 "shortName": "mit",
852 "spdxId": "MIT",
841 "spdxId": "MIT",
853 "url": "http://spdx.org/licenses/MIT.html"
842 "url": "http://spdx.org/licenses/MIT.html"
854 }
843 }
855 ],
844 ],
856 "name": "python2.7-sqlalchemy-1.3.11"
845 "name": "python2.7-sqlalchemy-1.3.11"
857 },
846 },
858 {
847 {
859 "license": [
848 "license": [
860 {
849 {
861 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
850 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
862 "shortName": "bsdOriginal",
851 "shortName": "bsdOriginal",
863 "spdxId": "BSD-4-Clause",
852 "spdxId": "BSD-4-Clause",
864 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
853 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
865 }
854 }
866 ],
855 ],
867 "name": "python2.7-jupyter-core-4.5.0"
856 "name": "python2.7-jupyter-core-4.5.0"
868 },
857 },
869 {
858 {
870 "license": [
859 "license": [
871 {
860 {
872 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
861 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
873 "shortName": "bsdOriginal",
862 "shortName": "bsdOriginal",
874 "spdxId": "BSD-4-Clause",
863 "spdxId": "BSD-4-Clause",
875 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
864 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
876 }
865 }
877 ],
866 ],
878 "name": "python2.7-jupyter-client-5.0.0"
867 "name": "python2.7-jupyter-client-5.0.0"
879 },
868 },
880 {
869 {
881 "license": [
870 "license": [
882 {
871 {
883 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
872 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
884 "shortName": "bsdOriginal",
873 "shortName": "bsdOriginal",
885 "spdxId": "BSD-4-Clause",
874 "spdxId": "BSD-4-Clause",
886 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
875 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
887 },
876 },
888 {
877 {
889 "fullName": "LGPL+BSD"
878 "fullName": "LGPL+BSD"
890 },
879 },
891 {
880 {
892 "fullName": "GNU Library or Lesser General Public License (LGPL)"
881 "fullName": "GNU Library or Lesser General Public License (LGPL)"
893 }
882 }
894 ],
883 ],
895 "name": "python2.7-pyzmq-14.6.0"
884 "name": "python2.7-pyzmq-14.6.0"
896 },
885 },
897 {
886 {
898 "license": [
887 "license": [
899 {
888 {
900 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
889 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
901 "shortName": "bsdOriginal",
890 "shortName": "bsdOriginal",
902 "spdxId": "BSD-4-Clause",
891 "spdxId": "BSD-4-Clause",
903 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
892 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
904 }
893 }
905 ],
894 ],
906 "name": "python2.7-nbformat-4.4.0"
895 "name": "python2.7-nbformat-4.4.0"
907 },
896 },
908 {
897 {
909 "license": [
898 "license": [
910 {
899 {
911 "fullName": "MIT License",
900 "fullName": "MIT License",
912 "shortName": "mit",
901 "shortName": "mit",
913 "spdxId": "MIT",
902 "spdxId": "MIT",
914 "url": "http://spdx.org/licenses/MIT.html"
903 "url": "http://spdx.org/licenses/MIT.html"
915 }
904 }
916 ],
905 ],
917 "name": "python2.7-jsonschema-2.6.0"
906 "name": "python2.7-jsonschema-2.6.0"
918 },
907 },
919 {
908 {
920 "license": [
909 "license": [
921 {
910 {
922 "fullName": "Python Software Foundation License version 2",
911 "fullName": "Python Software Foundation License version 2",
923 "shortName": "psfl",
912 "shortName": "psfl",
924 "spdxId": "Python-2.0",
913 "spdxId": "Python-2.0",
925 "url": "http://spdx.org/licenses/Python-2.0.html"
914 "url": "http://spdx.org/licenses/Python-2.0.html"
926 }
915 }
927 ],
916 ],
928 "name": "python2.7-functools32-3.2.3.post2"
917 "name": "python2.7-functools32-3.2.3.post2"
929 },
918 },
930 {
919 {
931 "license": [
920 "license": [
932 {
921 {
933 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
922 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
934 "shortName": "bsdOriginal",
923 "shortName": "bsdOriginal",
935 "spdxId": "BSD-4-Clause",
924 "spdxId": "BSD-4-Clause",
936 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
925 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
937 }
926 }
938 ],
927 ],
939 "name": "python2.7-nbconvert-5.3.1"
928 "name": "python2.7-nbconvert-5.3.1"
940 },
929 },
941 {
930 {
942 "license": [
931 "license": [
943 {
932 {
944 "fullName": "MIT License",
933 "fullName": "MIT License",
945 "shortName": "mit",
934 "shortName": "mit",
946 "spdxId": "MIT",
935 "spdxId": "MIT",
947 "url": "http://spdx.org/licenses/MIT.html"
936 "url": "http://spdx.org/licenses/MIT.html"
948 }
937 }
949 ],
938 ],
950 "name": "python2.7-testpath-0.4.4"
939 "name": "python2.7-testpath-0.4.4"
951 },
940 },
952 {
941 {
953 "license": [
942 "license": [
954 {
943 {
955 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
944 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
956 "shortName": "bsdOriginal",
945 "shortName": "bsdOriginal",
957 "spdxId": "BSD-4-Clause",
946 "spdxId": "BSD-4-Clause",
958 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
947 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
959 }
948 }
960 ],
949 ],
961 "name": "python2.7-pandocfilters-1.4.2"
950 "name": "python2.7-pandocfilters-1.4.2"
962 },
951 },
963 {
952 {
964 "license": [
953 "license": [
965 {
954 {
966 "fullName": "Apache License 2.0",
955 "fullName": "Apache License 2.0",
967 "shortName": "asl20",
956 "shortName": "asl20",
968 "spdxId": "Apache-2.0",
957 "spdxId": "Apache-2.0",
969 "url": "http://spdx.org/licenses/Apache-2.0.html"
958 "url": "http://spdx.org/licenses/Apache-2.0.html"
970 }
959 }
971 ],
960 ],
972 "name": "python2.7-bleach-3.1.0"
961 "name": "python2.7-bleach-3.1.0"
973 },
962 },
974 {
963 {
975 "license": [
964 "license": [
976 {
965 {
977 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
966 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
978 "shortName": "bsdOriginal",
967 "shortName": "bsdOriginal",
979 "spdxId": "BSD-4-Clause",
968 "spdxId": "BSD-4-Clause",
980 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
969 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
981 }
970 }
982 ],
971 ],
983 "name": "python2.7-webencodings-0.5.1"
972 "name": "python2.7-webencodings-0.5.1"
984 },
973 },
985 {
974 {
986 "license": [
975 "license": [
987 {
976 {
988 "fullName": "MIT License",
977 "fullName": "MIT License",
989 "shortName": "mit",
978 "shortName": "mit",
990 "spdxId": "MIT",
979 "spdxId": "MIT",
991 "url": "http://spdx.org/licenses/MIT.html"
980 "url": "http://spdx.org/licenses/MIT.html"
992 }
981 }
993 ],
982 ],
994 "name": "python2.7-entrypoints-0.2.2"
983 "name": "python2.7-entrypoints-0.2.2"
995 },
984 },
996 {
985 {
997 "license": [
986 "license": [
998 {
987 {
999 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
988 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1000 "shortName": "bsdOriginal",
989 "shortName": "bsdOriginal",
1001 "spdxId": "BSD-4-Clause",
990 "spdxId": "BSD-4-Clause",
1002 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
991 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1003 }
992 }
1004 ],
993 ],
1005 "name": "python2.7-jinja2-2.9.6"
994 "name": "python2.7-jinja2-2.9.6"
1006 },
995 },
1007 {
996 {
1008 "license": [
997 "license": [
1009 {
998 {
1010 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
999 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1011 "shortName": "bsdOriginal",
1000 "shortName": "bsdOriginal",
1012 "spdxId": "BSD-4-Clause",
1001 "spdxId": "BSD-4-Clause",
1013 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1002 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1014 }
1003 }
1015 ],
1004 ],
1016 "name": "python2.7-mistune-0.8.4"
1005 "name": "python2.7-mistune-0.8.4"
1017 },
1006 },
1018 {
1007 {
1019 "license": {
1008 "license": {
1020 "fullName": "GNU Lesser General Public License v3.0 or later",
1009 "fullName": "GNU Lesser General Public License v3.0 or later",
1021 "shortName": "lgpl3Plus",
1010 "shortName": "lgpl3Plus",
1022 "spdxId": "LGPL-3.0+",
1011 "spdxId": "LGPL-3.0+",
1023 "url": "http://spdx.org/licenses/LGPL-3.0+.html"
1012 "url": "http://spdx.org/licenses/LGPL-3.0+.html"
1024 },
1013 },
1025 "name": "python2.7-psycopg2-2.8.4"
1014 "name": "python2.7-psycopg2-2.8.4"
1026 },
1015 },
1027 {
1016 {
1028 "license": {
1017 "license": {
1029 "fullName": "PostgreSQL License",
1018 "fullName": "PostgreSQL License",
1030 "shortName": "postgresql",
1019 "shortName": "postgresql",
1031 "spdxId": "PostgreSQL",
1020 "spdxId": "PostgreSQL",
1032 "url": "http://spdx.org/licenses/PostgreSQL.html"
1021 "url": "http://spdx.org/licenses/PostgreSQL.html"
1033 },
1022 },
1034 "name": "postgresql-9.6.10"
1023 "name": "postgresql-9.6.10"
1035 },
1024 },
1036 {
1025 {
1037 "license": [
1026 "license": [
1038 {
1027 {
1039 "fullName": "zlib License",
1028 "fullName": "zlib License",
1040 "shortName": "zlib",
1029 "shortName": "zlib",
1041 "spdxId": "Zlib",
1030 "spdxId": "Zlib",
1042 "url": "http://spdx.org/licenses/Zlib.html"
1031 "url": "http://spdx.org/licenses/Zlib.html"
1043 },
1032 },
1044 {
1033 {
1045 "fullName": "libpng License",
1034 "fullName": "libpng License",
1046 "shortName": "libpng",
1035 "shortName": "libpng",
1047 "spdxId": "Libpng",
1036 "spdxId": "Libpng",
1048 "url": "http://spdx.org/licenses/Libpng.html"
1037 "url": "http://spdx.org/licenses/Libpng.html"
1049 }
1038 }
1050 ],
1039 ],
1051 "name": "python2.7-pysqlite-2.8.3"
1040 "name": "python2.7-pysqlite-2.8.3"
1052 },
1041 },
1053 {
1042 {
1054 "license": [
1043 "license": [
1055 {
1044 {
1056 "fullName": "MIT License",
1045 "fullName": "MIT License",
1057 "shortName": "mit",
1046 "shortName": "mit",
1058 "spdxId": "MIT",
1047 "spdxId": "MIT",
1059 "url": "http://spdx.org/licenses/MIT.html"
1048 "url": "http://spdx.org/licenses/MIT.html"
1060 }
1049 }
1061 ],
1050 ],
1062 "name": "python2.7-pymysql-0.8.1"
1051 "name": "python2.7-pymysql-0.8.1"
1063 },
1052 },
1064 {
1053 {
1065 "license": [
1054 "license": [
1066 {
1055 {
1067 "fullName": "GNU General Public License v1.0 only",
1056 "fullName": "GNU General Public License v1.0 only",
1068 "shortName": "gpl1",
1057 "shortName": "gpl1",
1069 "spdxId": "GPL-1.0",
1058 "spdxId": "GPL-1.0",
1070 "url": "http://spdx.org/licenses/GPL-1.0.html"
1059 "url": "http://spdx.org/licenses/GPL-1.0.html"
1071 }
1060 }
1072 ],
1061 ],
1073 "name": "python2.7-mysql-python-1.2.5"
1062 "name": "python2.7-mysql-python-1.2.5"
1074 },
1063 },
1075 {
1064 {
1076 "license": {
1065 "license": {
1077 "fullName": "GNU Library General Public License v2.1 only",
1066 "fullName": "GNU Library General Public License v2.1 only",
1078 "shortName": "lgpl21",
1067 "shortName": "lgpl21",
1079 "spdxId": "LGPL-2.1",
1068 "spdxId": "LGPL-2.1",
1080 "url": "http://spdx.org/licenses/LGPL-2.1.html"
1069 "url": "http://spdx.org/licenses/LGPL-2.1.html"
1081 },
1070 },
1082 "name": "mariadb-connector-c-2.3.4"
1071 "name": "mariadb-connector-c-2.3.4"
1083 },
1072 },
1084 {
1073 {
1085 "license": [
1074 "license": [
1086 {
1075 {
1087 "fullName": "Zope Public License 2.1",
1076 "fullName": "Zope Public License 2.1",
1088 "shortName": "zpl21",
1077 "shortName": "zpl21",
1089 "spdxId": "ZPL-2.1",
1078 "spdxId": "ZPL-2.1",
1090 "url": "http://spdx.org/licenses/ZPL-2.1.html"
1079 "url": "http://spdx.org/licenses/ZPL-2.1.html"
1091 }
1080 }
1092 ],
1081 ],
1093 "name": "python2.7-zope.interface-4.6.0"
1082 "name": "python2.7-zope.interface-4.6.0"
1094 },
1083 },
1095 {
1084 {
1096 "license": [
1085 "license": [
1097 {
1086 {
1098 "fullName": "Zope Public License 2.1",
1087 "fullName": "Zope Public License 2.1",
1099 "shortName": "zpl21",
1088 "shortName": "zpl21",
1100 "spdxId": "ZPL-2.1",
1089 "spdxId": "ZPL-2.1",
1101 "url": "http://spdx.org/licenses/ZPL-2.1.html"
1090 "url": "http://spdx.org/licenses/ZPL-2.1.html"
1102 }
1091 }
1103 ],
1092 ],
1104 "name": "python2.7-zope.event-4.4"
1093 "name": "python2.7-zope.event-4.4"
1105 },
1094 },
1106 {
1095 {
1107 "license": [
1096 "license": [
1108 {
1097 {
1109 "fullName": "Zope Public License 2.1",
1098 "fullName": "Zope Public License 2.1",
1110 "shortName": "zpl21",
1099 "shortName": "zpl21",
1111 "spdxId": "ZPL-2.1",
1100 "spdxId": "ZPL-2.1",
1112 "url": "http://spdx.org/licenses/ZPL-2.1.html"
1101 "url": "http://spdx.org/licenses/ZPL-2.1.html"
1113 }
1102 }
1114 ],
1103 ],
1115 "name": "python2.7-zope.deprecation-4.4.0"
1104 "name": "python2.7-zope.deprecation-4.4.0"
1116 },
1105 },
1117 {
1106 {
1118 "license": [
1107 "license": [
1119 {
1108 {
1120 "fullName": "Zope Public License 2.1",
1109 "fullName": "Zope Public License 2.1",
1121 "shortName": "zpl21",
1110 "shortName": "zpl21",
1122 "spdxId": "ZPL-2.1",
1111 "spdxId": "ZPL-2.1",
1123 "url": "http://spdx.org/licenses/ZPL-2.1.html"
1112 "url": "http://spdx.org/licenses/ZPL-2.1.html"
1124 }
1113 }
1125 ],
1114 ],
1126 "name": "python2.7-zope.cachedescriptors-4.3.1"
1115 "name": "python2.7-zope.cachedescriptors-4.3.1"
1127 },
1116 },
1128 {
1117 {
1129 "license": [
1118 "license": [
1130 {
1119 {
1131 "fullName": "PSF or ZPL"
1120 "fullName": "PSF or ZPL"
1132 }
1121 }
1133 ],
1122 ],
1134 "name": "python2.7-wsgiref-0.1.2"
1123 "name": "python2.7-wsgiref-0.1.2"
1135 },
1124 },
1136 {
1125 {
1137 "license": [
1126 "license": [
1138 {
1127 {
1139 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1128 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1140 "shortName": "bsdOriginal",
1129 "shortName": "bsdOriginal",
1141 "spdxId": "BSD-4-Clause",
1130 "spdxId": "BSD-4-Clause",
1142 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1131 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1143 }
1132 }
1144 ],
1133 ],
1145 "name": "python2.7-webhelpers-1.3"
1134 "name": "python2.7-webhelpers-1.3"
1146 },
1135 },
1147 {
1136 {
1148 "license": [
1137 "license": [
1149 {
1138 {
1150 "fullName": "MIT License",
1139 "fullName": "MIT License",
1151 "shortName": "mit",
1140 "shortName": "mit",
1152 "spdxId": "MIT",
1141 "spdxId": "MIT",
1153 "url": "http://spdx.org/licenses/MIT.html"
1142 "url": "http://spdx.org/licenses/MIT.html"
1154 }
1143 }
1155 ],
1144 ],
1156 "name": "python2.7-webhelpers2-2.0"
1145 "name": "python2.7-webhelpers2-2.0"
1157 },
1146 },
1158 {
1147 {
1159 "license": [
1148 "license": [
1160 {
1149 {
1161 "fullName": "MIT License",
1150 "fullName": "MIT License",
1162 "shortName": "mit",
1151 "shortName": "mit",
1163 "spdxId": "MIT",
1152 "spdxId": "MIT",
1164 "url": "http://spdx.org/licenses/MIT.html"
1153 "url": "http://spdx.org/licenses/MIT.html"
1165 }
1154 }
1166 ],
1155 ],
1167 "name": "python2.7-weberror-0.10.3"
1156 "name": "python2.7-weberror-0.10.3"
1168 },
1157 },
1169 {
1158 {
1170 "license": [
1159 "license": [
1171 {
1160 {
1172 "fullName": "MIT License",
1161 "fullName": "MIT License",
1173 "shortName": "mit",
1162 "shortName": "mit",
1174 "spdxId": "MIT",
1163 "spdxId": "MIT",
1175 "url": "http://spdx.org/licenses/MIT.html"
1164 "url": "http://spdx.org/licenses/MIT.html"
1176 }
1165 }
1177 ],
1166 ],
1178 "name": "python2.7-paste-3.2.1"
1167 "name": "python2.7-paste-3.2.1"
1179 },
1168 },
1180 {
1169 {
1181 "license": [
1170 "license": [
1182 {
1171 {
1183 "fullName": "MIT License",
1172 "fullName": "MIT License",
1184 "shortName": "mit",
1173 "shortName": "mit",
1185 "spdxId": "MIT",
1174 "spdxId": "MIT",
1186 "url": "http://spdx.org/licenses/MIT.html"
1175 "url": "http://spdx.org/licenses/MIT.html"
1187 }
1176 }
1188 ],
1177 ],
1189 "name": "python2.7-tempita-0.5.2"
1178 "name": "python2.7-tempita-0.5.2"
1190 },
1179 },
1191 {
1180 {
1192 "license": {
1181 "license": {
1193 "fullName": "Repoze License",
1182 "fullName": "Repoze License",
1194 "url": "http://www.repoze.org/LICENSE.txt"
1183 "url": "http://www.repoze.org/LICENSE.txt"
1195 },
1184 },
1196 "name": "python2.7-venusian-1.2.0"
1185 "name": "python2.7-venusian-1.2.0"
1197 },
1186 },
1198 {
1187 {
1199 "license": {
1188 "license": {
1200 "fullName": "The Unlicense",
1189 "fullName": "The Unlicense",
1201 "spdxId": "Unlicense",
1190 "spdxId": "Unlicense",
1202 "url": "http://unlicense.org/"
1191 "url": "http://unlicense.org/"
1203 },
1192 },
1204 "name": "python2.7-urlobject-2.4.3"
1193 "name": "python2.7-urlobject-2.4.3"
1205 },
1194 },
1206 {
1195 {
1207 "license": {
1196 "license": {
1208 "fullName": "Repoze License",
1197 "fullName": "Repoze License",
1209 "url": "http://www.repoze.org/LICENSE.txt"
1198 "url": "http://www.repoze.org/LICENSE.txt"
1210 },
1199 },
1211 "name": "python2.7-translationstring-1.3"
1200 "name": "python2.7-translationstring-1.3"
1212 },
1201 },
1213 {
1202 {
1214 "license": [
1203 "license": [
1215 {
1204 {
1216 "fullName": "BSD-derived (http://www.repoze.org/LICENSE.txt)"
1205 "fullName": "BSD-derived (http://www.repoze.org/LICENSE.txt)"
1217 }
1206 }
1218 ],
1207 ],
1219 "name": "python2.7-supervisor-4.1.0"
1208 "name": "python2.7-supervisor-4.1.0"
1220 },
1209 },
1221 {
1210 {
1222 "license": [
1211 "license": [
1223 {
1212 {
1224 "fullName": "Python Software Foundation License version 2",
1213 "fullName": "Python Software Foundation License version 2",
1225 "shortName": "psfl",
1214 "shortName": "psfl",
1226 "spdxId": "Python-2.0",
1215 "spdxId": "Python-2.0",
1227 "url": "http://spdx.org/licenses/Python-2.0.html"
1216 "url": "http://spdx.org/licenses/Python-2.0.html"
1228 }
1217 }
1229 ],
1218 ],
1230 "name": "python2.7-subprocess32-3.5.4"
1219 "name": "python2.7-subprocess32-3.5.4"
1231 },
1220 },
1232 {
1221 {
1233 "license": [
1222 "license": [
1234 {
1223 {
1235 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1224 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1236 "shortName": "bsdOriginal",
1225 "shortName": "bsdOriginal",
1237 "spdxId": "BSD-4-Clause",
1226 "spdxId": "BSD-4-Clause",
1238 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1227 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1239 }
1228 }
1240 ],
1229 ],
1241 "name": "python2.7-sshpubkeys-3.1.0"
1230 "name": "python2.7-sshpubkeys-3.1.0"
1242 },
1231 },
1243 {
1232 {
1244 "license": [
1233 "license": [
1245 {
1234 {
1246 "fullName": "MIT License",
1235 "fullName": "MIT License",
1247 "shortName": "mit",
1236 "shortName": "mit",
1248 "spdxId": "MIT",
1237 "spdxId": "MIT",
1249 "url": "http://spdx.org/licenses/MIT.html"
1238 "url": "http://spdx.org/licenses/MIT.html"
1250 }
1239 }
1251 ],
1240 ],
1252 "name": "python2.7-ecdsa-0.13.2"
1241 "name": "python2.7-ecdsa-0.13.2"
1253 },
1242 },
1254 {
1243 {
1255 "license": [
1244 "license": [
1256 {
1245 {
1257 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1246 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1258 "shortName": "bsdOriginal",
1247 "shortName": "bsdOriginal",
1259 "spdxId": "BSD-4-Clause",
1248 "spdxId": "BSD-4-Clause",
1260 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1249 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1261 },
1250 },
1262 {
1251 {
1263 "fullName": "BSD or Apache License, Version 2.0"
1252 "fullName": "BSD or Apache License, Version 2.0"
1264 },
1253 },
1265 {
1254 {
1266 "fullName": "Apache License 2.0",
1255 "fullName": "Apache License 2.0",
1267 "shortName": "asl20",
1256 "shortName": "asl20",
1268 "spdxId": "Apache-2.0",
1257 "spdxId": "Apache-2.0",
1269 "url": "http://spdx.org/licenses/Apache-2.0.html"
1258 "url": "http://spdx.org/licenses/Apache-2.0.html"
1270 }
1259 }
1271 ],
1260 ],
1272 "name": "python2.7-cryptography-2.6.1"
1261 "name": "python2.7-cryptography-2.6.1"
1273 },
1262 },
1274 {
1263 {
1275 "license": [
1264 "license": [
1276 {
1265 {
1277 "fullName": "MIT License",
1266 "fullName": "MIT License",
1278 "shortName": "mit",
1267 "shortName": "mit",
1279 "spdxId": "MIT",
1268 "spdxId": "MIT",
1280 "url": "http://spdx.org/licenses/MIT.html"
1269 "url": "http://spdx.org/licenses/MIT.html"
1281 }
1270 }
1282 ],
1271 ],
1283 "name": "python2.7-cffi-1.12.3"
1272 "name": "python2.7-cffi-1.12.3"
1284 },
1273 },
1285 {
1274 {
1286 "license": [
1275 "license": [
1287 {
1276 {
1288 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1277 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1289 "shortName": "bsdOriginal",
1278 "shortName": "bsdOriginal",
1290 "spdxId": "BSD-4-Clause",
1279 "spdxId": "BSD-4-Clause",
1291 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1280 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1292 }
1281 }
1293 ],
1282 ],
1294 "name": "python2.7-pycparser-2.19"
1283 "name": "python2.7-pycparser-2.19"
1295 },
1284 },
1296 {
1285 {
1297 "license": [
1286 "license": [
1298 {
1287 {
1299 "fullName": "MIT License",
1288 "fullName": "MIT License",
1300 "shortName": "mit",
1289 "shortName": "mit",
1301 "spdxId": "MIT",
1290 "spdxId": "MIT",
1302 "url": "http://spdx.org/licenses/MIT.html"
1291 "url": "http://spdx.org/licenses/MIT.html"
1303 }
1292 }
1304 ],
1293 ],
1305 "name": "python2.7-asn1crypto-0.24.0"
1294 "name": "python2.7-asn1crypto-0.24.0"
1306 },
1295 },
1307 {
1296 {
1308 "license": [
1297 "license": [
1309 {
1298 {
1310 "fullName": "Academic Free License (AFL)"
1299 "fullName": "Academic Free License (AFL)"
1311 },
1300 },
1312 {
1301 {
1313 "fullName": "MIT License",
1302 "fullName": "MIT License",
1314 "shortName": "mit",
1303 "shortName": "mit",
1315 "spdxId": "MIT",
1304 "spdxId": "MIT",
1316 "url": "http://spdx.org/licenses/MIT.html"
1305 "url": "http://spdx.org/licenses/MIT.html"
1317 }
1306 }
1318 ],
1307 ],
1319 "name": "python2.7-simplejson-3.16.0"
1308 "name": "python2.7-simplejson-3.16.0"
1320 },
1309 },
1321 {
1310 {
1322 "license": [
1311 "license": [
1323 {
1312 {
1324 "fullName": "MIT License",
1313 "fullName": "MIT License",
1325 "shortName": "mit",
1314 "shortName": "mit",
1326 "spdxId": "MIT",
1315 "spdxId": "MIT",
1327 "url": "http://spdx.org/licenses/MIT.html"
1316 "url": "http://spdx.org/licenses/MIT.html"
1328 }
1317 }
1329 ],
1318 ],
1330 "name": "python2.7-routes-2.4.1"
1319 "name": "python2.7-routes-2.4.1"
1331 },
1320 },
1332 {
1321 {
1333 "license": {
1322 "license": {
1334 "fullName": "Repoze License",
1323 "fullName": "Repoze License",
1335 "url": "http://www.repoze.org/LICENSE.txt"
1324 "url": "http://www.repoze.org/LICENSE.txt"
1336 },
1325 },
1337 "name": "python2.7-repoze.lru-0.7"
1326 "name": "python2.7-repoze.lru-0.7"
1338 },
1327 },
1339 {
1328 {
1340 "license": [
1329 "license": [
1341 {
1330 {
1342 "fullName": "MIT License",
1331 "fullName": "MIT License",
1343 "shortName": "mit",
1332 "shortName": "mit",
1344 "spdxId": "MIT",
1333 "spdxId": "MIT",
1345 "url": "http://spdx.org/licenses/MIT.html"
1334 "url": "http://spdx.org/licenses/MIT.html"
1346 }
1335 }
1347 ],
1336 ],
1348 "name": "python2.7-redis-3.3.11"
1337 "name": "python2.7-redis-3.3.11"
1349 },
1338 },
1350 {
1339 {
1351 "license": [
1340 "license": [
1352 {
1341 {
1353 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1342 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1354 "shortName": "bsdOriginal",
1343 "shortName": "bsdOriginal",
1355 "spdxId": "BSD-4-Clause",
1344 "spdxId": "BSD-4-Clause",
1356 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1345 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1357 }
1346 }
1358 ],
1347 ],
1359 "name": "python2.7-py-gfm-0.1.4"
1348 "name": "python2.7-py-gfm-0.1.4"
1360 },
1349 },
1361 {
1350 {
1362 "license": [
1351 "license": [
1363 {
1352 {
1364 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1353 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1365 "shortName": "bsdOriginal",
1354 "shortName": "bsdOriginal",
1366 "spdxId": "BSD-4-Clause",
1355 "spdxId": "BSD-4-Clause",
1367 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1356 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1368 }
1357 }
1369 ],
1358 ],
1370 "name": "python2.7-markdown-2.6.11"
1359 "name": "python2.7-markdown-2.6.11"
1371 },
1360 },
1372 {
1361 {
1373 "license": [
1362 "license": [
1374 {
1363 {
1375 "fullName": "MIT License",
1364 "fullName": "MIT License",
1376 "shortName": "mit",
1365 "shortName": "mit",
1377 "spdxId": "MIT",
1366 "spdxId": "MIT",
1378 "url": "http://spdx.org/licenses/MIT.html"
1367 "url": "http://spdx.org/licenses/MIT.html"
1379 }
1368 }
1380 ],
1369 ],
1381 "name": "python2.7-tzlocal-1.5.1"
1370 "name": "python2.7-tzlocal-1.5.1"
1382 },
1371 },
1383 {
1372 {
1384 "license": [
1373 "license": [
1385 {
1374 {
1386 "fullName": "MIT License",
1375 "fullName": "MIT License",
1387 "shortName": "mit",
1376 "shortName": "mit",
1388 "spdxId": "MIT",
1377 "spdxId": "MIT",
1389 "url": "http://spdx.org/licenses/MIT.html"
1378 "url": "http://spdx.org/licenses/MIT.html"
1390 }
1379 }
1391 ],
1380 ],
1392 "name": "python2.7-pytz-2019.2"
1381 "name": "python2.7-pytz-2019.2"
1393 },
1382 },
1394 {
1383 {
1395 "license": [
1384 "license": [
1396 {
1385 {
1397 "fullName": "MIT License",
1386 "fullName": "MIT License",
1398 "shortName": "mit",
1387 "shortName": "mit",
1399 "spdxId": "MIT",
1388 "spdxId": "MIT",
1400 "url": "http://spdx.org/licenses/MIT.html"
1389 "url": "http://spdx.org/licenses/MIT.html"
1401 }
1390 }
1402 ],
1391 ],
1403 "name": "python2.7-python-saml-2.4.2"
1392 "name": "python2.7-python-saml-2.4.2"
1404 },
1393 },
1405 {
1394 {
1406 "license": [
1395 "license": [
1407 {
1396 {
1408 "fullName": "Python Software Foundation License version 2",
1397 "fullName": "Python Software Foundation License version 2",
1409 "shortName": "psfl",
1398 "shortName": "psfl",
1410 "spdxId": "Python-2.0",
1399 "spdxId": "Python-2.0",
1411 "url": "http://spdx.org/licenses/Python-2.0.html"
1400 "url": "http://spdx.org/licenses/Python-2.0.html"
1412 }
1401 }
1413 ],
1402 ],
1414 "name": "python2.7-defusedxml-0.6.0"
1403 "name": "python2.7-defusedxml-0.6.0"
1415 },
1404 },
1416 {
1405 {
1417 "license": [
1406 "license": [
1418 {
1407 {
1419 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1408 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1420 "shortName": "bsdOriginal",
1409 "shortName": "bsdOriginal",
1421 "spdxId": "BSD-4-Clause",
1410 "spdxId": "BSD-4-Clause",
1422 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1411 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1423 }
1412 }
1424 ],
1413 ],
1425 "name": "python2.7-isodate-0.6.0"
1414 "name": "python2.7-isodate-0.6.0"
1426 },
1415 },
1427 {
1416 {
1428 "license": [
1417 "license": [
1429 {
1418 {
1430 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1419 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1431 "shortName": "bsdOriginal",
1420 "shortName": "bsdOriginal",
1432 "spdxId": "BSD-4-Clause",
1421 "spdxId": "BSD-4-Clause",
1433 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1422 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1434 }
1423 }
1435 ],
1424 ],
1436 "name": "python2.7-dm.xmlsec.binding-1.3.7"
1425 "name": "python2.7-dm.xmlsec.binding-1.3.7"
1437 },
1426 },
1438 {
1427 {
1439 "license": [
1428 "license": [
1440 {
1429 {
1441 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1430 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1442 "shortName": "bsdOriginal",
1431 "shortName": "bsdOriginal",
1443 "spdxId": "BSD-4-Clause",
1432 "spdxId": "BSD-4-Clause",
1444 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1433 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1445 }
1434 }
1446 ],
1435 ],
1447 "name": "python2.7-lxml-4.2.5"
1436 "name": "python2.7-lxml-4.2.5"
1448 },
1437 },
1449 {
1438 {
1450 "license": [
1439 "license": [
1451 {
1440 {
1452 "fullName": "MIT License",
1441 "fullName": "MIT License",
1453 "shortName": "mit",
1442 "shortName": "mit",
1454 "spdxId": "MIT",
1443 "spdxId": "MIT",
1455 "url": "http://spdx.org/licenses/MIT.html"
1444 "url": "http://spdx.org/licenses/MIT.html"
1456 }
1445 }
1457 ],
1446 ],
1458 "name": "python2.7-wheel-0.30.0"
1447 "name": "python2.7-wheel-0.30.0"
1459 },
1448 },
1460 {
1449 {
1461 "license": [
1450 "license": [
1462 {
1451 {
1463 "fullName": "License :: OSI Approved :: MIT License"
1452 "fullName": "License :: OSI Approved :: MIT License"
1464 },
1453 },
1465 {
1454 {
1466 "fullName": "MIT License",
1455 "fullName": "MIT License",
1467 "shortName": "mit",
1456 "shortName": "mit",
1468 "spdxId": "MIT",
1457 "spdxId": "MIT",
1469 "url": "http://spdx.org/licenses/MIT.html"
1458 "url": "http://spdx.org/licenses/MIT.html"
1470 }
1459 }
1471 ],
1460 ],
1472 "name": "python2.7-python-pam-1.8.4"
1461 "name": "python2.7-python-pam-1.8.4"
1473 },
1462 },
1474 {
1463 {
1475 "license": "UNKNOWN",
1464 "license": "UNKNOWN",
1476 "name": "linux-pam-1.3.0"
1465 "name": "linux-pam-1.3.0"
1477 },
1466 },
1478 {
1467 {
1479 "license": [
1468 "license": [
1480 {
1469 {
1481 "fullName": "Python Software Foundation License version 2",
1470 "fullName": "Python Software Foundation License version 2",
1482 "shortName": "psfl",
1471 "shortName": "psfl",
1483 "spdxId": "Python-2.0",
1472 "spdxId": "Python-2.0",
1484 "url": "http://spdx.org/licenses/Python-2.0.html"
1473 "url": "http://spdx.org/licenses/Python-2.0.html"
1485 }
1474 }
1486 ],
1475 ],
1487 "name": "python2.7-python-memcached-1.59"
1476 "name": "python2.7-python-memcached-1.59"
1488 },
1477 },
1489 {
1478 {
1490 "license": [
1479 "license": [
1491 {
1480 {
1492 "fullName": "Python Software Foundation License version 2",
1481 "fullName": "Python Software Foundation License version 2",
1493 "shortName": "psfl",
1482 "shortName": "psfl",
1494 "spdxId": "Python-2.0",
1483 "spdxId": "Python-2.0",
1495 "url": "http://spdx.org/licenses/Python-2.0.html"
1484 "url": "http://spdx.org/licenses/Python-2.0.html"
1496 }
1485 }
1497 ],
1486 ],
1498 "name": "python2.7-python-ldap-3.1.0"
1487 "name": "python2.7-python-ldap-3.1.0"
1499 },
1488 },
1500 {
1489 {
1501 "license": {
1490 "license": {
1502 "fullName": "MIT License",
1491 "fullName": "MIT License",
1503 "shortName": "mit",
1492 "shortName": "mit",
1504 "spdxId": "MIT",
1493 "spdxId": "MIT",
1505 "url": "http://spdx.org/licenses/MIT.html"
1494 "url": "http://spdx.org/licenses/MIT.html"
1506 },
1495 },
1507 "name": "libkrb5-1.15.2"
1496 "name": "libkrb5-1.15.2"
1508 },
1497 },
1509 {
1498 {
1510 "license": "UNKNOWN",
1499 "license": "UNKNOWN",
1511 "name": "openldap-2.4.45"
1500 "name": "openldap-2.4.45"
1512 },
1501 },
1513 {
1502 {
1514 "license": [
1503 "license": [
1515 {
1504 {
1516 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1505 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1517 "shortName": "bsdOriginal",
1506 "shortName": "bsdOriginal",
1518 "spdxId": "BSD-4-Clause",
1507 "spdxId": "BSD-4-Clause",
1519 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1508 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1520 },
1509 },
1521 {
1510 {
1522 "fullName": "BSD 2-clause \"Simplified\" License",
1511 "fullName": "BSD 2-clause \"Simplified\" License",
1523 "shortName": "bsd2",
1512 "shortName": "bsd2",
1524 "spdxId": "BSD-2-Clause",
1513 "spdxId": "BSD-2-Clause",
1525 "url": "http://spdx.org/licenses/BSD-2-Clause.html"
1514 "url": "http://spdx.org/licenses/BSD-2-Clause.html"
1526 }
1515 }
1527 ],
1516 ],
1528 "name": "python2.7-pyasn1-modules-0.2.6"
1517 "name": "python2.7-pyasn1-modules-0.2.6"
1529 },
1518 },
1530 {
1519 {
1531 "license": [
1520 "license": [
1532 {
1521 {
1533 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1522 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1534 "shortName": "bsdOriginal",
1523 "shortName": "bsdOriginal",
1535 "spdxId": "BSD-4-Clause",
1524 "spdxId": "BSD-4-Clause",
1536 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1525 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1537 }
1526 }
1538 ],
1527 ],
1539 "name": "python2.7-pyasn1-0.4.7"
1528 "name": "python2.7-pyasn1-0.4.7"
1540 },
1529 },
1541 {
1530 {
1542 "license": [
1531 "license": [
1543 {
1532 {
1544 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1533 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1545 "shortName": "bsdOriginal",
1534 "shortName": "bsdOriginal",
1546 "spdxId": "BSD-4-Clause",
1535 "spdxId": "BSD-4-Clause",
1547 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1536 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1548 }
1537 }
1549 ],
1538 ],
1550 "name": "python2.7-pyramid-mailer-0.15.1"
1539 "name": "python2.7-pyramid-mailer-0.15.1"
1551 },
1540 },
1552 {
1541 {
1553 "license": [
1542 "license": [
1554 {
1543 {
1555 "fullName": "Zope Public License 2.1",
1544 "fullName": "Zope Public License 2.1",
1556 "shortName": "zpl21",
1545 "shortName": "zpl21",
1557 "spdxId": "ZPL-2.1",
1546 "spdxId": "ZPL-2.1",
1558 "url": "http://spdx.org/licenses/ZPL-2.1.html"
1547 "url": "http://spdx.org/licenses/ZPL-2.1.html"
1559 }
1548 }
1560 ],
1549 ],
1561 "name": "python2.7-transaction-2.4.0"
1550 "name": "python2.7-transaction-2.4.0"
1562 },
1551 },
1563 {
1552 {
1564 "license": [
1553 "license": [
1565 {
1554 {
1566 "fullName": "Zope Public License 2.1",
1555 "fullName": "Zope Public License 2.1",
1567 "shortName": "zpl21",
1556 "shortName": "zpl21",
1568 "spdxId": "ZPL-2.1",
1557 "spdxId": "ZPL-2.1",
1569 "url": "http://spdx.org/licenses/ZPL-2.1.html"
1558 "url": "http://spdx.org/licenses/ZPL-2.1.html"
1570 }
1559 }
1571 ],
1560 ],
1572 "name": "python2.7-repoze.sendmail-4.4.1"
1561 "name": "python2.7-repoze.sendmail-4.4.1"
1573 },
1562 },
1574 {
1563 {
1575 "license": {
1564 "license": {
1576 "fullName": "Repoze License",
1565 "fullName": "Repoze License",
1577 "url": "http://www.repoze.org/LICENSE.txt"
1566 "url": "http://www.repoze.org/LICENSE.txt"
1578 },
1567 },
1579 "name": "python2.7-pyramid-1.10.4"
1568 "name": "python2.7-pyramid-1.10.4"
1580 },
1569 },
1581 {
1570 {
1582 "license": [
1571 "license": [
1583 {
1572 {
1584 "fullName": "MIT License",
1573 "fullName": "MIT License",
1585 "shortName": "mit",
1574 "shortName": "mit",
1586 "spdxId": "MIT",
1575 "spdxId": "MIT",
1587 "url": "http://spdx.org/licenses/MIT.html"
1576 "url": "http://spdx.org/licenses/MIT.html"
1588 }
1577 }
1589 ],
1578 ],
1590 "name": "python2.7-plaster-pastedeploy-0.7"
1579 "name": "python2.7-plaster-pastedeploy-0.7"
1591 },
1580 },
1592 {
1581 {
1593 "license": [
1582 "license": [
1594 {
1583 {
1595 "fullName": "MIT License",
1584 "fullName": "MIT License",
1596 "shortName": "mit",
1585 "shortName": "mit",
1597 "spdxId": "MIT",
1586 "spdxId": "MIT",
1598 "url": "http://spdx.org/licenses/MIT.html"
1587 "url": "http://spdx.org/licenses/MIT.html"
1599 }
1588 }
1600 ],
1589 ],
1601 "name": "python2.7-plaster-1.0"
1590 "name": "python2.7-plaster-1.0"
1602 },
1591 },
1603 {
1592 {
1604 "license": [
1593 "license": [
1605 {
1594 {
1606 "fullName": "MIT License",
1595 "fullName": "MIT License",
1607 "shortName": "mit",
1596 "shortName": "mit",
1608 "spdxId": "MIT",
1597 "spdxId": "MIT",
1609 "url": "http://spdx.org/licenses/MIT.html"
1598 "url": "http://spdx.org/licenses/MIT.html"
1610 }
1599 }
1611 ],
1600 ],
1612 "name": "python2.7-pastedeploy-2.0.1"
1601 "name": "python2.7-pastedeploy-2.0.1"
1613 },
1602 },
1614 {
1603 {
1615 "license": [
1604 "license": [
1616 {
1605 {
1617 "fullName": "MIT License",
1606 "fullName": "MIT License",
1618 "shortName": "mit",
1607 "shortName": "mit",
1619 "spdxId": "MIT",
1608 "spdxId": "MIT",
1620 "url": "http://spdx.org/licenses/MIT.html"
1609 "url": "http://spdx.org/licenses/MIT.html"
1621 }
1610 }
1622 ],
1611 ],
1623 "name": "python2.7-hupper-1.9.1"
1612 "name": "python2.7-hupper-1.9.1"
1624 },
1613 },
1625 {
1614 {
1626 "license": {
1615 "license": {
1627 "fullName": "Repoze License",
1616 "fullName": "Repoze License",
1628 "url": "http://www.repoze.org/LICENSE.txt"
1617 "url": "http://www.repoze.org/LICENSE.txt"
1629 },
1618 },
1630 "name": "python2.7-pyramid-mako-1.1.0"
1619 "name": "python2.7-pyramid-mako-1.1.0"
1631 },
1620 },
1632 {
1621 {
1633 "license": [
1622 "license": [
1634 {
1623 {
1635 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1624 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1636 "shortName": "bsdOriginal",
1625 "shortName": "bsdOriginal",
1637 "spdxId": "BSD-4-Clause",
1626 "spdxId": "BSD-4-Clause",
1638 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1627 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1639 },
1628 },
1640 {
1629 {
1641 "fullName": "Repoze License",
1630 "fullName": "Repoze License",
1642 "url": "http://www.repoze.org/LICENSE.txt"
1631 "url": "http://www.repoze.org/LICENSE.txt"
1643 }
1632 }
1644 ],
1633 ],
1645 "name": "python2.7-pyramid-debugtoolbar-4.5.1"
1634 "name": "python2.7-pyramid-debugtoolbar-4.5.1"
1646 },
1635 },
1647 {
1636 {
1648 "license": [
1637 "license": [
1649 {
1638 {
1650 "fullName": "Public Domain",
1639 "fullName": "Public Domain",
1651 "shortName": "publicDomain"
1640 "shortName": "publicDomain"
1652 }
1641 }
1653 ],
1642 ],
1654 "name": "python2.7-pycrypto-2.6.1"
1643 "name": "python2.7-pycrypto-2.6.1"
1655 },
1644 },
1656 {
1645 {
1657 "license": {
1646 "license": {
1658 "fullName": "MIT License",
1647 "fullName": "MIT License",
1659 "shortName": "mit",
1648 "shortName": "mit",
1660 "spdxId": "MIT",
1649 "spdxId": "MIT",
1661 "url": "http://spdx.org/licenses/MIT.html"
1650 "url": "http://spdx.org/licenses/MIT.html"
1662 },
1651 },
1663 "name": "python2.7-pycurl-7.43.0.3"
1652 "name": "python2.7-pycurl-7.43.0.3"
1664 },
1653 },
1665 {
1654 {
1666 "license": [
1655 "license": [
1667 {
1656 {
1668 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1657 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1669 "shortName": "bsdOriginal",
1658 "shortName": "bsdOriginal",
1670 "spdxId": "BSD-4-Clause",
1659 "spdxId": "BSD-4-Clause",
1671 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1660 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1672 }
1661 }
1673 ],
1662 ],
1674 "name": "python2.7-py-bcrypt-0.4"
1663 "name": "python2.7-py-bcrypt-0.4"
1675 },
1664 },
1676 {
1665 {
1677 "license": [
1666 "license": [
1678 {
1667 {
1679 "fullName": "BSD-derived (http://www.repoze.org/LICENSE.txt)"
1668 "fullName": "BSD-derived (http://www.repoze.org/LICENSE.txt)"
1680 }
1669 }
1681 ],
1670 ],
1682 "name": "python2.7-peppercorn-0.6"
1671 "name": "python2.7-peppercorn-0.6"
1683 },
1672 },
1684 {
1673 {
1685 "license": [
1674 "license": [
1686 {
1675 {
1687 "fullName": "MIT License",
1676 "fullName": "MIT License",
1688 "shortName": "mit",
1677 "shortName": "mit",
1689 "spdxId": "MIT",
1678 "spdxId": "MIT",
1690 "url": "http://spdx.org/licenses/MIT.html"
1679 "url": "http://spdx.org/licenses/MIT.html"
1691 }
1680 }
1692 ],
1681 ],
1693 "name": "python2.7-pastescript-3.2.0"
1682 "name": "python2.7-pastescript-3.2.0"
1694 },
1683 },
1695 {
1684 {
1696 "license": [
1685 "license": [
1697 {
1686 {
1698 "fullName": "MIT License",
1687 "fullName": "MIT License",
1699 "shortName": "mit",
1688 "shortName": "mit",
1700 "spdxId": "MIT",
1689 "spdxId": "MIT",
1701 "url": "http://spdx.org/licenses/MIT.html"
1690 "url": "http://spdx.org/licenses/MIT.html"
1702 }
1691 }
1703 ],
1692 ],
1704 "name": "python2.7-pyotp-2.3.0"
1693 "name": "python2.7-pyotp-2.3.0"
1705 },
1694 },
1706 {
1695 {
1707 "license": [
1696 "license": [
1708 {
1697 {
1709 "fullName": "Apache License 2.0",
1698 "fullName": "Apache License 2.0",
1710 "shortName": "asl20",
1699 "shortName": "asl20",
1711 "spdxId": "Apache-2.0",
1700 "spdxId": "Apache-2.0",
1712 "url": "http://spdx.org/licenses/Apache-2.0.html"
1701 "url": "http://spdx.org/licenses/Apache-2.0.html"
1713 }
1702 }
1714 ],
1703 ],
1715 "name": "python2.7-msgpack-python-0.5.6"
1704 "name": "python2.7-msgpack-python-0.5.6"
1716 },
1705 },
1717 {
1706 {
1718 "license": [
1707 "license": [
1719 {
1708 {
1720 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1709 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1721 "shortName": "bsdOriginal",
1710 "shortName": "bsdOriginal",
1722 "spdxId": "BSD-4-Clause",
1711 "spdxId": "BSD-4-Clause",
1723 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1712 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1724 }
1713 }
1725 ],
1714 ],
1726 "name": "python2.7-kombu-4.6.6"
1715 "name": "python2.7-kombu-4.6.6"
1727 },
1716 },
1728 {
1717 {
1729 "license": [
1718 "license": [
1730 {
1719 {
1731 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1720 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1732 "shortName": "bsdOriginal",
1721 "shortName": "bsdOriginal",
1733 "spdxId": "BSD-4-Clause",
1722 "spdxId": "BSD-4-Clause",
1734 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1723 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1735 }
1724 }
1736 ],
1725 ],
1737 "name": "python2.7-amqp-2.5.2"
1726 "name": "python2.7-amqp-2.5.2"
1738 },
1727 },
1739 {
1728 {
1740 "license": [
1729 "license": [
1741 {
1730 {
1742 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1731 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1743 "shortName": "bsdOriginal",
1732 "shortName": "bsdOriginal",
1744 "spdxId": "BSD-4-Clause",
1733 "spdxId": "BSD-4-Clause",
1745 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1734 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1746 }
1735 }
1747 ],
1736 ],
1748 "name": "python2.7-vine-1.3.0"
1737 "name": "python2.7-vine-1.3.0"
1749 },
1738 },
1750 {
1739 {
1751 "license": [
1740 "license": [
1752 {
1741 {
1753 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1742 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1754 "shortName": "bsdOriginal",
1743 "shortName": "bsdOriginal",
1755 "spdxId": "BSD-4-Clause",
1744 "spdxId": "BSD-4-Clause",
1756 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1745 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1757 }
1746 }
1758 ],
1747 ],
1759 "name": "python2.7-itsdangerous-0.24"
1748 "name": "python2.7-itsdangerous-0.24"
1760 },
1749 },
1761 {
1750 {
1762 "license": [
1751 "license": [
1763 {
1752 {
1764 "fullName": "MIT License",
1753 "fullName": "MIT License",
1765 "shortName": "mit",
1754 "shortName": "mit",
1766 "spdxId": "MIT",
1755 "spdxId": "MIT",
1767 "url": "http://spdx.org/licenses/MIT.html"
1756 "url": "http://spdx.org/licenses/MIT.html"
1768 }
1757 }
1769 ],
1758 ],
1770 "name": "python2.7-iso8601-0.1.12"
1759 "name": "python2.7-iso8601-0.1.12"
1771 },
1760 },
1772 {
1761 {
1773 "license": [
1762 "license": [
1774 {
1763 {
1775 "fullName": "Zope Public License 2.1",
1764 "fullName": "Zope Public License 2.1",
1776 "shortName": "zpl21",
1765 "shortName": "zpl21",
1777 "spdxId": "ZPL-2.1",
1766 "spdxId": "ZPL-2.1",
1778 "url": "http://spdx.org/licenses/ZPL-2.1.html"
1767 "url": "http://spdx.org/licenses/ZPL-2.1.html"
1779 }
1768 }
1780 ],
1769 ],
1781 "name": "python2.7-infrae.cache-1.0.1"
1770 "name": "python2.7-infrae.cache-1.0.1"
1782 },
1771 },
1783 {
1772 {
1784 "license": [
1773 "license": [
1785 {
1774 {
1786 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1775 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1787 "shortName": "bsdOriginal",
1776 "shortName": "bsdOriginal",
1788 "spdxId": "BSD-4-Clause",
1777 "spdxId": "BSD-4-Clause",
1789 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1778 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1790 }
1779 }
1791 ],
1780 ],
1792 "name": "python2.7-beaker-1.9.1"
1781 "name": "python2.7-beaker-1.9.1"
1793 },
1782 },
1794 {
1783 {
1795 "license": [
1784 "license": [
1796 {
1785 {
1797 "fullName": "Python Software Foundation License version 2",
1786 "fullName": "Python Software Foundation License version 2",
1798 "shortName": "psfl",
1787 "shortName": "psfl",
1799 "spdxId": "Python-2.0",
1788 "spdxId": "Python-2.0",
1800 "url": "http://spdx.org/licenses/Python-2.0.html"
1789 "url": "http://spdx.org/licenses/Python-2.0.html"
1801 }
1790 }
1802 ],
1791 ],
1803 "name": "python2.7-formencode-1.2.4"
1792 "name": "python2.7-formencode-1.2.4"
1804 },
1793 },
1805 {
1794 {
1806 "license": [
1795 "license": [
1807 {
1796 {
1808 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1797 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1809 "shortName": "bsdOriginal",
1798 "shortName": "bsdOriginal",
1810 "spdxId": "BSD-4-Clause",
1799 "spdxId": "BSD-4-Clause",
1811 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1800 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1812 }
1801 }
1813 ],
1802 ],
1814 "name": "python2.7-dogpile.cache-0.9.0"
1803 "name": "python2.7-dogpile.cache-0.9.0"
1815 },
1804 },
1816 {
1805 {
1817 "license": {
1806 "license": {
1818 "fullName": "BSD 2-clause \"Simplified\" License",
1807 "fullName": "BSD 2-clause \"Simplified\" License",
1819 "shortName": "bsd2",
1808 "shortName": "bsd2",
1820 "spdxId": "BSD-2-Clause",
1809 "spdxId": "BSD-2-Clause",
1821 "url": "http://spdx.org/licenses/BSD-2-Clause.html"
1810 "url": "http://spdx.org/licenses/BSD-2-Clause.html"
1822 },
1811 },
1823 "name": "python2.7-docutils-0.14"
1812 "name": "python2.7-docutils-0.14"
1824 },
1813 },
1825 {
1814 {
1826 "license": [
1815 "license": [
1827 {
1816 {
1828 "fullName": "Repoze Public License"
1817 "fullName": "Repoze Public License"
1829 },
1818 },
1830 {
1819 {
1831 "fullName": "BSD-derived (http://www.repoze.org/LICENSE.txt)"
1820 "fullName": "BSD-derived (http://www.repoze.org/LICENSE.txt)"
1832 }
1821 }
1833 ],
1822 ],
1834 "name": "python2.7-deform-2.0.8"
1823 "name": "python2.7-deform-2.0.8"
1835 },
1824 },
1836 {
1825 {
1837 "license": {
1826 "license": {
1838 "fullName": "Repoze License",
1827 "fullName": "Repoze License",
1839 "url": "http://www.repoze.org/LICENSE.txt"
1828 "url": "http://www.repoze.org/LICENSE.txt"
1840 },
1829 },
1841 "name": "python2.7-colander-1.7.0"
1830 "name": "python2.7-colander-1.7.0"
1842 },
1831 },
1843 {
1832 {
1844 "license": [
1833 "license": [
1845 {
1834 {
1846 "fullName": "BSD-like (http://repoze.org/license.html)"
1835 "fullName": "BSD-like (http://repoze.org/license.html)"
1847 }
1836 }
1848 ],
1837 ],
1849 "name": "python2.7-chameleon-2.24"
1838 "name": "python2.7-chameleon-2.24"
1850 },
1839 },
1851 {
1840 {
1852 "license": [
1841 "license": [
1853 {
1842 {
1854 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1843 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1855 "shortName": "bsdOriginal",
1844 "shortName": "bsdOriginal",
1856 "spdxId": "BSD-4-Clause",
1845 "spdxId": "BSD-4-Clause",
1857 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1846 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1858 }
1847 }
1859 ],
1848 ],
1860 "name": "python2.7-cssselect-1.0.3"
1849 "name": "python2.7-cssselect-1.0.3"
1861 },
1850 },
1862 {
1851 {
1863 "license": [
1852 "license": [
1864 {
1853 {
1865 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1854 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1866 "shortName": "bsdOriginal",
1855 "shortName": "bsdOriginal",
1867 "spdxId": "BSD-4-Clause",
1856 "spdxId": "BSD-4-Clause",
1868 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1857 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1869 }
1858 }
1870 ],
1859 ],
1871 "name": "python2.7-configobj-5.0.6"
1872 },
1873 {
1874 "license": [
1875 {
1876 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1877 "shortName": "bsdOriginal",
1878 "spdxId": "BSD-4-Clause",
1879 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1880 }
1881 ],
1882 "name": "python2.7-channelstream-0.6.14"
1860 "name": "python2.7-channelstream-0.6.14"
1883 },
1861 },
1884 {
1862 {
1885 "license": [
1863 "license": [
1886 {
1864 {
1887 "fullName": "Repoze Public License"
1865 "fullName": "Repoze Public License"
1888 },
1866 },
1889 {
1867 {
1890 "fullName": "BSD-derived (http://www.repoze.org/LICENSE.txt)"
1868 "fullName": "BSD-derived (http://www.repoze.org/LICENSE.txt)"
1891 }
1869 }
1892 ],
1870 ],
1893 "name": "python2.7-pyramid-jinja2-2.7"
1871 "name": "python2.7-pyramid-jinja2-2.7"
1894 },
1872 },
1895 {
1873 {
1896 "license": [
1874 "license": [
1897 {
1875 {
1898 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1876 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1899 "shortName": "bsdOriginal",
1877 "shortName": "bsdOriginal",
1900 "spdxId": "BSD-4-Clause",
1878 "spdxId": "BSD-4-Clause",
1901 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1879 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1902 }
1880 }
1903 ],
1881 ],
1904 "name": "python2.7-ws4py-0.5.1"
1882 "name": "python2.7-ws4py-0.5.1"
1905 },
1883 },
1906 {
1884 {
1907 "license": [
1885 "license": [
1908 {
1886 {
1909 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1887 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1910 "shortName": "bsdOriginal",
1888 "shortName": "bsdOriginal",
1911 "spdxId": "BSD-4-Clause",
1889 "spdxId": "BSD-4-Clause",
1912 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1890 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1913 }
1891 }
1914 ],
1892 ],
1915 "name": "python2.7-celery-4.3.0"
1893 "name": "python2.7-celery-4.3.0"
1916 },
1894 },
1917 {
1895 {
1918 "license": [
1896 "license": [
1919 {
1897 {
1920 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1898 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1921 "shortName": "bsdOriginal",
1899 "shortName": "bsdOriginal",
1922 "spdxId": "BSD-4-Clause",
1900 "spdxId": "BSD-4-Clause",
1923 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1901 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1924 }
1902 }
1925 ],
1903 ],
1926 "name": "python2.7-billiard-3.6.1.0"
1904 "name": "python2.7-billiard-3.6.1.0"
1927 },
1905 },
1928 {
1906 {
1929 "license": [
1907 "license": [
1930 {
1908 {
1931 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1909 "fullName": "BSD 4-clause \"Original\" or \"Old\" License",
1932 "shortName": "bsdOriginal",
1910 "shortName": "bsdOriginal",
1933 "spdxId": "BSD-4-Clause",
1911 "spdxId": "BSD-4-Clause",
1934 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1912 "url": "http://spdx.org/licenses/BSD-4-Clause.html"
1935 }
1913 }
1936 ],
1914 ],
1937 "name": "python2.7-babel-1.3"
1915 "name": "python2.7-babel-1.3"
1938 },
1916 },
1939 {
1917 {
1940 "license": "UNKNOWN",
1918 "license": "UNKNOWN",
1941 "name": "python2.7-rhodecode-testdata-0.10.0"
1919 "name": "python2.7-rhodecode-testdata-0.10.0"
1942 }
1920 }
1943 ]
1921 ]
@@ -1,616 +1,630 b''
1
1
2 # Copyright (C) 2010-2020 RhodeCode GmbH
2 # Copyright (C) 2010-2020 RhodeCode GmbH
3 #
3 #
4 # This program is free software: you can redistribute it and/or modify
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU Affero General Public License, version 3
5 # it under the terms of the GNU Affero General Public License, version 3
6 # (only), as published by the Free Software Foundation.
6 # (only), as published by the Free Software Foundation.
7 #
7 #
8 # This program is distributed in the hope that it will be useful,
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
11 # GNU General Public License for more details.
12 #
12 #
13 # You should have received a copy of the GNU Affero General Public License
13 # You should have received a copy of the GNU Affero General Public License
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 #
15 #
16 # This program is dual-licensed. If you wish to learn more about the
16 # This program is dual-licensed. If you wish to learn more about the
17 # RhodeCode Enterprise Edition, including its added features, Support services,
17 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # and proprietary license terms, please see https://rhodecode.com/licenses/
18 # and proprietary license terms, please see https://rhodecode.com/licenses/
19
19
20 import os
20 import os
21 import sys
21 import sys
22 import collections
22 import collections
23 import tempfile
23 import tempfile
24 import time
24 import time
25 import logging.config
25 import logging.config
26
26
27 from paste.gzipper import make_gzip_middleware
27 from paste.gzipper import make_gzip_middleware
28 import pyramid.events
28 import pyramid.events
29 from pyramid.wsgi import wsgiapp
29 from pyramid.wsgi import wsgiapp
30 from pyramid.authorization import ACLAuthorizationPolicy
30 from pyramid.authorization import ACLAuthorizationPolicy
31 from pyramid.config import Configurator
31 from pyramid.config import Configurator
32 from pyramid.settings import asbool, aslist
32 from pyramid.settings import asbool, aslist
33 from pyramid.httpexceptions import (
33 from pyramid.httpexceptions import (
34 HTTPException, HTTPError, HTTPInternalServerError, HTTPFound, HTTPNotFound)
34 HTTPException, HTTPError, HTTPInternalServerError, HTTPFound, HTTPNotFound)
35 from pyramid.renderers import render_to_response
35 from pyramid.renderers import render_to_response
36
36
37 from rhodecode.model import meta
37 from rhodecode.model import meta
38 from rhodecode.config import patches
38 from rhodecode.config import patches
39 from rhodecode.config import utils as config_utils
39 from rhodecode.config import utils as config_utils
40 from rhodecode.config.settings_maker import SettingsMaker
40 from rhodecode.config.settings_maker import SettingsMaker
41 from rhodecode.config.environment import load_pyramid_environment
41 from rhodecode.config.environment import load_pyramid_environment
42
42
43 import rhodecode.events
43 import rhodecode.events
44 from rhodecode.lib.middleware.vcs import VCSMiddleware
44 from rhodecode.lib.middleware.vcs import VCSMiddleware
45 from rhodecode.lib.request import Request
45 from rhodecode.lib.request import Request
46 from rhodecode.lib.vcs import VCSCommunicationError
46 from rhodecode.lib.vcs import VCSCommunicationError
47 from rhodecode.lib.exceptions import VCSServerUnavailable
47 from rhodecode.lib.exceptions import VCSServerUnavailable
48 from rhodecode.lib.middleware.appenlight import wrap_in_appenlight_if_enabled
48 from rhodecode.lib.middleware.appenlight import wrap_in_appenlight_if_enabled
49 from rhodecode.lib.middleware.https_fixup import HttpsFixup
49 from rhodecode.lib.middleware.https_fixup import HttpsFixup
50 from rhodecode.lib.plugins.utils import register_rhodecode_plugin
50 from rhodecode.lib.plugins.utils import register_rhodecode_plugin
51 from rhodecode.lib.utils2 import AttributeDict
51 from rhodecode.lib.utils2 import AttributeDict
52 from rhodecode.lib.exc_tracking import store_exception
52 from rhodecode.lib.exc_tracking import store_exception
53 from rhodecode.subscribers import (
53 from rhodecode.subscribers import (
54 scan_repositories_if_enabled, write_js_routes_if_enabled,
54 scan_repositories_if_enabled, write_js_routes_if_enabled,
55 write_metadata_if_needed, write_usage_data)
55 write_metadata_if_needed, write_usage_data)
56 from rhodecode.lib.statsd_client import StatsdClient
56 from rhodecode.lib.statsd_client import StatsdClient
57
57
58 log = logging.getLogger(__name__)
58 log = logging.getLogger(__name__)
59
59
60
60
61 def is_http_error(response):
61 def is_http_error(response):
62 # error which should have traceback
62 # error which should have traceback
63 return response.status_code > 499
63 return response.status_code > 499
64
64
65
65
66 def should_load_all():
66 def should_load_all():
67 """
67 """
68 Returns if all application components should be loaded. In some cases it's
68 Returns if all application components should be loaded. In some cases it's
69 desired to skip apps loading for faster shell script execution
69 desired to skip apps loading for faster shell script execution
70 """
70 """
71 ssh_cmd = os.environ.get('RC_CMD_SSH_WRAPPER')
71 ssh_cmd = os.environ.get('RC_CMD_SSH_WRAPPER')
72 if ssh_cmd:
72 if ssh_cmd:
73 return False
73 return False
74
74
75 return True
75 return True
76
76
77
77
78 def make_pyramid_app(global_config, **settings):
78 def make_pyramid_app(global_config, **settings):
79 """
79 """
80 Constructs the WSGI application based on Pyramid.
80 Constructs the WSGI application based on Pyramid.
81
81
82 Specials:
82 Specials:
83
83
84 * The application can also be integrated like a plugin via the call to
84 * The application can also be integrated like a plugin via the call to
85 `includeme`. This is accompanied with the other utility functions which
85 `includeme`. This is accompanied with the other utility functions which
86 are called. Changing this should be done with great care to not break
86 are called. Changing this should be done with great care to not break
87 cases when these fragments are assembled from another place.
87 cases when these fragments are assembled from another place.
88
88
89 """
89 """
90 start_time = time.time()
90 start_time = time.time()
91 log.info('Pyramid app config starting')
91 log.info('Pyramid app config starting')
92
92
93 sanitize_settings_and_apply_defaults(global_config, settings)
93 sanitize_settings_and_apply_defaults(global_config, settings)
94
94
95 # init and bootstrap StatsdClient
95 # init and bootstrap StatsdClient
96 StatsdClient.setup(settings)
96 StatsdClient.setup(settings)
97
97
98 config = Configurator(settings=settings)
98 config = Configurator(settings=settings)
99 # Init our statsd at very start
99 # Init our statsd at very start
100 config.registry.statsd = StatsdClient.statsd
100 config.registry.statsd = StatsdClient.statsd
101
101
102 # Apply compatibility patches
102 # Apply compatibility patches
103 patches.inspect_getargspec()
103 patches.inspect_getargspec()
104
104
105 load_pyramid_environment(global_config, settings)
105 load_pyramid_environment(global_config, settings)
106
106
107 # Static file view comes first
107 # Static file view comes first
108 includeme_first(config)
108 includeme_first(config)
109
109
110 includeme(config)
110 includeme(config)
111
111
112 pyramid_app = config.make_wsgi_app()
112 pyramid_app = config.make_wsgi_app()
113 pyramid_app = wrap_app_in_wsgi_middlewares(pyramid_app, config)
113 pyramid_app = wrap_app_in_wsgi_middlewares(pyramid_app, config)
114 pyramid_app.config = config
114 pyramid_app.config = config
115
115
116 celery_settings = get_celery_config(settings)
116 celery_settings = get_celery_config(settings)
117 config.configure_celery(celery_settings)
117 config.configure_celery(celery_settings)
118
118
119 # creating the app uses a connection - return it after we are done
119 # creating the app uses a connection - return it after we are done
120 meta.Session.remove()
120 meta.Session.remove()
121
121
122 total_time = time.time() - start_time
122 total_time = time.time() - start_time
123 log.info('Pyramid app `%s` created and configured in %.2fs',
123 log.info('Pyramid app created and configured in %.2fs', total_time)
124 getattr(pyramid_app, 'func_name', 'pyramid_app'), total_time)
125 return pyramid_app
124 return pyramid_app
126
125
127
126
128 def get_celery_config(settings):
127 def get_celery_config(settings):
129 """
128 """
130 Converts basic ini configuration into celery 4.X options
129 Converts basic ini configuration into celery 4.X options
131 """
130 """
132
131
133 def key_converter(key_name):
132 def key_converter(key_name):
134 pref = 'celery.'
133 pref = 'celery.'
135 if key_name.startswith(pref):
134 if key_name.startswith(pref):
136 return key_name[len(pref):].replace('.', '_').lower()
135 return key_name[len(pref):].replace('.', '_').lower()
137
136
138 def type_converter(parsed_key, value):
137 def type_converter(parsed_key, value):
139 # cast to int
138 # cast to int
140 if value.isdigit():
139 if value.isdigit():
141 return int(value)
140 return int(value)
142
141
143 # cast to bool
142 # cast to bool
144 if value.lower() in ['true', 'false', 'True', 'False']:
143 if value.lower() in ['true', 'false', 'True', 'False']:
145 return value.lower() == 'true'
144 return value.lower() == 'true'
146 return value
145 return value
147
146
148 celery_config = {}
147 celery_config = {}
149 for k, v in settings.items():
148 for k, v in settings.items():
150 pref = 'celery.'
149 pref = 'celery.'
151 if k.startswith(pref):
150 if k.startswith(pref):
152 celery_config[key_converter(k)] = type_converter(key_converter(k), v)
151 celery_config[key_converter(k)] = type_converter(key_converter(k), v)
153
152
154 # TODO:rethink if we want to support celerybeat based file config, probably NOT
153 # TODO:rethink if we want to support celerybeat based file config, probably NOT
155 # beat_config = {}
154 # beat_config = {}
156 # for section in parser.sections():
155 # for section in parser.sections():
157 # if section.startswith('celerybeat:'):
156 # if section.startswith('celerybeat:'):
158 # name = section.split(':', 1)[1]
157 # name = section.split(':', 1)[1]
159 # beat_config[name] = get_beat_config(parser, section)
158 # beat_config[name] = get_beat_config(parser, section)
160
159
161 # final compose of settings
160 # final compose of settings
162 celery_settings = {}
161 celery_settings = {}
163
162
164 if celery_config:
163 if celery_config:
165 celery_settings.update(celery_config)
164 celery_settings.update(celery_config)
166 # if beat_config:
165 # if beat_config:
167 # celery_settings.update({'beat_schedule': beat_config})
166 # celery_settings.update({'beat_schedule': beat_config})
168
167
169 return celery_settings
168 return celery_settings
170
169
171
170
172 def not_found_view(request):
171 def not_found_view(request):
173 """
172 """
174 This creates the view which should be registered as not-found-view to
173 This creates the view which should be registered as not-found-view to
175 pyramid.
174 pyramid.
176 """
175 """
177
176
178 if not getattr(request, 'vcs_call', None):
177 if not getattr(request, 'vcs_call', None):
179 # handle like regular case with our error_handler
178 # handle like regular case with our error_handler
180 return error_handler(HTTPNotFound(), request)
179 return error_handler(HTTPNotFound(), request)
181
180
182 # handle not found view as a vcs call
181 # handle not found view as a vcs call
183 settings = request.registry.settings
182 settings = request.registry.settings
184 ae_client = getattr(request, 'ae_client', None)
183 ae_client = getattr(request, 'ae_client', None)
185 vcs_app = VCSMiddleware(
184 vcs_app = VCSMiddleware(
186 HTTPNotFound(), request.registry, settings,
185 HTTPNotFound(), request.registry, settings,
187 appenlight_client=ae_client)
186 appenlight_client=ae_client)
188
187
189 return wsgiapp(vcs_app)(None, request)
188 return wsgiapp(vcs_app)(None, request)
190
189
191
190
192 def error_handler(exception, request):
191 def error_handler(exception, request):
193 import rhodecode
192 import rhodecode
194 from rhodecode.lib import helpers
193 from rhodecode.lib import helpers
195 from rhodecode.lib.utils2 import str2bool
194 from rhodecode.lib.utils2 import str2bool
196
195
197 rhodecode_title = rhodecode.CONFIG.get('rhodecode_title') or 'RhodeCode'
196 rhodecode_title = rhodecode.CONFIG.get('rhodecode_title') or 'RhodeCode'
198
197
199 base_response = HTTPInternalServerError()
198 base_response = HTTPInternalServerError()
200 # prefer original exception for the response since it may have headers set
199 # prefer original exception for the response since it may have headers set
201 if isinstance(exception, HTTPException):
200 if isinstance(exception, HTTPException):
202 base_response = exception
201 base_response = exception
203 elif isinstance(exception, VCSCommunicationError):
202 elif isinstance(exception, VCSCommunicationError):
204 base_response = VCSServerUnavailable()
203 base_response = VCSServerUnavailable()
205
204
206 if is_http_error(base_response):
205 if is_http_error(base_response):
207 log.exception(
206 log.exception(
208 'error occurred handling this request for path: %s', request.path)
207 'error occurred handling this request for path: %s', request.path)
209
208
210 error_explanation = base_response.explanation or str(base_response)
209 error_explanation = base_response.explanation or str(base_response)
211 if base_response.status_code == 404:
210 if base_response.status_code == 404:
212 error_explanation += " Optionally you don't have permission to access this page."
211 error_explanation += " Optionally you don't have permission to access this page."
213 c = AttributeDict()
212 c = AttributeDict()
214 c.error_message = base_response.status
213 c.error_message = base_response.status
215 c.error_explanation = error_explanation
214 c.error_explanation = error_explanation
216 c.visual = AttributeDict()
215 c.visual = AttributeDict()
217
216
218 c.visual.rhodecode_support_url = (
217 c.visual.rhodecode_support_url = (
219 request.registry.settings.get('rhodecode_support_url') or
218 request.registry.settings.get('rhodecode_support_url') or
220 request.route_url('rhodecode_support')
219 request.route_url('rhodecode_support')
221 )
220 )
222 c.redirect_time = 0
221 c.redirect_time = 0
223 c.rhodecode_name = rhodecode_title
222 c.rhodecode_name = rhodecode_title
224 if not c.rhodecode_name:
223 if not c.rhodecode_name:
225 c.rhodecode_name = 'Rhodecode'
224 c.rhodecode_name = 'Rhodecode'
226
225
227 c.causes = []
226 c.causes = []
228 if is_http_error(base_response):
227 if is_http_error(base_response):
229 c.causes.append('Server is overloaded.')
228 c.causes.append('Server is overloaded.')
230 c.causes.append('Server database connection is lost.')
229 c.causes.append('Server database connection is lost.')
231 c.causes.append('Server expected unhandled error.')
230 c.causes.append('Server expected unhandled error.')
232
231
233 if hasattr(base_response, 'causes'):
232 if hasattr(base_response, 'causes'):
234 c.causes = base_response.causes
233 c.causes = base_response.causes
235
234
236 c.messages = helpers.flash.pop_messages(request=request)
235 c.messages = helpers.flash.pop_messages(request=request)
237 exc_info = sys.exc_info()
236 exc_info = sys.exc_info()
238 c.exception_id = id(exc_info)
237 c.exception_id = id(exc_info)
239 c.show_exception_id = isinstance(base_response, VCSServerUnavailable) \
238 c.show_exception_id = isinstance(base_response, VCSServerUnavailable) \
240 or base_response.status_code > 499
239 or base_response.status_code > 499
241 c.exception_id_url = request.route_url(
240 c.exception_id_url = request.route_url(
242 'admin_settings_exception_tracker_show', exception_id=c.exception_id)
241 'admin_settings_exception_tracker_show', exception_id=c.exception_id)
243
242
243 debug_mode = rhodecode.ConfigGet().get_bool('debug')
244 if c.show_exception_id:
244 if c.show_exception_id:
245 store_exception(c.exception_id, exc_info)
245 store_exception(c.exception_id, exc_info)
246 c.exception_debug = str2bool(rhodecode.CONFIG.get('debug'))
246 c.exception_debug = debug_mode
247 c.exception_config_ini = rhodecode.CONFIG.get('__file__')
247 c.exception_config_ini = rhodecode.CONFIG.get('__file__')
248
248
249 if debug_mode:
250 try:
251 from rich.traceback import install
252 install(show_locals=True)
253 log.debug('Installing rich tracebacks...')
254 except ImportError:
255 pass
256
249 response = render_to_response(
257 response = render_to_response(
250 '/errors/error_document.mako', {'c': c, 'h': helpers}, request=request,
258 '/errors/error_document.mako', {'c': c, 'h': helpers}, request=request,
251 response=base_response)
259 response=base_response)
252
260
253 statsd = request.registry.statsd
261 statsd = request.registry.statsd
254 if statsd and base_response.status_code > 499:
262 if statsd and base_response.status_code > 499:
255 exc_type = "{}.{}".format(exception.__class__.__module__, exception.__class__.__name__)
263 exc_type = "{}.{}".format(exception.__class__.__module__, exception.__class__.__name__)
256 statsd.incr('rhodecode_exception_total',
264 statsd.incr('rhodecode_exception_total',
257 tags=["exc_source:web",
265 tags=["exc_source:web",
258 "http_code:{}".format(base_response.status_code),
266 "http_code:{}".format(base_response.status_code),
259 "type:{}".format(exc_type)])
267 "type:{}".format(exc_type)])
260
268
261 return response
269 return response
262
270
263
271
264 def includeme_first(config):
272 def includeme_first(config):
265 # redirect automatic browser favicon.ico requests to correct place
273 # redirect automatic browser favicon.ico requests to correct place
266 def favicon_redirect(context, request):
274 def favicon_redirect(context, request):
267 return HTTPFound(
275 return HTTPFound(
268 request.static_path('rhodecode:public/images/favicon.ico'))
276 request.static_path('rhodecode:public/images/favicon.ico'))
269
277
270 config.add_view(favicon_redirect, route_name='favicon')
278 config.add_view(favicon_redirect, route_name='favicon')
271 config.add_route('favicon', '/favicon.ico')
279 config.add_route('favicon', '/favicon.ico')
272
280
273 def robots_redirect(context, request):
281 def robots_redirect(context, request):
274 return HTTPFound(
282 return HTTPFound(
275 request.static_path('rhodecode:public/robots.txt'))
283 request.static_path('rhodecode:public/robots.txt'))
276
284
277 config.add_view(robots_redirect, route_name='robots')
285 config.add_view(robots_redirect, route_name='robots')
278 config.add_route('robots', '/robots.txt')
286 config.add_route('robots', '/robots.txt')
279
287
280 config.add_static_view(
288 config.add_static_view(
281 '_static/deform', 'deform:static')
289 '_static/deform', 'deform:static')
282 config.add_static_view(
290 config.add_static_view(
283 '_static/rhodecode', path='rhodecode:public', cache_max_age=3600 * 24)
291 '_static/rhodecode', path='rhodecode:public', cache_max_age=3600 * 24)
284
292
285
293
294 ce_auth_resources = [
295 'rhodecode.authentication.plugins.auth_crowd',
296 'rhodecode.authentication.plugins.auth_headers',
297 'rhodecode.authentication.plugins.auth_jasig_cas',
298 'rhodecode.authentication.plugins.auth_ldap',
299 'rhodecode.authentication.plugins.auth_pam',
300 'rhodecode.authentication.plugins.auth_rhodecode',
301 'rhodecode.authentication.plugins.auth_token',
302 ]
303
304
286 def includeme(config, auth_resources=None):
305 def includeme(config, auth_resources=None):
287 from rhodecode.lib.celerylib.loader import configure_celery
306 from rhodecode.lib.celerylib.loader import configure_celery
288 log.debug('Initializing main includeme from %s', os.path.basename(__file__))
307 log.debug('Initializing main includeme from %s', os.path.basename(__file__))
289 settings = config.registry.settings
308 settings = config.registry.settings
290 config.set_request_factory(Request)
309 config.set_request_factory(Request)
291
310
292 # plugin information
311 # plugin information
293 config.registry.rhodecode_plugins = collections.OrderedDict()
312 config.registry.rhodecode_plugins = collections.OrderedDict()
294
313
295 config.add_directive(
314 config.add_directive(
296 'register_rhodecode_plugin', register_rhodecode_plugin)
315 'register_rhodecode_plugin', register_rhodecode_plugin)
297
316
298 config.add_directive('configure_celery', configure_celery)
317 config.add_directive('configure_celery', configure_celery)
299
318
300 if settings.get('appenlight', False):
319 if settings.get('appenlight', False):
301 config.include('appenlight_client.ext.pyramid_tween')
320 config.include('appenlight_client.ext.pyramid_tween')
302
321
303 load_all = should_load_all()
322 load_all = should_load_all()
304
323
305 # Includes which are required. The application would fail without them.
324 # Includes which are required. The application would fail without them.
306 config.include('pyramid_mako')
325 config.include('pyramid_mako')
307 config.include('rhodecode.lib.rc_beaker')
326 config.include('rhodecode.lib.rc_beaker')
308 config.include('rhodecode.lib.rc_cache')
327 config.include('rhodecode.lib.rc_cache')
328 config.include('rhodecode.lib.rc_cache.archive_cache')
329
309 config.include('rhodecode.apps._base.navigation')
330 config.include('rhodecode.apps._base.navigation')
310 config.include('rhodecode.apps._base.subscribers')
331 config.include('rhodecode.apps._base.subscribers')
311 config.include('rhodecode.tweens')
332 config.include('rhodecode.tweens')
312 config.include('rhodecode.authentication')
333 config.include('rhodecode.authentication')
313
334
314 if load_all:
335 if load_all:
315 ce_auth_resources = [
316 'rhodecode.authentication.plugins.auth_crowd',
317 'rhodecode.authentication.plugins.auth_headers',
318 'rhodecode.authentication.plugins.auth_jasig_cas',
319 'rhodecode.authentication.plugins.auth_ldap',
320 'rhodecode.authentication.plugins.auth_pam',
321 'rhodecode.authentication.plugins.auth_rhodecode',
322 'rhodecode.authentication.plugins.auth_token',
323 ]
324
336
325 # load CE authentication plugins
337 # load CE authentication plugins
326
338
327 if auth_resources:
339 if auth_resources:
328 ce_auth_resources.extend(auth_resources)
340 ce_auth_resources.extend(auth_resources)
329
341
330 for resource in ce_auth_resources:
342 for resource in ce_auth_resources:
331 config.include(resource)
343 config.include(resource)
332
344
333 # Auto discover authentication plugins and include their configuration.
345 # Auto discover authentication plugins and include their configuration.
334 if asbool(settings.get('auth_plugin.import_legacy_plugins', 'true')):
346 if asbool(settings.get('auth_plugin.import_legacy_plugins', 'true')):
335 from rhodecode.authentication import discover_legacy_plugins
347 from rhodecode.authentication import discover_legacy_plugins
336 discover_legacy_plugins(config)
348 discover_legacy_plugins(config)
337
349
338 # apps
350 # apps
339 if load_all:
351 if load_all:
340 log.debug('Starting config.include() calls')
352 log.debug('Starting config.include() calls')
341 config.include('rhodecode.api.includeme')
353 config.include('rhodecode.api.includeme')
342 config.include('rhodecode.apps._base.includeme')
354 config.include('rhodecode.apps._base.includeme')
343 config.include('rhodecode.apps._base.navigation.includeme')
355 config.include('rhodecode.apps._base.navigation.includeme')
344 config.include('rhodecode.apps._base.subscribers.includeme')
356 config.include('rhodecode.apps._base.subscribers.includeme')
345 config.include('rhodecode.apps.hovercards.includeme')
357 config.include('rhodecode.apps.hovercards.includeme')
346 config.include('rhodecode.apps.ops.includeme')
358 config.include('rhodecode.apps.ops.includeme')
347 config.include('rhodecode.apps.channelstream.includeme')
359 config.include('rhodecode.apps.channelstream.includeme')
348 config.include('rhodecode.apps.file_store.includeme')
360 config.include('rhodecode.apps.file_store.includeme')
349 config.include('rhodecode.apps.admin.includeme')
361 config.include('rhodecode.apps.admin.includeme')
350 config.include('rhodecode.apps.login.includeme')
362 config.include('rhodecode.apps.login.includeme')
351 config.include('rhodecode.apps.home.includeme')
363 config.include('rhodecode.apps.home.includeme')
352 config.include('rhodecode.apps.journal.includeme')
364 config.include('rhodecode.apps.journal.includeme')
353
365
354 config.include('rhodecode.apps.repository.includeme')
366 config.include('rhodecode.apps.repository.includeme')
355 config.include('rhodecode.apps.repo_group.includeme')
367 config.include('rhodecode.apps.repo_group.includeme')
356 config.include('rhodecode.apps.user_group.includeme')
368 config.include('rhodecode.apps.user_group.includeme')
357 config.include('rhodecode.apps.search.includeme')
369 config.include('rhodecode.apps.search.includeme')
358 config.include('rhodecode.apps.user_profile.includeme')
370 config.include('rhodecode.apps.user_profile.includeme')
359 config.include('rhodecode.apps.user_group_profile.includeme')
371 config.include('rhodecode.apps.user_group_profile.includeme')
360 config.include('rhodecode.apps.my_account.includeme')
372 config.include('rhodecode.apps.my_account.includeme')
361 config.include('rhodecode.apps.gist.includeme')
373 config.include('rhodecode.apps.gist.includeme')
362
374
363 config.include('rhodecode.apps.svn_support.includeme')
375 config.include('rhodecode.apps.svn_support.includeme')
364 config.include('rhodecode.apps.ssh_support.includeme')
376 config.include('rhodecode.apps.ssh_support.includeme')
365 config.include('rhodecode.apps.debug_style')
377 config.include('rhodecode.apps.debug_style')
366
378
367 if load_all:
379 if load_all:
368 config.include('rhodecode.integrations.includeme')
380 config.include('rhodecode.integrations.includeme')
369 config.include('rhodecode.integrations.routes.includeme')
381 config.include('rhodecode.integrations.routes.includeme')
370
382
371 config.add_route('rhodecode_support', 'https://rhodecode.com/help/', static=True)
383 config.add_route('rhodecode_support', 'https://rhodecode.com/help/', static=True)
372 settings['default_locale_name'] = settings.get('lang', 'en')
384 settings['default_locale_name'] = settings.get('lang', 'en')
373 config.add_translation_dirs('rhodecode:i18n/')
385 config.add_translation_dirs('rhodecode:i18n/')
374
386
375 # Add subscribers.
387 # Add subscribers.
376 if load_all:
388 if load_all:
377 log.debug('Adding subscribers....')
389 log.debug('Adding subscribers....')
378 config.add_subscriber(scan_repositories_if_enabled,
390 config.add_subscriber(scan_repositories_if_enabled,
379 pyramid.events.ApplicationCreated)
391 pyramid.events.ApplicationCreated)
380 config.add_subscriber(write_metadata_if_needed,
392 config.add_subscriber(write_metadata_if_needed,
381 pyramid.events.ApplicationCreated)
393 pyramid.events.ApplicationCreated)
382 config.add_subscriber(write_usage_data,
394 config.add_subscriber(write_usage_data,
383 pyramid.events.ApplicationCreated)
395 pyramid.events.ApplicationCreated)
384 config.add_subscriber(write_js_routes_if_enabled,
396 config.add_subscriber(write_js_routes_if_enabled,
385 pyramid.events.ApplicationCreated)
397 pyramid.events.ApplicationCreated)
386
398
387 # Set the authorization policy.
388 authz_policy = ACLAuthorizationPolicy()
389 config.set_authorization_policy(authz_policy)
390
399
391 # Set the default renderer for HTML templates to mako.
400 # Set the default renderer for HTML templates to mako.
392 config.add_mako_renderer('.html')
401 config.add_mako_renderer('.html')
393
402
394 config.add_renderer(
403 config.add_renderer(
395 name='json_ext',
404 name='json_ext',
396 factory='rhodecode.lib.ext_json_renderer.pyramid_ext_json')
405 factory='rhodecode.lib.ext_json_renderer.pyramid_ext_json')
397
406
398 config.add_renderer(
407 config.add_renderer(
399 name='string_html',
408 name='string_html',
400 factory='rhodecode.lib.string_renderer.html')
409 factory='rhodecode.lib.string_renderer.html')
401
410
402 # include RhodeCode plugins
411 # include RhodeCode plugins
403 includes = aslist(settings.get('rhodecode.includes', []))
412 includes = aslist(settings.get('rhodecode.includes', []))
404 log.debug('processing rhodecode.includes data...')
413 log.debug('processing rhodecode.includes data...')
405 for inc in includes:
414 for inc in includes:
406 config.include(inc)
415 config.include(inc)
407
416
408 # custom not found view, if our pyramid app doesn't know how to handle
417 # custom not found view, if our pyramid app doesn't know how to handle
409 # the request pass it to potential VCS handling ap
418 # the request pass it to potential VCS handling ap
410 config.add_notfound_view(not_found_view)
419 config.add_notfound_view(not_found_view)
411 if not settings.get('debugtoolbar.enabled', False):
420 if not settings.get('debugtoolbar.enabled', False):
412 # disabled debugtoolbar handle all exceptions via the error_handlers
421 # disabled debugtoolbar handle all exceptions via the error_handlers
413 config.add_view(error_handler, context=Exception)
422 config.add_view(error_handler, context=Exception)
414
423
415 # all errors including 403/404/50X
424 # all errors including 403/404/50X
416 config.add_view(error_handler, context=HTTPError)
425 config.add_view(error_handler, context=HTTPError)
417
426
418
427
419 def wrap_app_in_wsgi_middlewares(pyramid_app, config):
428 def wrap_app_in_wsgi_middlewares(pyramid_app, config):
420 """
429 """
421 Apply outer WSGI middlewares around the application.
430 Apply outer WSGI middlewares around the application.
422 """
431 """
423 registry = config.registry
432 registry = config.registry
424 settings = registry.settings
433 settings = registry.settings
425
434
426 # enable https redirects based on HTTP_X_URL_SCHEME set by proxy
435 # enable https redirects based on HTTP_X_URL_SCHEME set by proxy
427 pyramid_app = HttpsFixup(pyramid_app, settings)
436 pyramid_app = HttpsFixup(pyramid_app, settings)
428
437
429 pyramid_app, _ae_client = wrap_in_appenlight_if_enabled(
438 pyramid_app, _ae_client = wrap_in_appenlight_if_enabled(
430 pyramid_app, settings)
439 pyramid_app, settings)
431 registry.ae_client = _ae_client
440 registry.ae_client = _ae_client
432
441
433 if settings['gzip_responses']:
442 if settings['gzip_responses']:
434 pyramid_app = make_gzip_middleware(
443 pyramid_app = make_gzip_middleware(
435 pyramid_app, settings, compress_level=1)
444 pyramid_app, settings, compress_level=1)
436
445
437 # this should be the outer most middleware in the wsgi stack since
446 # this should be the outer most middleware in the wsgi stack since
438 # middleware like Routes make database calls
447 # middleware like Routes make database calls
439 def pyramid_app_with_cleanup(environ, start_response):
448 def pyramid_app_with_cleanup(environ, start_response):
440 start = time.time()
449 start = time.time()
441 try:
450 try:
442 return pyramid_app(environ, start_response)
451 return pyramid_app(environ, start_response)
443 finally:
452 finally:
444 # Dispose current database session and rollback uncommitted
453 # Dispose current database session and rollback uncommitted
445 # transactions.
454 # transactions.
446 meta.Session.remove()
455 meta.Session.remove()
447
456
448 # In a single threaded mode server, on non sqlite db we should have
457 # In a single threaded mode server, on non sqlite db we should have
449 # '0 Current Checked out connections' at the end of a request,
458 # '0 Current Checked out connections' at the end of a request,
450 # if not, then something, somewhere is leaving a connection open
459 # if not, then something, somewhere is leaving a connection open
451 pool = meta.Base.metadata.bind.engine.pool
460 pool = meta.get_engine().pool
452 log.debug('sa pool status: %s', pool.status())
461 log.debug('sa pool status: %s', pool.status())
453 total = time.time() - start
462 total = time.time() - start
454 log.debug('Request processing finalized: %.4fs', total)
463 log.debug('Request processing finalized: %.4fs', total)
455
464
456 return pyramid_app_with_cleanup
465 return pyramid_app_with_cleanup
457
466
458
467
459 def sanitize_settings_and_apply_defaults(global_config, settings):
468 def sanitize_settings_and_apply_defaults(global_config, settings):
460 """
469 """
461 Applies settings defaults and does all type conversion.
470 Applies settings defaults and does all type conversion.
462
471
463 We would move all settings parsing and preparation into this place, so that
472 We would move all settings parsing and preparation into this place, so that
464 we have only one place left which deals with this part. The remaining parts
473 we have only one place left which deals with this part. The remaining parts
465 of the application would start to rely fully on well prepared settings.
474 of the application would start to rely fully on well prepared settings.
466
475
467 This piece would later be split up per topic to avoid a big fat monster
476 This piece would later be split up per topic to avoid a big fat monster
468 function.
477 function.
469 """
478 """
470
479
471 global_settings_maker = SettingsMaker(global_config)
480 global_settings_maker = SettingsMaker(global_config)
472 global_settings_maker.make_setting('debug', default=False, parser='bool')
481 global_settings_maker.make_setting('debug', default=False, parser='bool')
473 debug_enabled = asbool(global_config.get('debug'))
482 debug_enabled = asbool(global_config.get('debug'))
474
483
475 settings_maker = SettingsMaker(settings)
484 settings_maker = SettingsMaker(settings)
476
485
477 settings_maker.make_setting(
486 settings_maker.make_setting(
478 'logging.autoconfigure',
487 'logging.autoconfigure',
479 default=False,
488 default=False,
480 parser='bool')
489 parser='bool')
481
490
482 logging_conf = os.path.join(os.path.dirname(global_config.get('__file__')), 'logging.ini')
491 logging_conf = os.path.join(os.path.dirname(global_config.get('__file__')), 'logging.ini')
483 settings_maker.enable_logging(logging_conf, level='INFO' if debug_enabled else 'DEBUG')
492 settings_maker.enable_logging(logging_conf, level='INFO' if debug_enabled else 'DEBUG')
484
493
485 # Default includes, possible to change as a user
494 # Default includes, possible to change as a user
486 pyramid_includes = settings_maker.make_setting('pyramid.includes', [], parser='list:newline')
495 pyramid_includes = settings_maker.make_setting('pyramid.includes', [], parser='list:newline')
487 log.debug(
496 log.debug(
488 "Using the following pyramid.includes: %s",
497 "Using the following pyramid.includes: %s",
489 pyramid_includes)
498 pyramid_includes)
490
499
491 settings_maker.make_setting('rhodecode.edition', 'Community Edition')
500 settings_maker.make_setting('rhodecode.edition', 'Community Edition')
492 settings_maker.make_setting('rhodecode.edition_id', 'CE')
501 settings_maker.make_setting('rhodecode.edition_id', 'CE')
493
502
494 if 'mako.default_filters' not in settings:
503 if 'mako.default_filters' not in settings:
495 # set custom default filters if we don't have it defined
504 # set custom default filters if we don't have it defined
496 settings['mako.imports'] = 'from rhodecode.lib.base import h_filter'
505 settings['mako.imports'] = 'from rhodecode.lib.base import h_filter'
497 settings['mako.default_filters'] = 'h_filter'
506 settings['mako.default_filters'] = 'h_filter'
498
507
499 if 'mako.directories' not in settings:
508 if 'mako.directories' not in settings:
500 mako_directories = settings.setdefault('mako.directories', [
509 mako_directories = settings.setdefault('mako.directories', [
501 # Base templates of the original application
510 # Base templates of the original application
502 'rhodecode:templates',
511 'rhodecode:templates',
503 ])
512 ])
504 log.debug(
513 log.debug(
505 "Using the following Mako template directories: %s",
514 "Using the following Mako template directories: %s",
506 mako_directories)
515 mako_directories)
507
516
508 # NOTE(marcink): fix redis requirement for schema of connection since 3.X
517 # NOTE(marcink): fix redis requirement for schema of connection since 3.X
509 if 'beaker.session.type' in settings and settings['beaker.session.type'] == 'ext:redis':
518 if 'beaker.session.type' in settings and settings['beaker.session.type'] == 'ext:redis':
510 raw_url = settings['beaker.session.url']
519 raw_url = settings['beaker.session.url']
511 if not raw_url.startswith(('redis://', 'rediss://', 'unix://')):
520 if not raw_url.startswith(('redis://', 'rediss://', 'unix://')):
512 settings['beaker.session.url'] = 'redis://' + raw_url
521 settings['beaker.session.url'] = 'redis://' + raw_url
513
522
514 settings_maker.make_setting('__file__', global_config.get('__file__'))
523 settings_maker.make_setting('__file__', global_config.get('__file__'))
515
524
516 # TODO: johbo: Re-think this, usually the call to config.include
525 # TODO: johbo: Re-think this, usually the call to config.include
517 # should allow to pass in a prefix.
526 # should allow to pass in a prefix.
518 settings_maker.make_setting('rhodecode.api.url', '/_admin/api')
527 settings_maker.make_setting('rhodecode.api.url', '/_admin/api')
519
528
520 # Sanitize generic settings.
529 # Sanitize generic settings.
521 settings_maker.make_setting('default_encoding', 'UTF-8', parser='list')
530 settings_maker.make_setting('default_encoding', 'UTF-8', parser='list')
522 settings_maker.make_setting('is_test', False, parser='bool')
531 settings_maker.make_setting('is_test', False, parser='bool')
523 settings_maker.make_setting('gzip_responses', False, parser='bool')
532 settings_maker.make_setting('gzip_responses', False, parser='bool')
524
533
525 # statsd
534 # statsd
526 settings_maker.make_setting('statsd.enabled', False, parser='bool')
535 settings_maker.make_setting('statsd.enabled', False, parser='bool')
527 settings_maker.make_setting('statsd.statsd_host', 'statsd-exporter', parser='string')
536 settings_maker.make_setting('statsd.statsd_host', 'statsd-exporter', parser='string')
528 settings_maker.make_setting('statsd.statsd_port', 9125, parser='int')
537 settings_maker.make_setting('statsd.statsd_port', 9125, parser='int')
529 settings_maker.make_setting('statsd.statsd_prefix', '')
538 settings_maker.make_setting('statsd.statsd_prefix', '')
530 settings_maker.make_setting('statsd.statsd_ipv6', False, parser='bool')
539 settings_maker.make_setting('statsd.statsd_ipv6', False, parser='bool')
531
540
532 settings_maker.make_setting('vcs.svn.compatible_version', '')
541 settings_maker.make_setting('vcs.svn.compatible_version', '')
533 settings_maker.make_setting('vcs.hooks.protocol', 'http')
542 settings_maker.make_setting('vcs.hooks.protocol', 'http')
534 settings_maker.make_setting('vcs.hooks.host', '127.0.0.1')
543 settings_maker.make_setting('vcs.hooks.host', '*')
535 settings_maker.make_setting('vcs.scm_app_implementation', 'http')
544 settings_maker.make_setting('vcs.scm_app_implementation', 'http')
536 settings_maker.make_setting('vcs.server', '')
545 settings_maker.make_setting('vcs.server', '')
537 settings_maker.make_setting('vcs.server.protocol', 'http')
546 settings_maker.make_setting('vcs.server.protocol', 'http')
538 settings_maker.make_setting('vcs.server.enable', 'true', parser='bool')
547 settings_maker.make_setting('vcs.server.enable', 'true', parser='bool')
539 settings_maker.make_setting('startup.import_repos', 'false', parser='bool')
548 settings_maker.make_setting('startup.import_repos', 'false', parser='bool')
540 settings_maker.make_setting('vcs.hooks.direct_calls', 'false', parser='bool')
549 settings_maker.make_setting('vcs.hooks.direct_calls', 'false', parser='bool')
541 settings_maker.make_setting('vcs.start_server', 'false', parser='bool')
550 settings_maker.make_setting('vcs.start_server', 'false', parser='bool')
542 settings_maker.make_setting('vcs.backends', 'hg, git, svn', parser='list')
551 settings_maker.make_setting('vcs.backends', 'hg, git, svn', parser='list')
543 settings_maker.make_setting('vcs.connection_timeout', 3600, parser='int')
552 settings_maker.make_setting('vcs.connection_timeout', 3600, parser='int')
544
553
545 settings_maker.make_setting('vcs.methods.cache', True, parser='bool')
554 settings_maker.make_setting('vcs.methods.cache', True, parser='bool')
546
555
547 # Support legacy values of vcs.scm_app_implementation. Legacy
556 # Support legacy values of vcs.scm_app_implementation. Legacy
548 # configurations may use 'rhodecode.lib.middleware.utils.scm_app_http', or
557 # configurations may use 'rhodecode.lib.middleware.utils.scm_app_http', or
549 # disabled since 4.13 'vcsserver.scm_app' which is now mapped to 'http'.
558 # disabled since 4.13 'vcsserver.scm_app' which is now mapped to 'http'.
550 scm_app_impl = settings['vcs.scm_app_implementation']
559 scm_app_impl = settings['vcs.scm_app_implementation']
551 if scm_app_impl in ['rhodecode.lib.middleware.utils.scm_app_http', 'vcsserver.scm_app']:
560 if scm_app_impl in ['rhodecode.lib.middleware.utils.scm_app_http', 'vcsserver.scm_app']:
552 settings['vcs.scm_app_implementation'] = 'http'
561 settings['vcs.scm_app_implementation'] = 'http'
553
562
554 settings_maker.make_setting('appenlight', False, parser='bool')
563 settings_maker.make_setting('appenlight', False, parser='bool')
555
564
556 temp_store = tempfile.gettempdir()
565 temp_store = tempfile.gettempdir()
557 tmp_cache_dir = os.path.join(temp_store, 'rc_cache')
566 tmp_cache_dir = os.path.join(temp_store, 'rc_cache')
558
567
559 # save default, cache dir, and use it for all backends later.
568 # save default, cache dir, and use it for all backends later.
560 default_cache_dir = settings_maker.make_setting(
569 default_cache_dir = settings_maker.make_setting(
561 'cache_dir',
570 'cache_dir',
562 default=tmp_cache_dir, default_when_empty=True,
571 default=tmp_cache_dir, default_when_empty=True,
563 parser='dir:ensured')
572 parser='dir:ensured')
564
573
565 # exception store cache
574 # exception store cache
566 settings_maker.make_setting(
575 settings_maker.make_setting(
567 'exception_tracker.store_path',
576 'exception_tracker.store_path',
568 default=os.path.join(default_cache_dir, 'exc_store'), default_when_empty=True,
577 default=os.path.join(default_cache_dir, 'exc_store'), default_when_empty=True,
569 parser='dir:ensured'
578 parser='dir:ensured'
570 )
579 )
571
580
572 settings_maker.make_setting(
581 settings_maker.make_setting(
573 'celerybeat-schedule.path',
582 'celerybeat-schedule.path',
574 default=os.path.join(default_cache_dir, 'celerybeat_schedule', 'celerybeat-schedule.db'), default_when_empty=True,
583 default=os.path.join(default_cache_dir, 'celerybeat_schedule', 'celerybeat-schedule.db'), default_when_empty=True,
575 parser='file:ensured'
584 parser='file:ensured'
576 )
585 )
577
586
578 settings_maker.make_setting('exception_tracker.send_email', False, parser='bool')
587 settings_maker.make_setting('exception_tracker.send_email', False, parser='bool')
579 settings_maker.make_setting('exception_tracker.email_prefix', '[RHODECODE ERROR]', default_when_empty=True)
588 settings_maker.make_setting('exception_tracker.email_prefix', '[RHODECODE ERROR]', default_when_empty=True)
580
589
581 # cache_general
590 # cache_general
582 settings_maker.make_setting('rc_cache.cache_general.backend', 'dogpile.cache.rc.file_namespace')
591 settings_maker.make_setting('rc_cache.cache_general.backend', 'dogpile.cache.rc.file_namespace')
583 settings_maker.make_setting('rc_cache.cache_general.expiration_time', 60 * 60 * 12, parser='int')
592 settings_maker.make_setting('rc_cache.cache_general.expiration_time', 60 * 60 * 12, parser='int')
584 settings_maker.make_setting('rc_cache.cache_general.arguments.filename', os.path.join(default_cache_dir, 'rhodecode_cache_general.db'))
593 settings_maker.make_setting('rc_cache.cache_general.arguments.filename', os.path.join(default_cache_dir, 'rhodecode_cache_general.db'))
585
594
586 # cache_perms
595 # cache_perms
587 settings_maker.make_setting('rc_cache.cache_perms.backend', 'dogpile.cache.rc.file_namespace')
596 settings_maker.make_setting('rc_cache.cache_perms.backend', 'dogpile.cache.rc.file_namespace')
588 settings_maker.make_setting('rc_cache.cache_perms.expiration_time', 60 * 60, parser='int')
597 settings_maker.make_setting('rc_cache.cache_perms.expiration_time', 60 * 60, parser='int')
589 settings_maker.make_setting('rc_cache.cache_perms.arguments.filename', os.path.join(default_cache_dir, 'rhodecode_cache_perms.db'))
598 settings_maker.make_setting('rc_cache.cache_perms.arguments.filename', os.path.join(default_cache_dir, 'rhodecode_cache_perms_db'))
590
599
591 # cache_repo
600 # cache_repo
592 settings_maker.make_setting('rc_cache.cache_repo.backend', 'dogpile.cache.rc.file_namespace')
601 settings_maker.make_setting('rc_cache.cache_repo.backend', 'dogpile.cache.rc.file_namespace')
593 settings_maker.make_setting('rc_cache.cache_repo.expiration_time', 60 * 60 * 24 * 30, parser='int')
602 settings_maker.make_setting('rc_cache.cache_repo.expiration_time', 60 * 60 * 24 * 30, parser='int')
594 settings_maker.make_setting('rc_cache.cache_repo.arguments.filename', os.path.join(default_cache_dir, 'rhodecode_cache_repo.db'))
603 settings_maker.make_setting('rc_cache.cache_repo.arguments.filename', os.path.join(default_cache_dir, 'rhodecode_cache_repo_db'))
595
604
596 # cache_license
605 # cache_license
597 settings_maker.make_setting('rc_cache.cache_license.backend', 'dogpile.cache.rc.file_namespace')
606 settings_maker.make_setting('rc_cache.cache_license.backend', 'dogpile.cache.rc.file_namespace')
598 settings_maker.make_setting('rc_cache.cache_license.expiration_time', 60 * 5, parser='int')
607 settings_maker.make_setting('rc_cache.cache_license.expiration_time', 60 * 5, parser='int')
599 settings_maker.make_setting('rc_cache.cache_license.arguments.filename', os.path.join(default_cache_dir, 'rhodecode_cache_license.db'))
608 settings_maker.make_setting('rc_cache.cache_license.arguments.filename', os.path.join(default_cache_dir, 'rhodecode_cache_license_db'))
600
609
601 # cache_repo_longterm memory, 96H
610 # cache_repo_longterm memory, 96H
602 settings_maker.make_setting('rc_cache.cache_repo_longterm.backend', 'dogpile.cache.rc.memory_lru')
611 settings_maker.make_setting('rc_cache.cache_repo_longterm.backend', 'dogpile.cache.rc.memory_lru')
603 settings_maker.make_setting('rc_cache.cache_repo_longterm.expiration_time', 345600, parser='int')
612 settings_maker.make_setting('rc_cache.cache_repo_longterm.expiration_time', 345600, parser='int')
604 settings_maker.make_setting('rc_cache.cache_repo_longterm.max_size', 10000, parser='int')
613 settings_maker.make_setting('rc_cache.cache_repo_longterm.max_size', 10000, parser='int')
605
614
606 # sql_cache_short
615 # sql_cache_short
607 settings_maker.make_setting('rc_cache.sql_cache_short.backend', 'dogpile.cache.rc.memory_lru')
616 settings_maker.make_setting('rc_cache.sql_cache_short.backend', 'dogpile.cache.rc.memory_lru')
608 settings_maker.make_setting('rc_cache.sql_cache_short.expiration_time', 30, parser='int')
617 settings_maker.make_setting('rc_cache.sql_cache_short.expiration_time', 30, parser='int')
609 settings_maker.make_setting('rc_cache.sql_cache_short.max_size', 10000, parser='int')
618 settings_maker.make_setting('rc_cache.sql_cache_short.max_size', 10000, parser='int')
610
619
620 # archive_cache
621 settings_maker.make_setting('archive_cache.store_dir', os.path.join(default_cache_dir, 'archive_cache'), default_when_empty=True,)
622 settings_maker.make_setting('archive_cache.cache_size_gb', 10, parser='float')
623 settings_maker.make_setting('archive_cache.cache_shards', 10, parser='int')
624
611 settings_maker.env_expand()
625 settings_maker.env_expand()
612
626
613 # configure instance id
627 # configure instance id
614 config_utils.set_instance_id(settings)
628 config_utils.set_instance_id(settings)
615
629
616 return settings
630 return settings
@@ -1,99 +1,100 b''
1
1
2
2
3 # Copyright (C) 2016-2020 RhodeCode GmbH
3 # Copyright (C) 2016-2020 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the 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 Compatibility patches.
22 Compatibility patches.
23
23
24 Please keep the following principles in mind:
24 Please keep the following principles in mind:
25
25
26 * Keep imports local, so that importing this module does not cause too many
26 * Keep imports local, so that importing this module does not cause too many
27 side effects by itself.
27 side effects by itself.
28
28
29 * Try to make patches idempotent, calling them multiple times should not do
29 * Try to make patches idempotent, calling them multiple times should not do
30 harm. If that is not possible, ensure that the second call explodes.
30 harm. If that is not possible, ensure that the second call explodes.
31
31
32 """
32 """
33
33
34
34
35 def inspect_getargspec():
35 def inspect_getargspec():
36 """
36 """
37 Pyramid rely on inspect.getargspec to lookup the signature of
37 Pyramid rely on inspect.getargspec to lookup the signature of
38 view functions. This is not compatible with cython, therefore we replace
38 view functions. This is not compatible with cython, therefore we replace
39 getargspec with a custom version.
39 getargspec with a custom version.
40 Code is inspired by the inspect module from Python-3.4
40 Code is inspired by the inspect module from Python-3.4
41 """
41 """
42 import inspect
42 import inspect
43
43
44 def _isCython(func):
44 def _isCython(func):
45 """
45 """
46 Private helper that checks if a function is a cython function.
46 Private helper that checks if a function is a cython function.
47 """
47 """
48 return func.__class__.__name__ == 'cython_function_or_method'
48 return func.__class__.__name__ == 'cython_function_or_method'
49
49
50 def unwrap(func):
50 def unwrap(func):
51 """
51 """
52 Get the object wrapped by *func*.
52 Get the object wrapped by *func*.
53
53
54 Follows the chain of :attr:`__wrapped__` attributes returning the last
54 Follows the chain of :attr:`__wrapped__` attributes returning the last
55 object in the chain.
55 object in the chain.
56
56
57 *stop* is an optional callback accepting an object in the wrapper chain
57 *stop* is an optional callback accepting an object in the wrapper chain
58 as its sole argument that allows the unwrapping to be terminated early
58 as its sole argument that allows the unwrapping to be terminated early
59 if the callback returns a true value. If the callback never returns a
59 if the callback returns a true value. If the callback never returns a
60 true value, the last object in the chain is returned as usual. For
60 true value, the last object in the chain is returned as usual. For
61 example, :func:`signature` uses this to stop unwrapping if any object
61 example, :func:`signature` uses this to stop unwrapping if any object
62 in the chain has a ``__signature__`` attribute defined.
62 in the chain has a ``__signature__`` attribute defined.
63
63
64 :exc:`ValueError` is raised if a cycle is encountered.
64 :exc:`ValueError` is raised if a cycle is encountered.
65 """
65 """
66 f = func # remember the original func for error reporting
66 f = func # remember the original func for error reporting
67 memo = {id(f)} # Memoise by id to tolerate non-hashable objects
67 memo = {id(f)} # Memoise by id to tolerate non-hashable objects
68 while hasattr(func, '__wrapped__'):
68 while hasattr(func, '__wrapped__'):
69 func = func.__wrapped__
69 func = func.__wrapped__
70 id_func = id(func)
70 id_func = id(func)
71 if id_func in memo:
71 if id_func in memo:
72 raise ValueError('wrapper loop when unwrapping {!r}'.format(f))
72 raise ValueError('wrapper loop when unwrapping {!r}'.format(f))
73 memo.add(id_func)
73 memo.add(id_func)
74 return func
74 return func
75
75
76 def custom_getargspec(func):
76 def custom_getargspec(func):
77 """
77 """
78 Get the names and default values of a function's arguments.
78 Get the names and default values of a function's arguments.
79
79
80 A tuple of four things is returned: (args, varargs, varkw, defaults).
80 A tuple of four things is returned: (args, varargs, varkw, defaults).
81 'args' is a list of the argument names (it may contain nested lists).
81 'args' is a list of the argument names (it may contain nested lists).
82 'varargs' and 'varkw' are the names of the * and ** arguments or None.
82 'varargs' and 'varkw' are the names of the * and ** arguments or None.
83 'defaults' is an n-tuple of the default values of the last n arguments.
83 'defaults' is an n-tuple of the default values of the last n arguments.
84 """
84 """
85
85
86 func = unwrap(func)
86 func = unwrap(func)
87
87
88 if inspect.ismethod(func):
88 if inspect.ismethod(func):
89 func = func.im_func
89 func = func.im_func
90 if not inspect.isfunction(func):
90 if not inspect.isfunction(func):
91 if not _isCython(func):
91 if not _isCython(func):
92 raise TypeError('{!r} is not a Python or Cython function'
92 raise TypeError('{!r} is not a Python or Cython function'
93 .format(func))
93 .format(func))
94 args, varargs, varkw = inspect.getargs(func.func_code)
94 args, varargs, varkw = inspect.getargs(func.func_code)
95 return inspect.ArgSpec(args, varargs, varkw, func.func_defaults)
95 return inspect.ArgSpec(args, varargs, varkw, func.func_defaults)
96
96
97 inspect.getargspec = custom_getargspec
97 #TODO: fix it and test it on python3.11
98 inspect.getargspec = inspect.getfullargspec #custom_getargspec
98
99
99 return inspect
100 return inspect
@@ -1,147 +1,147 b''
1
1
2 # Copyright (C) 2016-2020 RhodeCode GmbH
2 # Copyright (C) 2016-2020 RhodeCode GmbH
3 #
3 #
4 # This program is free software: you can redistribute it and/or modify
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU Affero General Public License, version 3
5 # it under the terms of the GNU Affero General Public License, version 3
6 # (only), as published by the Free Software Foundation.
6 # (only), as published by the Free Software Foundation.
7 #
7 #
8 # This program is distributed in the hope that it will be useful,
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
11 # GNU General Public License for more details.
12 #
12 #
13 # You should have received a copy of the GNU Affero General Public License
13 # You should have received a copy of the GNU Affero General Public License
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 #
15 #
16 # This program is dual-licensed. If you wish to learn more about the
16 # This program is dual-licensed. If you wish to learn more about the
17 # RhodeCode Enterprise Edition, including its added features, Support services,
17 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # and proprietary license terms, please see https://rhodecode.com/licenses/
18 # and proprietary license terms, please see https://rhodecode.com/licenses/
19
19
20 """
20 """
21 us in hooks::
21 us in hooks::
22
22
23 from .helpers import extract_pre_files
23 from .helpers import extract_pre_files
24 # returns list of dicts with key-val fetched from extra fields
24 # returns list of dicts with key-val fetched from extra fields
25 file_list = extract_pre_files.run(**kwargs)
25 file_list = extract_pre_files.run(**kwargs)
26
26
27 """
27 """
28 import re
28 import re
29 import collections
29 import collections
30 import json
30 import json
31
31
32 from rhodecode.lib import diffs
32 from rhodecode.lib import diffs
33 from rhodecode.lib.vcs.backends.hg.diff import MercurialDiff
33 from rhodecode.lib.vcs.backends.hg.diff import MercurialDiff
34 from rhodecode.lib.vcs.backends.git.diff import GitDiff
34 from rhodecode.lib.vcs.backends.git.diff import GitDiff
35 from vcsserver.utils import safe_int
35 from rhodecode.lib.str_utils import safe_int
36
36
37
37
38 def get_svn_files(repo, vcs_repo, refs):
38 def get_svn_files(repo, vcs_repo, refs):
39 txn_id = refs[0]
39 txn_id = refs[0]
40 files = []
40 files = []
41
41
42 stdout, stderr = vcs_repo.run_svn_command(
42 stdout, stderr = vcs_repo.run_svn_command(
43 ['svnlook', 'changed', repo.repo_full_path, '--transaction', txn_id])
43 ['svnlook', 'changed', repo.repo_full_path, '--transaction', txn_id])
44
44
45 svn_op_to_rc_op = {
45 svn_op_to_rc_op = {
46 'A': 'A',
46 'A': 'A',
47 'U': 'M',
47 'U': 'M',
48 'D': 'D',
48 'D': 'D',
49 }
49 }
50
50
51 for entry in stdout.splitlines():
51 for entry in stdout.splitlines():
52 parsed_entry = {
52 parsed_entry = {
53 'raw_diff': '',
53 'raw_diff': '',
54 'filename': '',
54 'filename': '',
55 'chunks': [],
55 'chunks': [],
56 'ops': {},
56 'ops': {},
57 'file_size': 0
57 'file_size': 0
58 }
58 }
59
59
60 op = entry[0]
60 op = entry[0]
61 path = entry[1:].strip()
61 path = entry[1:].strip()
62
62
63 rc_op = svn_op_to_rc_op.get(op) or '?'
63 rc_op = svn_op_to_rc_op.get(op) or '?'
64 parsed_entry['filename'] = path
64 parsed_entry['filename'] = path
65 parsed_entry['operation'] = rc_op
65 parsed_entry['operation'] = rc_op
66
66
67 if rc_op in ['A', 'M']:
67 if rc_op in ['A', 'M']:
68
68
69 stdout, stderr = vcs_repo.run_svn_command(
69 stdout, stderr = vcs_repo.run_svn_command(
70 ['svnlook', 'filesize', repo.repo_full_path, path, '--transaction', txn_id],
70 ['svnlook', 'filesize', repo.repo_full_path, path, '--transaction', txn_id],
71 _safe=True
71 _safe=True
72 )
72 )
73
73
74 if "Path '{}' is not a file".format(path.rstrip('/')) in stderr:
74 if "Path '{}' is not a file".format(path.rstrip('/')) in stderr:
75 # skip dirs
75 # skip dirs
76 continue
76 continue
77
77
78 parsed_entry['file_size'] = safe_int(stdout.strip()) or 0
78 parsed_entry['file_size'] = safe_int(stdout.strip()) or 0
79
79
80 files.append(parsed_entry)
80 files.append(parsed_entry)
81
81
82 return files
82 return files
83
83
84
84
85 def get_hg_files(repo, vcs_repo, refs):
85 def get_hg_files(repo, vcs_repo, refs):
86 files = []
86 files = []
87 return files
87 return files
88
88
89
89
90 def get_git_files(repo, vcs_repo, refs):
90 def get_git_files(repo, vcs_repo, refs):
91 files = []
91 files = []
92
92
93 for data in refs:
93 for data in refs:
94 # we should now extract commit data
94 # we should now extract commit data
95 old_rev = data['old_rev']
95 old_rev = data['old_rev']
96 new_rev = data['new_rev']
96 new_rev = data['new_rev']
97
97
98 if '00000000' in old_rev:
98 if '00000000' in old_rev:
99 # new branch, we don't need to extract nothing
99 # new branch, we don't need to extract nothing
100 return files
100 return files
101
101
102 git_env = dict(data['git_env'])
102 git_env = dict(data['git_env'])
103
103
104 cmd = [
104 cmd = [
105 'diff', old_rev, new_rev
105 'diff', old_rev, new_rev
106 ]
106 ]
107
107
108 stdout, stderr = vcs_repo.run_git_command(cmd, extra_env=git_env)
108 stdout, stderr = vcs_repo.run_git_command(cmd, extra_env=git_env)
109 vcs_diff = GitDiff(stdout)
109 vcs_diff = GitDiff(stdout)
110
110
111 diff_processor = diffs.DiffProcessor(vcs_diff, format='newdiff')
111 diff_processor = diffs.DiffProcessor(vcs_diff, diff_format='newdiff')
112 # this is list of dicts with diff information
112 # this is list of dicts with diff information
113 # _parsed[0].keys()
113 # _parsed[0].keys()
114 # ['raw_diff', 'old_revision', 'stats', 'original_filename',
114 # ['raw_diff', 'old_revision', 'stats', 'original_filename',
115 # 'is_limited_diff', 'chunks', 'new_revision', 'operation',
115 # 'is_limited_diff', 'chunks', 'new_revision', 'operation',
116 # 'exceeds_limit', 'filename']
116 # 'exceeds_limit', 'filename']
117 files = _parsed = diff_processor.prepare()
117 files = _parsed = diff_processor.prepare()
118
118
119 return files
119 return files
120
120
121
121
122 def run(*args, **kwargs):
122 def run(*args, **kwargs):
123 from rhodecode.model.db import Repository
123 from rhodecode.model.db import Repository
124
124
125 vcs_type = kwargs['scm']
125 vcs_type = kwargs['scm']
126 # use temp name then the main one propagated
126 # use temp name then the main one propagated
127 repo_name = kwargs.pop('REPOSITORY', None) or kwargs['repository']
127 repo_name = kwargs.pop('REPOSITORY', None) or kwargs['repository']
128
128
129 repo = Repository.get_by_repo_name(repo_name)
129 repo = Repository.get_by_repo_name(repo_name)
130 vcs_repo = repo.scm_instance(cache=False)
130 vcs_repo = repo.scm_instance(cache=False)
131
131
132 files = []
132 files = []
133
133
134 if vcs_type == 'git':
134 if vcs_type == 'git':
135 for rev_data in kwargs['commit_ids']:
135 for rev_data in kwargs['commit_ids']:
136 new_environ = dict((k, v) for k, v in rev_data['git_env'])
136 new_environ = dict((k, v) for k, v in rev_data['git_env'])
137 files = get_git_files(repo, vcs_repo, kwargs['commit_ids'])
137 files = get_git_files(repo, vcs_repo, kwargs['commit_ids'])
138
138
139 if vcs_type == 'hg':
139 if vcs_type == 'hg':
140 for rev_data in kwargs['commit_ids']:
140 for rev_data in kwargs['commit_ids']:
141 new_environ = dict((k, v) for k, v in rev_data['hg_env'])
141 new_environ = dict((k, v) for k, v in rev_data['hg_env'])
142 files = get_hg_files(repo, vcs_repo, kwargs['commit_ids'])
142 files = get_hg_files(repo, vcs_repo, kwargs['commit_ids'])
143
143
144 if vcs_type == 'svn':
144 if vcs_type == 'svn':
145 files = get_svn_files(repo, vcs_repo, kwargs['commit_ids'])
145 files = get_svn_files(repo, vcs_repo, kwargs['commit_ids'])
146
146
147 return files
147 return files
@@ -1,199 +1,200 b''
1 # Copyright (C) 2016-2020 RhodeCode GmbH
1 # Copyright (C) 2016-2020 RhodeCode GmbH
2 #
2 #
3 # This program is free software: you can redistribute it and/or modify
3 # This program is free software: you can redistribute it and/or modify
4 # it under the terms of the GNU Affero General Public License, version 3
4 # it under the terms of the GNU Affero General Public License, version 3
5 # (only), as published by the Free Software Foundation.
5 # (only), as published by the Free Software Foundation.
6 #
6 #
7 # This program is distributed in the hope that it will be useful,
7 # This program is distributed in the hope that it will be useful,
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # GNU General Public License for more details.
10 # GNU General Public License for more details.
11 #
11 #
12 # You should have received a copy of the GNU Affero General Public License
12 # You should have received a copy of the GNU Affero General Public License
13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 #
14 #
15 # This program is dual-licensed. If you wish to learn more about the
15 # This program is dual-licensed. If you wish to learn more about the
16 # RhodeCode Enterprise Edition, including its added features, Support services,
16 # RhodeCode Enterprise Edition, including its added features, Support services,
17 # and proprietary license terms, please see https://rhodecode.com/licenses/
17 # and proprietary license terms, please see https://rhodecode.com/licenses/
18
18
19 import logging
19 import logging
20 import os
20 import os
21 import string
21 import string
22 import functools
22 import functools
23 import collections
23 import collections
24 import urllib.request, urllib.parse, urllib.error
24 import urllib.request
25 import urllib.parse
26 import urllib.error
25
27
26 log = logging.getLogger('rhodecode.' + __name__)
28 log = logging.getLogger('rhodecode.' + __name__)
27
29
28
30
29 class HookResponse(object):
31 class HookResponse(object):
30 def __init__(self, status, output):
32 def __init__(self, status, output):
31 self.status = status
33 self.status = status
32 self.output = output
34 self.output = output
33
35
34 def __add__(self, other):
36 def __add__(self, other):
35 other_status = getattr(other, 'status', 0)
37 other_status = getattr(other, 'status', 0)
36 new_status = max(self.status, other_status)
38 new_status = max(self.status, other_status)
37 other_output = getattr(other, 'output', '')
39 other_output = getattr(other, 'output', '')
38 new_output = self.output + other_output
40 new_output = self.output + other_output
39
41
40 return HookResponse(new_status, new_output)
42 return HookResponse(new_status, new_output)
41
43
42 def __bool__(self):
44 def __bool__(self):
43 return self.status == 0
45 return self.status == 0
44
46
45
47
46 class DotDict(dict):
48 class DotDict(dict):
47
49
48 def __contains__(self, k):
50 def __contains__(self, k):
49 try:
51 try:
50 return dict.__contains__(self, k) or hasattr(self, k)
52 return dict.__contains__(self, k) or hasattr(self, k)
51 except:
53 except Exception:
52 return False
54 return False
53
55
54 # only called if k not found in normal places
56 # only called if k not found in normal places
55 def __getattr__(self, k):
57 def __getattr__(self, k):
56 try:
58 try:
57 return object.__getattribute__(self, k)
59 return object.__getattribute__(self, k)
58 except AttributeError:
60 except AttributeError:
59 try:
61 try:
60 return self[k]
62 return self[k]
61 except KeyError:
63 except KeyError:
62 raise AttributeError(k)
64 raise AttributeError(k)
63
65
64 def __setattr__(self, k, v):
66 def __setattr__(self, k, v):
65 try:
67 try:
66 object.__getattribute__(self, k)
68 object.__getattribute__(self, k)
67 except AttributeError:
69 except AttributeError:
68 try:
70 try:
69 self[k] = v
71 self[k] = v
70 except:
72 except:
71 raise AttributeError(k)
73 raise AttributeError(k)
72 else:
74 else:
73 object.__setattr__(self, k, v)
75 object.__setattr__(self, k, v)
74
76
75 def __delattr__(self, k):
77 def __delattr__(self, k):
76 try:
78 try:
77 object.__getattribute__(self, k)
79 object.__getattribute__(self, k)
78 except AttributeError:
80 except AttributeError:
79 try:
81 try:
80 del self[k]
82 del self[k]
81 except KeyError:
83 except KeyError:
82 raise AttributeError(k)
84 raise AttributeError(k)
83 else:
85 else:
84 object.__delattr__(self, k)
86 object.__delattr__(self, k)
85
87
86 def toDict(self):
88 def toDict(self):
87 return unserialize(self)
89 return unserialize(self)
88
90
89 def __repr__(self):
91 def __repr__(self):
90 keys = list(self.keys())
92 keys = list(self.keys())
91 keys.sort()
93 keys.sort()
92 args = ', '.join(['%s=%r' % (key, self[key]) for key in keys])
94 args = ', '.join(['%s=%r' % (key, self[key]) for key in keys])
93 return '%s(%s)' % (self.__class__.__name__, args)
95 return '%s(%s)' % (self.__class__.__name__, args)
94
96
95 @staticmethod
97 @staticmethod
96 def fromDict(d):
98 def fromDict(d):
97 return serialize(d)
99 return serialize(d)
98
100
99
101
100 def serialize(x):
102 def serialize(x):
101 if isinstance(x, dict):
103 if isinstance(x, dict):
102 return DotDict((k, serialize(v)) for k, v in x.items())
104 return DotDict((k, serialize(v)) for k, v in x.items())
103 elif isinstance(x, (list, tuple)):
105 elif isinstance(x, (list, tuple)):
104 return type(x)(serialize(v) for v in x)
106 return type(x)(serialize(v) for v in x)
105 else:
107 else:
106 return x
108 return x
107
109
108
110
109 def unserialize(x):
111 def unserialize(x):
110 if isinstance(x, dict):
112 if isinstance(x, dict):
111 return dict((k, unserialize(v)) for k, v in x.items())
113 return dict((k, unserialize(v)) for k, v in x.items())
112 elif isinstance(x, (list, tuple)):
114 elif isinstance(x, (list, tuple)):
113 return type(x)(unserialize(v) for v in x)
115 return type(x)(unserialize(v) for v in x)
114 else:
116 else:
115 return x
117 return x
116
118
117
119
118 def _verify_kwargs(func_name, expected_parameters, kwargs):
120 def _verify_kwargs(func_name, expected_parameters, kwargs):
119 """
121 """
120 Verify that exactly `expected_parameters` are passed in as `kwargs`.
122 Verify that exactly `expected_parameters` are passed in as `kwargs`.
121 """
123 """
122 expected_parameters = set(expected_parameters)
124 expected_parameters = set(expected_parameters)
123 kwargs_keys = set(kwargs.keys())
125 kwargs_keys = set(kwargs.keys())
124 if kwargs_keys != expected_parameters:
126 if kwargs_keys != expected_parameters:
125 missing_kwargs = expected_parameters - kwargs_keys
127 missing_kwargs = expected_parameters - kwargs_keys
126 unexpected_kwargs = kwargs_keys - expected_parameters
128 unexpected_kwargs = kwargs_keys - expected_parameters
127 raise AssertionError(
129 raise AssertionError(
128 "func:%s: missing parameters: %r, unexpected parameters: %s" %
130 "func:%s: missing parameters: %r, unexpected parameters: %s" %
129 (func_name, missing_kwargs, unexpected_kwargs))
131 (func_name, missing_kwargs, unexpected_kwargs))
130
132
131
133
132 def has_kwargs(required_args):
134 def has_kwargs(required_args):
133 """
135 """
134 decorator to verify extension calls arguments.
136 decorator to verify extension calls arguments.
135
137
136 :param required_args:
138 :param required_args:
137 """
139 """
138 def wrap(func):
140 def wrap(func):
139 def wrapper(*args, **kwargs):
141 def wrapper(*args, **kwargs):
140 _verify_kwargs(func.__name__, required_args.keys(), kwargs)
142 _verify_kwargs(func.__name__, required_args.keys(), kwargs)
141 # in case there's `calls` defined on module we store the data
143 # in case there's `calls` defined on module we store the data
142 maybe_log_call(func.__name__, args, kwargs)
144 maybe_log_call(func.__name__, args, kwargs)
143 log.debug('Calling rcextensions function %s', func.__name__)
145 log.debug('Calling rcextensions function %s', func.__name__)
144 return func(*args, **kwargs)
146 return func(*args, **kwargs)
145 return wrapper
147 return wrapper
146 return wrap
148 return wrap
147
149
148
150
149 def maybe_log_call(name, args, kwargs):
151 def maybe_log_call(name, args, kwargs):
150 from rhodecode.config import rcextensions
152 from rhodecode.config import rcextensions
151 if hasattr(rcextensions, 'calls'):
153 if hasattr(rcextensions, 'calls'):
152 calls = rcextensions.calls
154 calls = rcextensions.calls
153 calls[name].append((args, kwargs))
155 calls[name].append((args, kwargs))
154
156
155
157
156 def str2bool(_str):
158 def str2bool(_str) -> bool:
157 """
159 """
158 returns True/False value from given string, it tries to translate the
160 returns True/False value from given string, it tries to translate the
159 string into boolean
161 string into boolean
160
162
161 :param _str: string value to translate into boolean
163 :param _str: string value to translate into boolean
162 :rtype: boolean
164 :returns: bool from given string
163 :returns: boolean from given string
164 """
165 """
165 if _str is None:
166 if _str is None:
166 return False
167 return False
167 if _str in (True, False):
168 if _str in (True, False):
168 return _str
169 return _str
169 _str = str(_str).strip().lower()
170 _str = str(_str).strip().lower()
170 return _str in ('t', 'true', 'y', 'yes', 'on', '1')
171 return _str in ('t', 'true', 'y', 'yes', 'on', '1')
171
172
172
173
173 def aslist(obj, sep=None, strip=True):
174 def aslist(obj, sep=None, strip=True):
174 """
175 """
175 Returns given string separated by sep as list
176 Returns given string separated by sep as list
176
177
177 :param obj:
178 :param obj:
178 :param sep:
179 :param sep:
179 :param strip:
180 :param strip:
180 """
181 """
181 if isinstance(obj, (str,)):
182 if isinstance(obj, (str,)):
182 lst = obj.split(sep)
183 lst = obj.split(sep)
183 if strip:
184 if strip:
184 lst = [v.strip() for v in lst]
185 lst = [v.strip() for v in lst]
185 return lst
186 return lst
186 elif isinstance(obj, (list, tuple)):
187 elif isinstance(obj, (list, tuple)):
187 return obj
188 return obj
188 elif obj is None:
189 elif obj is None:
189 return []
190 return []
190 else:
191 else:
191 return [obj]
192 return [obj]
192
193
193
194
194 class UrlTemplate(string.Template):
195 class UrlTemplate(string.Template):
195
196
196 def safe_substitute(self, **kws):
197 def safe_substitute(self, **kws):
197 # url encode the kw for usage in url
198 # url encode the kw for usage in url
198 kws = {k: urllib.parse.quote(str(v)) for k, v in kws.items()}
199 kws = {k: urllib.parse.quote(str(v)) for k, v in kws.items()}
199 return super(UrlTemplate, self).safe_substitute(**kws)
200 return super(UrlTemplate, self).safe_substitute(**kws)
@@ -1,204 +1,167 b''
1
1
2 # Copyright (C) 2010-2020 RhodeCode GmbH
2 # Copyright (C) 2010-2020 RhodeCode GmbH
3 #
3 #
4 # This program is free software: you can redistribute it and/or modify
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU Affero General Public License, version 3
5 # it under the terms of the GNU Affero General Public License, version 3
6 # (only), as published by the Free Software Foundation.
6 # (only), as published by the Free Software Foundation.
7 #
7 #
8 # This program is distributed in the hope that it will be useful,
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
11 # GNU General Public License for more details.
12 #
12 #
13 # You should have received a copy of the GNU Affero General Public License
13 # You should have received a copy of the GNU Affero General Public License
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 #
15 #
16 # This program is dual-licensed. If you wish to learn more about the
16 # This program is dual-licensed. If you wish to learn more about the
17 # RhodeCode Enterprise Edition, including its added features, Support services,
17 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # and proprietary license terms, please see https://rhodecode.com/licenses/
18 # and proprietary license terms, please see https://rhodecode.com/licenses/
19
19
20 import os
20 import os
21 import textwrap
21 import textwrap
22 import string
22 import string
23 import functools
23 import functools
24 import logging
24 import logging
25 import tempfile
25 import tempfile
26 import logging.config
26 import logging.config
27 from rhodecode.lib.type_utils import str2bool, aslist
28
27 log = logging.getLogger(__name__)
29 log = logging.getLogger(__name__)
28
30
31
29 # skip keys, that are set here, so we don't double process those
32 # skip keys, that are set here, so we don't double process those
30 set_keys = {
33 set_keys = {
31 '__file__': ''
34 '__file__': ''
32 }
35 }
33
36
34
37
35 def str2bool(_str):
36 """
37 returns True/False value from given string, it tries to translate the
38 string into boolean
39
40 :param _str: string value to translate into boolean
41 :rtype: boolean
42 :returns: boolean from given string
43 """
44 if _str is None:
45 return False
46 if _str in (True, False):
47 return _str
48 _str = str(_str).strip().lower()
49 return _str in ('t', 'true', 'y', 'yes', 'on', '1')
50
51
52 def aslist(obj, sep=None, strip=True):
53 """
54 Returns given string separated by sep as list
55
56 :param obj:
57 :param sep:
58 :param strip:
59 """
60 if isinstance(obj, str):
61 if obj in ['', ""]:
62 return []
63
64 lst = obj.split(sep)
65 if strip:
66 lst = [v.strip() for v in lst]
67 return lst
68 elif isinstance(obj, (list, tuple)):
69 return obj
70 elif obj is None:
71 return []
72 else:
73 return [obj]
74
75
76 class SettingsMaker(object):
38 class SettingsMaker(object):
77
39
78 def __init__(self, app_settings):
40 def __init__(self, app_settings):
79 self.settings = app_settings
41 self.settings = app_settings
80
42
81 @classmethod
43 @classmethod
82 def _bool_func(cls, input_val):
44 def _bool_func(cls, input_val):
83 return str2bool(input_val)
45 return str2bool(input_val)
84
46
85 @classmethod
47 @classmethod
86 def _int_func(cls, input_val):
48 def _int_func(cls, input_val):
87 return int(input_val)
49 return int(input_val)
88
50
89 @classmethod
51 @classmethod
52 def _float_func(cls, input_val):
53 return float(input_val)
54
55 @classmethod
90 def _list_func(cls, input_val, sep=','):
56 def _list_func(cls, input_val, sep=','):
91 return aslist(input_val, sep=sep)
57 return aslist(input_val, sep=sep)
92
58
93 @classmethod
59 @classmethod
94 def _string_func(cls, input_val, lower=True):
60 def _string_func(cls, input_val, lower=True):
95 if lower:
61 if lower:
96 input_val = input_val.lower()
62 input_val = input_val.lower()
97 return input_val
63 return input_val
98
64
99 @classmethod
65 @classmethod
100 def _float_func(cls, input_val):
101 return float(input_val)
102
103 @classmethod
104 def _dir_func(cls, input_val, ensure_dir=False, mode=0o755):
66 def _dir_func(cls, input_val, ensure_dir=False, mode=0o755):
105
67
106 # ensure we have our dir created
68 # ensure we have our dir created
107 if not os.path.isdir(input_val) and ensure_dir:
69 if not os.path.isdir(input_val) and ensure_dir:
108 os.makedirs(input_val, mode=mode)
70 os.makedirs(input_val, mode=mode)
109
71
110 if not os.path.isdir(input_val):
72 if not os.path.isdir(input_val):
111 raise Exception('Dir at {} does not exist'.format(input_val))
73 raise Exception('Dir at {} does not exist'.format(input_val))
112 return input_val
74 return input_val
113
75
114 @classmethod
76 @classmethod
115 def _file_path_func(cls, input_val, ensure_dir=False, mode=0o755):
77 def _file_path_func(cls, input_val, ensure_dir=False, mode=0o755):
116 dirname = os.path.dirname(input_val)
78 dirname = os.path.dirname(input_val)
117 cls._dir_func(dirname, ensure_dir=ensure_dir)
79 cls._dir_func(dirname, ensure_dir=ensure_dir)
118 return input_val
80 return input_val
119
81
120 @classmethod
82 @classmethod
121 def _key_transformator(cls, key):
83 def _key_transformator(cls, key):
122 return "{}_{}".format('RC'.upper(), key.upper().replace('.', '_').replace('-', '_'))
84 return "{}_{}".format('RC'.upper(), key.upper().replace('.', '_').replace('-', '_'))
123
85
124 def maybe_env_key(self, key):
86 def maybe_env_key(self, key):
125 # now maybe we have this KEY in env, search and use the value with higher priority.
87 # now maybe we have this KEY in env, search and use the value with higher priority.
126 transformed_key = self._key_transformator(key)
88 transformed_key = self._key_transformator(key)
127 envvar_value = os.environ.get(transformed_key)
89 envvar_value = os.environ.get(transformed_key)
128 if envvar_value:
90 if envvar_value:
129 log.debug('using `%s` key instead of `%s` key for config', transformed_key, key)
91 log.debug('using `%s` key instead of `%s` key for config', transformed_key, key)
130
92
131 return envvar_value
93 return envvar_value
132
94
133 def env_expand(self):
95 def env_expand(self):
134 replaced = {}
96 replaced = {}
135 for k, v in self.settings.items():
97 for k, v in self.settings.items():
136 if k not in set_keys:
98 if k not in set_keys:
137 envvar_value = self.maybe_env_key(k)
99 envvar_value = self.maybe_env_key(k)
138 if envvar_value:
100 if envvar_value:
139 replaced[k] = envvar_value
101 replaced[k] = envvar_value
140 set_keys[k] = envvar_value
102 set_keys[k] = envvar_value
141
103
142 # replace ALL keys updated
104 # replace ALL keys updated
143 self.settings.update(replaced)
105 self.settings.update(replaced)
144
106
145 def enable_logging(self, logging_conf=None, level='INFO', formatter='generic'):
107 def enable_logging(self, logging_conf=None, level='INFO', formatter='generic'):
146 """
108 """
147 Helper to enable debug on running instance
109 Helper to enable debug on running instance
148 :return:
110 :return:
149 """
111 """
150
112
151 if not str2bool(self.settings.get('logging.autoconfigure')):
113 if not str2bool(self.settings.get('logging.autoconfigure')):
152 log.info('logging configuration based on main .ini file')
114 log.info('logging configuration based on main .ini file')
153 return
115 return
154
116
155 if logging_conf is None:
117 if logging_conf is None:
156 logging_conf = self.settings.get('logging.logging_conf_file') or ''
118 logging_conf = self.settings.get('logging.logging_conf_file') or ''
157
119
158 if not os.path.isfile(logging_conf):
120 if not os.path.isfile(logging_conf):
159 log.error('Unable to setup logging based on %s, '
121 log.error('Unable to setup logging based on %s, '
160 'file does not exist.... specify path using logging.logging_conf_file= config setting. ', logging_conf)
122 'file does not exist.... specify path using logging.logging_conf_file= config setting. ', logging_conf)
161 return
123 return
162
124
163 with open(logging_conf, 'rb') as f:
125 with open(logging_conf, 'rt') as f:
164 ini_template = textwrap.dedent(f.read())
126 ini_template = textwrap.dedent(f.read())
165 ini_template = string.Template(ini_template).safe_substitute(
127 ini_template = string.Template(ini_template).safe_substitute(
166 RC_LOGGING_LEVEL=os.environ.get('RC_LOGGING_LEVEL', '') or level,
128 RC_LOGGING_LEVEL=os.environ.get('RC_LOGGING_LEVEL', '') or level,
167 RC_LOGGING_FORMATTER=os.environ.get('RC_LOGGING_FORMATTER', '') or formatter
129 RC_LOGGING_FORMATTER=os.environ.get('RC_LOGGING_FORMATTER', '') or formatter
168 )
130 )
169
131
170 with tempfile.NamedTemporaryFile(prefix='rc_logging_', suffix='.ini', delete=False) as f:
132 with tempfile.NamedTemporaryFile(prefix='rc_logging_', suffix='.ini', delete=False) as f:
171 log.info('Saved Temporary LOGGING config at %s', f.name)
133 log.info('Saved Temporary LOGGING config at %s', f.name)
172 f.write(ini_template)
134 f.write(ini_template)
173
135
174 logging.config.fileConfig(f.name)
136 logging.config.fileConfig(f.name)
175 os.remove(f.name)
137 os.remove(f.name)
176
138
177 def make_setting(self, key, default, lower=False, default_when_empty=False, parser=None):
139 def make_setting(self, key, default, lower=False, default_when_empty=False, parser=None):
178 input_val = self.settings.get(key, default)
140 input_val = self.settings.get(key, default)
179
141
180 if default_when_empty and not input_val:
142 if default_when_empty and not input_val:
181 # use default value when value is set in the config but it is empty
143 # use default value when value is set in the config but it is empty
182 input_val = default
144 input_val = default
183
145
184 parser_func = {
146 parser_func = {
185 'bool': self._bool_func,
147 'bool': self._bool_func,
186 'int': self._int_func,
148 'int': self._int_func,
149 'float': self._float_func,
187 'list': self._list_func,
150 'list': self._list_func,
188 'list:newline': functools.partial(self._list_func, sep='/n'),
151 'list:newline': functools.partial(self._list_func, sep='/n'),
189 'list:spacesep': functools.partial(self._list_func, sep=' '),
152 'list:spacesep': functools.partial(self._list_func, sep=' '),
190 'string': functools.partial(self._string_func, lower=lower),
153 'string': functools.partial(self._string_func, lower=lower),
191 'dir': self._dir_func,
154 'dir': self._dir_func,
192 'dir:ensured': functools.partial(self._dir_func, ensure_dir=True),
155 'dir:ensured': functools.partial(self._dir_func, ensure_dir=True),
193 'file': self._file_path_func,
156 'file': self._file_path_func,
194 'file:ensured': functools.partial(self._file_path_func, ensure_dir=True),
157 'file:ensured': functools.partial(self._file_path_func, ensure_dir=True),
195 None: lambda i: i
158 None: lambda i: i
196 }[parser]
159 }[parser]
197
160
198 envvar_value = self.maybe_env_key(key)
161 envvar_value = self.maybe_env_key(key)
199 if envvar_value:
162 if envvar_value:
200 input_val = envvar_value
163 input_val = envvar_value
201 set_keys[key] = input_val
164 set_keys[key] = input_val
202
165
203 self.settings[key] = parser_func(input_val)
166 self.settings[key] = parser_func(input_val)
204 return self.settings[key]
167 return self.settings[key]
@@ -1,103 +1,119 b''
1
1
2 # Copyright (C) 2010-2020 RhodeCode GmbH
2 # Copyright (C) 2010-2020 RhodeCode GmbH
3 #
3 #
4 # This program is free software: you can redistribute it and/or modify
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU Affero General Public License, version 3
5 # it under the terms of the GNU Affero General Public License, version 3
6 # (only), as published by the Free Software Foundation.
6 # (only), as published by the Free Software Foundation.
7 #
7 #
8 # This program is distributed in the hope that it will be useful,
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
11 # GNU General Public License for more details.
12 #
12 #
13 # You should have received a copy of the GNU Affero General Public License
13 # You should have received a copy of the GNU Affero General Public License
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 #
15 #
16 # This program is dual-licensed. If you wish to learn more about the
16 # This program is dual-licensed. If you wish to learn more about the
17 # RhodeCode Enterprise Edition, including its added features, Support services,
17 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # and proprietary license terms, please see https://rhodecode.com/licenses/
18 # and proprietary license terms, please see https://rhodecode.com/licenses/
19
19
20 import os
20 import os
21 import platform
21 import platform
22
22
23 from rhodecode.model import init_model
23 from rhodecode.model import init_model
24
24
25
25
26 def configure_vcs(config):
26 def configure_vcs(config):
27 """
27 """
28 Patch VCS config with some RhodeCode specific stuff
28 Patch VCS config with some RhodeCode specific stuff
29 """
29 """
30 from rhodecode.lib.vcs import conf
30 from rhodecode.lib.vcs import conf
31 import rhodecode.lib.vcs.conf.settings
31 import rhodecode.lib.vcs.conf.settings
32
32
33 conf.settings.BACKENDS = {
33 conf.settings.BACKENDS = {
34 'hg': 'rhodecode.lib.vcs.backends.hg.MercurialRepository',
34 'hg': 'rhodecode.lib.vcs.backends.hg.MercurialRepository',
35 'git': 'rhodecode.lib.vcs.backends.git.GitRepository',
35 'git': 'rhodecode.lib.vcs.backends.git.GitRepository',
36 'svn': 'rhodecode.lib.vcs.backends.svn.SubversionRepository',
36 'svn': 'rhodecode.lib.vcs.backends.svn.SubversionRepository',
37 }
37 }
38
38
39 conf.settings.HOOKS_PROTOCOL = config['vcs.hooks.protocol']
39 conf.settings.HOOKS_PROTOCOL = config['vcs.hooks.protocol']
40 conf.settings.HOOKS_HOST = config['vcs.hooks.host']
40 conf.settings.HOOKS_HOST = config['vcs.hooks.host']
41 conf.settings.HOOKS_DIRECT_CALLS = config['vcs.hooks.direct_calls']
41 conf.settings.HOOKS_DIRECT_CALLS = config['vcs.hooks.direct_calls']
42 conf.settings.DEFAULT_ENCODINGS = config['default_encoding']
42 conf.settings.DEFAULT_ENCODINGS = config['default_encoding']
43 conf.settings.ALIASES[:] = config['vcs.backends']
43 conf.settings.ALIASES[:] = config['vcs.backends']
44 conf.settings.SVN_COMPATIBLE_VERSION = config['vcs.svn.compatible_version']
44 conf.settings.SVN_COMPATIBLE_VERSION = config['vcs.svn.compatible_version']
45
45
46
46
47 def initialize_database(config):
47 def initialize_database(config):
48 from rhodecode.lib.utils2 import engine_from_config, get_encryption_key
48 from rhodecode.lib.utils2 import engine_from_config, get_encryption_key
49 engine = engine_from_config(config, 'sqlalchemy.db1.')
49 engine = engine_from_config(config, 'sqlalchemy.db1.')
50 init_model(engine, encryption_key=get_encryption_key(config))
50 init_model(engine, encryption_key=get_encryption_key(config))
51
51
52
52
53 def initialize_test_environment(settings, test_env=None):
53 def initialize_test_environment(settings, test_env=None):
54 if test_env is None:
54 if test_env is None:
55 test_env = not int(os.environ.get('RC_NO_TMP_PATH', 0))
55 test_env = not int(os.environ.get('RC_NO_TMP_PATH', 0))
56
56
57 from rhodecode.lib.utils import (
57 from rhodecode.lib.utils import (
58 create_test_directory, create_test_database, create_test_repositories,
58 create_test_directory, create_test_database, create_test_repositories,
59 create_test_index)
59 create_test_index)
60 from rhodecode.tests import TESTS_TMP_PATH
60 from rhodecode.tests import TESTS_TMP_PATH
61 from rhodecode.lib.vcs.backends.hg import largefiles_store
61 from rhodecode.lib.vcs.backends.hg import largefiles_store
62 from rhodecode.lib.vcs.backends.git import lfs_store
62 from rhodecode.lib.vcs.backends.git import lfs_store
63
63
64 # test repos
64 # test repos
65 if test_env:
65 if test_env:
66 create_test_directory(TESTS_TMP_PATH)
66 create_test_directory(TESTS_TMP_PATH)
67 # large object stores
67 # large object stores
68 create_test_directory(largefiles_store(TESTS_TMP_PATH))
68 create_test_directory(largefiles_store(TESTS_TMP_PATH))
69 create_test_directory(lfs_store(TESTS_TMP_PATH))
69 create_test_directory(lfs_store(TESTS_TMP_PATH))
70
70
71 create_test_database(TESTS_TMP_PATH, settings)
71 create_test_database(TESTS_TMP_PATH, settings)
72 create_test_repositories(TESTS_TMP_PATH, settings)
72 create_test_repositories(TESTS_TMP_PATH, settings)
73 create_test_index(TESTS_TMP_PATH, settings)
73 create_test_index(TESTS_TMP_PATH, settings)
74
74
75
75
76 def get_vcs_server_protocol(config):
76 def get_vcs_server_protocol(config):
77 return config['vcs.server.protocol']
77 return config['vcs.server.protocol']
78
78
79
79
80 def set_instance_id(config):
80 def set_instance_id(config):
81 """
81 """
82 Sets a dynamic generated config['instance_id'] if missing or '*'
82 Sets a dynamic generated config['instance_id'] if missing or '*'
83 E.g instance_id = *cluster-1 or instance_id = *
83 E.g instance_id = *cluster-1 or instance_id = *
84 """
84 """
85
85
86 config['instance_id'] = config.get('instance_id') or ''
86 config['instance_id'] = config.get('instance_id') or ''
87 instance_id = config['instance_id']
87 instance_id = config['instance_id']
88 if instance_id.startswith('*') or not instance_id:
88 if instance_id.startswith('*') or not instance_id:
89 prefix = instance_id.lstrip('*')
89 prefix = instance_id.lstrip('*')
90 _platform_id = platform.uname()[1] or 'instance'
90 _platform_id = platform.uname()[1] or 'instance'
91 config['instance_id'] = '{prefix}uname:{platform}-pid:{pid}'.format(
91 config['instance_id'] = '{prefix}uname:{platform}-pid:{pid}'.format(
92 prefix=prefix,
92 prefix=prefix,
93 platform=_platform_id,
93 platform=_platform_id,
94 pid=os.getpid())
94 pid=os.getpid())
95
95
96
96
97 def get_default_user_id():
97 def get_default_user_id():
98 from rhodecode.model.db import User, Session
98 DEFAULT_USER = 'default'
99 user_id = Session()\
99 from sqlalchemy import text
100 .query(User.user_id)\
100 from rhodecode.model import meta
101 .filter(User.username == User.DEFAULT_USER)\
101
102 .scalar()
102 engine = meta.get_engine()
103 with meta.SA_Session(engine) as session:
104 result = session.execute(text("SELECT user_id from users where username = :uname"), {'uname': DEFAULT_USER})
105 user_id = result.first()[0]
106
103 return user_id
107 return user_id
108
109
110 def get_default_base_path():
111 from sqlalchemy import text
112 from rhodecode.model import meta
113
114 engine = meta.get_engine()
115 with meta.SA_Session(engine) as session:
116 result = session.execute(text("SELECT ui_value from rhodecode_ui where ui_key = '/'"))
117 base_path = result.first()[0]
118
119 return base_path
General Comments 0
You need to be logged in to leave comments. Login now