devpi-web 5.0.1__tar.gz → 5.0.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- devpi_web-5.0.2/.flake8 +3 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/CHANGELOG +20 -19
- {devpi_web-5.0.1 → devpi_web-5.0.2}/CHANGELOG.short.rst +20 -22
- {devpi_web-5.0.1 → devpi_web-5.0.2}/PKG-INFO +22 -23
- devpi_web-5.0.2/devpi_web/__init__.py +1 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/indexing.py +37 -23
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/main.py +10 -8
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/null_index.py +1 -3
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/views.py +34 -14
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/whoosh_index.py +83 -43
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web.egg-info/PKG-INFO +22 -23
- {devpi_web-5.0.1 → devpi_web-5.0.2}/mypy.ini +7 -12
- {devpi_web-5.0.1 → devpi_web-5.0.2}/pyproject.toml +22 -18
- {devpi_web-5.0.1 → devpi_web-5.0.2}/tests/test_indexing.py +2 -2
- {devpi_web-5.0.1 → devpi_web-5.0.2}/tests/test_views.py +1 -6
- {devpi_web-5.0.1 → devpi_web-5.0.2}/tests/test_views_misc.py +3 -12
- {devpi_web-5.0.1 → devpi_web-5.0.2}/tests/test_views_search.py +18 -11
- {devpi_web-5.0.1 → devpi_web-5.0.2}/tests/test_views_toxresults.py +7 -3
- {devpi_web-5.0.1 → devpi_web-5.0.2}/tests/test_whoosh_index.py +42 -27
- {devpi_web-5.0.1 → devpi_web-5.0.2}/tox.ini +5 -4
- devpi_web-5.0.1/.flake8 +0 -2
- devpi_web-5.0.1/devpi_web/__init__.py +0 -1
- {devpi_web-5.0.1 → devpi_web-5.0.2}/LICENSE +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/MANIFEST.in +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/README.rst +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/clear_index.py +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/compat.py +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/config.py +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/description.py +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/doczip.py +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/hookspecs.py +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/macroregistry.py +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/macros.py +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/static/common.js +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/static/docview.js +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/static/favicon.ico +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/static/jquery-3.6.0.min.js +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/static/search.js +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/static/style.css +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/templates/doc.pt +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/templates/error.pt +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/templates/favicon.pt +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/templates/footer.pt +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/templates/footer_versions.pt +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/templates/head.pt +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/templates/header.pt +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/templates/header_breadcrumbs.pt +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/templates/header_search.pt +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/templates/header_status.pt +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/templates/html_head_css.pt +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/templates/html_head_scripts.pt +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/templates/index.pt +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/templates/logo.pt +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/templates/notfound.pt +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/templates/project.pt +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/templates/query_docs.pt +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/templates/root.pt +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/templates/root_above_user_index_list.pt +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/templates/root_below_user_index_list.pt +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/templates/search.pt +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/templates/search_help.pt +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/templates/status.pt +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/templates/status_badge.pt +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/templates/toxresult.pt +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/templates/toxresults.pt +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/templates/user.pt +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web/templates/version.pt +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web.egg-info/SOURCES.txt +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web.egg-info/dependency_links.txt +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web.egg-info/entry_points.txt +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web.egg-info/requires.txt +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/devpi_web.egg-info/top_level.txt +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/setup.cfg +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/tests/conftest.py +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/tests/test_macro_registry.py +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/tests/test_main.py +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/tests/test_theme.py +0 -0
- {devpi_web-5.0.1 → devpi_web-5.0.2}/tests/test_views_docs.py +0 -0
devpi_web-5.0.2/.flake8
ADDED
|
@@ -2,6 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
.. towncrier release notes start
|
|
4
4
|
|
|
5
|
+
5.0.2 (2026-03-17)
|
|
6
|
+
==================
|
|
7
|
+
|
|
8
|
+
Bug Fixes
|
|
9
|
+
---------
|
|
10
|
+
|
|
11
|
+
- Prevent double indexing work on first start of freshly initialized/imported instance.
|
|
12
|
+
|
|
13
|
+
- Optimize preparation of mirror project data for indexing.
|
|
14
|
+
|
|
15
|
+
- Consistently use offline mode when indexing. This especially helps performance on startup.
|
|
16
|
+
|
|
17
|
+
- Skip redirect if an installer is detected which is configured without ``+simple`` in the URL.
|
|
18
|
+
|
|
19
|
+
Other Changes
|
|
20
|
+
-------------
|
|
21
|
+
|
|
22
|
+
- Support string timestamps for file history log entries from devpi-server 7.0.0.
|
|
23
|
+
|
|
24
|
+
|
|
5
25
|
5.0.1 (2025-06-15)
|
|
6
26
|
==================
|
|
7
27
|
|
|
@@ -11,7 +31,6 @@ Bug Fixes
|
|
|
11
31
|
- Fix traceback during unpacking of documentation in some cases.
|
|
12
32
|
|
|
13
33
|
|
|
14
|
-
|
|
15
34
|
5.0.0 (2025-06-12)
|
|
16
35
|
==================
|
|
17
36
|
|
|
@@ -24,15 +43,11 @@ Deprecations and Removals
|
|
|
24
43
|
|
|
25
44
|
- Future releases will more often require newer devpi-server than before.
|
|
26
45
|
|
|
27
|
-
|
|
28
|
-
|
|
29
46
|
Bug Fixes
|
|
30
47
|
---------
|
|
31
48
|
|
|
32
49
|
- Fix #930: remove remaining uses of unmaintained py library.
|
|
33
50
|
|
|
34
|
-
|
|
35
|
-
|
|
36
51
|
Other Changes
|
|
37
52
|
-------------
|
|
38
53
|
|
|
@@ -69,7 +84,6 @@ Other Changes
|
|
|
69
84
|
- macros.pt: Move ``versions`` macro to separate ``footer_versions.pt`` template.
|
|
70
85
|
|
|
71
86
|
|
|
72
|
-
|
|
73
87
|
4.3.0 (2024-10-16)
|
|
74
88
|
==================
|
|
75
89
|
|
|
@@ -79,7 +93,6 @@ Features
|
|
|
79
93
|
- index.pt, project.pt, version.pt: Fix #1062: Added a link to download the documentation as zip-file to the index, project and version view.
|
|
80
94
|
|
|
81
95
|
|
|
82
|
-
|
|
83
96
|
4.2.3 (2024-09-19)
|
|
84
97
|
==================
|
|
85
98
|
|
|
@@ -95,7 +108,6 @@ Bug Fixes
|
|
|
95
108
|
- Increase threshold for index status from 60 s to 300 s for warnings and from 300 s to 3600 s for fatal.
|
|
96
109
|
|
|
97
110
|
|
|
98
|
-
|
|
99
111
|
4.2.2 (2024-04-20)
|
|
100
112
|
==================
|
|
101
113
|
|
|
@@ -109,7 +121,6 @@ Bug Fixes
|
|
|
109
121
|
- Fix #970: overwrite fixed html/body heights like ``100%`` in documentation iframe content.
|
|
110
122
|
|
|
111
123
|
|
|
112
|
-
|
|
113
124
|
4.2.1 (2023-07-02)
|
|
114
125
|
==================
|
|
115
126
|
|
|
@@ -131,7 +142,6 @@ Features
|
|
|
131
142
|
|
|
132
143
|
- Add ``--keep-docs-packed`` option.
|
|
133
144
|
|
|
134
|
-
|
|
135
145
|
Bug Fixes
|
|
136
146
|
---------
|
|
137
147
|
|
|
@@ -151,7 +161,6 @@ Bug Fixes
|
|
|
151
161
|
4.1.1 (2022-09-28)
|
|
152
162
|
==================
|
|
153
163
|
|
|
154
|
-
|
|
155
164
|
Bug Fixes
|
|
156
165
|
---------
|
|
157
166
|
|
|
@@ -170,7 +179,6 @@ Features
|
|
|
170
179
|
|
|
171
180
|
- project.pt: add navigation links to original project page for mirrors and to "Simple page" of projects.
|
|
172
181
|
|
|
173
|
-
|
|
174
182
|
Bug Fixes
|
|
175
183
|
---------
|
|
176
184
|
|
|
@@ -216,7 +224,6 @@ Bug Fixes
|
|
|
216
224
|
|
|
217
225
|
- Use a lock file to prevent concurrent unpacking of documentation.
|
|
218
226
|
|
|
219
|
-
|
|
220
227
|
Other Changes
|
|
221
228
|
-------------
|
|
222
229
|
|
|
@@ -277,7 +284,6 @@ Deprecations and Removals
|
|
|
277
284
|
|
|
278
285
|
- Dropped support for Python 2.7.
|
|
279
286
|
|
|
280
|
-
|
|
281
287
|
Features
|
|
282
288
|
--------
|
|
283
289
|
|
|
@@ -317,7 +323,6 @@ Features
|
|
|
317
323
|
|
|
318
324
|
- Indexer backend options can now be specified as a dict in yaml config files.
|
|
319
325
|
|
|
320
|
-
|
|
321
326
|
Bug Fixes
|
|
322
327
|
---------
|
|
323
328
|
|
|
@@ -325,7 +330,6 @@ Bug Fixes
|
|
|
325
330
|
|
|
326
331
|
- Pass query string on to documentation iframe, this fixes Sphinx search among other things.
|
|
327
332
|
|
|
328
|
-
|
|
329
333
|
Other Changes
|
|
330
334
|
-------------
|
|
331
335
|
|
|
@@ -364,7 +368,6 @@ Features
|
|
|
364
368
|
|
|
365
369
|
- feature #193: adding support for using markdown in package descriptions.
|
|
366
370
|
|
|
367
|
-
|
|
368
371
|
Bug Fixes
|
|
369
372
|
---------
|
|
370
373
|
|
|
@@ -404,7 +407,6 @@ Features
|
|
|
404
407
|
|
|
405
408
|
- Use ``mirror_web_url_fmt`` in ``get_description`` for mirror indexes.
|
|
406
409
|
|
|
407
|
-
|
|
408
410
|
Bug Fixes
|
|
409
411
|
---------
|
|
410
412
|
|
|
@@ -629,7 +631,6 @@ Bug Fixes
|
|
|
629
631
|
- fix notfound-redirect when serving under an outside URL with a sub path
|
|
630
632
|
|
|
631
633
|
|
|
632
|
-
|
|
633
634
|
2.2.0
|
|
634
635
|
=====
|
|
635
636
|
|
|
@@ -9,6 +9,26 @@ Changelog
|
|
|
9
9
|
|
|
10
10
|
.. towncrier release notes start
|
|
11
11
|
|
|
12
|
+
5.0.2 (2026-03-17)
|
|
13
|
+
==================
|
|
14
|
+
|
|
15
|
+
Bug Fixes
|
|
16
|
+
---------
|
|
17
|
+
|
|
18
|
+
- Prevent double indexing work on first start of freshly initialized/imported instance.
|
|
19
|
+
|
|
20
|
+
- Optimize preparation of mirror project data for indexing.
|
|
21
|
+
|
|
22
|
+
- Consistently use offline mode when indexing. This especially helps performance on startup.
|
|
23
|
+
|
|
24
|
+
- Skip redirect if an installer is detected which is configured without ``+simple`` in the URL.
|
|
25
|
+
|
|
26
|
+
Other Changes
|
|
27
|
+
-------------
|
|
28
|
+
|
|
29
|
+
- Support string timestamps for file history log entries from devpi-server 7.0.0.
|
|
30
|
+
|
|
31
|
+
|
|
12
32
|
5.0.1 (2025-06-15)
|
|
13
33
|
==================
|
|
14
34
|
|
|
@@ -18,7 +38,6 @@ Bug Fixes
|
|
|
18
38
|
- Fix traceback during unpacking of documentation in some cases.
|
|
19
39
|
|
|
20
40
|
|
|
21
|
-
|
|
22
41
|
5.0.0 (2025-06-12)
|
|
23
42
|
==================
|
|
24
43
|
|
|
@@ -31,15 +50,11 @@ Deprecations and Removals
|
|
|
31
50
|
|
|
32
51
|
- Future releases will more often require newer devpi-server than before.
|
|
33
52
|
|
|
34
|
-
|
|
35
|
-
|
|
36
53
|
Bug Fixes
|
|
37
54
|
---------
|
|
38
55
|
|
|
39
56
|
- Fix #930: remove remaining uses of unmaintained py library.
|
|
40
57
|
|
|
41
|
-
|
|
42
|
-
|
|
43
58
|
Other Changes
|
|
44
59
|
-------------
|
|
45
60
|
|
|
@@ -76,7 +91,6 @@ Other Changes
|
|
|
76
91
|
- macros.pt: Move ``versions`` macro to separate ``footer_versions.pt`` template.
|
|
77
92
|
|
|
78
93
|
|
|
79
|
-
|
|
80
94
|
4.3.0 (2024-10-16)
|
|
81
95
|
==================
|
|
82
96
|
|
|
@@ -86,7 +100,6 @@ Features
|
|
|
86
100
|
- index.pt, project.pt, version.pt: Fix #1062: Added a link to download the documentation as zip-file to the index, project and version view.
|
|
87
101
|
|
|
88
102
|
|
|
89
|
-
|
|
90
103
|
4.2.3 (2024-09-19)
|
|
91
104
|
==================
|
|
92
105
|
|
|
@@ -101,18 +114,3 @@ Bug Fixes
|
|
|
101
114
|
|
|
102
115
|
- Increase threshold for index status from 60 s to 300 s for warnings and from 300 s to 3600 s for fatal.
|
|
103
116
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
4.2.2 (2024-04-20)
|
|
107
|
-
==================
|
|
108
|
-
|
|
109
|
-
Bug Fixes
|
|
110
|
-
---------
|
|
111
|
-
|
|
112
|
-
- style.css: Always let content be full browser height. This also gives more height with some documentation themes when content is short.
|
|
113
|
-
|
|
114
|
-
- style.css: set ``scrollbar-gutter: stable`` on ``body`` to prevent jumping content in documentation iframe.
|
|
115
|
-
|
|
116
|
-
- Fix #970: overwrite fixed html/body heights like ``100%`` in documentation iframe content.
|
|
117
|
-
|
|
118
|
-
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: devpi-web
|
|
3
|
-
Version: 5.0.
|
|
3
|
+
Version: 5.0.2
|
|
4
4
|
Summary: devpi-web: a web view for devpi-server
|
|
5
5
|
Maintainer-email: Florian Schulze <mail@pyfidelity.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -20,6 +20,7 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
20
20
|
Classifier: Programming Language :: Python :: 3.11
|
|
21
21
|
Classifier: Programming Language :: Python :: 3.12
|
|
22
22
|
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
23
24
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
24
25
|
Classifier: Topic :: Internet :: WWW/HTTP
|
|
25
26
|
Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application
|
|
@@ -87,6 +88,26 @@ Changelog
|
|
|
87
88
|
|
|
88
89
|
.. towncrier release notes start
|
|
89
90
|
|
|
91
|
+
5.0.2 (2026-03-17)
|
|
92
|
+
==================
|
|
93
|
+
|
|
94
|
+
Bug Fixes
|
|
95
|
+
---------
|
|
96
|
+
|
|
97
|
+
- Prevent double indexing work on first start of freshly initialized/imported instance.
|
|
98
|
+
|
|
99
|
+
- Optimize preparation of mirror project data for indexing.
|
|
100
|
+
|
|
101
|
+
- Consistently use offline mode when indexing. This especially helps performance on startup.
|
|
102
|
+
|
|
103
|
+
- Skip redirect if an installer is detected which is configured without ``+simple`` in the URL.
|
|
104
|
+
|
|
105
|
+
Other Changes
|
|
106
|
+
-------------
|
|
107
|
+
|
|
108
|
+
- Support string timestamps for file history log entries from devpi-server 7.0.0.
|
|
109
|
+
|
|
110
|
+
|
|
90
111
|
5.0.1 (2025-06-15)
|
|
91
112
|
==================
|
|
92
113
|
|
|
@@ -96,7 +117,6 @@ Bug Fixes
|
|
|
96
117
|
- Fix traceback during unpacking of documentation in some cases.
|
|
97
118
|
|
|
98
119
|
|
|
99
|
-
|
|
100
120
|
5.0.0 (2025-06-12)
|
|
101
121
|
==================
|
|
102
122
|
|
|
@@ -109,15 +129,11 @@ Deprecations and Removals
|
|
|
109
129
|
|
|
110
130
|
- Future releases will more often require newer devpi-server than before.
|
|
111
131
|
|
|
112
|
-
|
|
113
|
-
|
|
114
132
|
Bug Fixes
|
|
115
133
|
---------
|
|
116
134
|
|
|
117
135
|
- Fix #930: remove remaining uses of unmaintained py library.
|
|
118
136
|
|
|
119
|
-
|
|
120
|
-
|
|
121
137
|
Other Changes
|
|
122
138
|
-------------
|
|
123
139
|
|
|
@@ -154,7 +170,6 @@ Other Changes
|
|
|
154
170
|
- macros.pt: Move ``versions`` macro to separate ``footer_versions.pt`` template.
|
|
155
171
|
|
|
156
172
|
|
|
157
|
-
|
|
158
173
|
4.3.0 (2024-10-16)
|
|
159
174
|
==================
|
|
160
175
|
|
|
@@ -164,7 +179,6 @@ Features
|
|
|
164
179
|
- index.pt, project.pt, version.pt: Fix #1062: Added a link to download the documentation as zip-file to the index, project and version view.
|
|
165
180
|
|
|
166
181
|
|
|
167
|
-
|
|
168
182
|
4.2.3 (2024-09-19)
|
|
169
183
|
==================
|
|
170
184
|
|
|
@@ -179,18 +193,3 @@ Bug Fixes
|
|
|
179
193
|
|
|
180
194
|
- Increase threshold for index status from 60 s to 300 s for warnings and from 300 s to 3600 s for fatal.
|
|
181
195
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
4.2.2 (2024-04-20)
|
|
185
|
-
==================
|
|
186
|
-
|
|
187
|
-
Bug Fixes
|
|
188
|
-
---------
|
|
189
|
-
|
|
190
|
-
- style.css: Always let content be full browser height. This also gives more height with some documentation themes when content is short.
|
|
191
|
-
|
|
192
|
-
- style.css: set ``scrollbar-gutter: stable`` on ``body`` to prevent jumping content in documentation iframe.
|
|
193
|
-
|
|
194
|
-
- Fix #970: overwrite fixed html/body heights like ``100%`` in documentation iframe content.
|
|
195
|
-
|
|
196
|
-
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "5.0.2"
|
|
@@ -1,10 +1,17 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from attrs import define
|
|
1
4
|
from collections.abc import Mapping
|
|
2
|
-
from devpi_common.types import ensure_unicode
|
|
3
5
|
from devpi_common.metadata import get_sorted_versions
|
|
6
|
+
from devpi_common.types import ensure_unicode
|
|
4
7
|
from devpi_common.validation import normalize_name
|
|
5
8
|
from devpi_web.config import get_pluginmanager
|
|
6
9
|
from devpi_web.doczip import Docs
|
|
7
|
-
import
|
|
10
|
+
from typing import TYPE_CHECKING
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from typing import Any
|
|
8
15
|
|
|
9
16
|
|
|
10
17
|
def is_project_cached(stage, project):
|
|
@@ -14,7 +21,7 @@ def is_project_cached(stage, project):
|
|
|
14
21
|
return True
|
|
15
22
|
|
|
16
23
|
|
|
17
|
-
def preprocess_project(project):
|
|
24
|
+
def preprocess_project(project: ProjectIndexingInfo) -> dict | None:
|
|
18
25
|
stage = project.stage
|
|
19
26
|
pm = get_pluginmanager(stage.xom.config)
|
|
20
27
|
name = normalize_name(project.name)
|
|
@@ -25,15 +32,19 @@ def preprocess_project(project):
|
|
|
25
32
|
user, index = stage.name.split('/')
|
|
26
33
|
user = ensure_unicode(user)
|
|
27
34
|
index = ensure_unicode(index)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
+
result: dict[str, object]
|
|
36
|
+
if stage.ixconfig["type"] == "mirror":
|
|
37
|
+
stage.offline = True
|
|
38
|
+
if not stage.is_project_cached(name):
|
|
39
|
+
# only index basic info for projects with no downloads
|
|
40
|
+
result = dict(name=project.name, user=user, index=index)
|
|
41
|
+
pm.hook.devpiweb_modify_preprocess_project_result(
|
|
42
|
+
project=project, result=result
|
|
43
|
+
)
|
|
44
|
+
return result
|
|
45
|
+
elif not stage.has_project_perstage(name):
|
|
35
46
|
# project doesn't exist anymore
|
|
36
|
-
return
|
|
47
|
+
return None
|
|
37
48
|
# metadata_keys is only available on private indexes
|
|
38
49
|
setuptools_metadata = frozenset(getattr(stage, 'metadata_keys', ()))
|
|
39
50
|
versions = get_sorted_versions(stage.list_versions_perstage(name))
|
|
@@ -49,8 +60,7 @@ def preprocess_project(project):
|
|
|
49
60
|
result['doc_version'] = version
|
|
50
61
|
result['+doczip'] = docs
|
|
51
62
|
break
|
|
52
|
-
|
|
53
|
-
assert '+doczip' not in result
|
|
63
|
+
assert "+doczip" not in result
|
|
54
64
|
|
|
55
65
|
result[u'user'] = user
|
|
56
66
|
result[u'index'] = index
|
|
@@ -64,17 +74,18 @@ def preprocess_project(project):
|
|
|
64
74
|
return result
|
|
65
75
|
|
|
66
76
|
|
|
67
|
-
@
|
|
68
|
-
class ProjectIndexingInfo
|
|
69
|
-
stage
|
|
70
|
-
name
|
|
77
|
+
@define
|
|
78
|
+
class ProjectIndexingInfo:
|
|
79
|
+
stage: Any
|
|
80
|
+
name: str
|
|
81
|
+
num_names: int
|
|
71
82
|
|
|
72
83
|
@property
|
|
73
|
-
def indexname(self):
|
|
84
|
+
def indexname(self) -> str:
|
|
74
85
|
return self.stage.name
|
|
75
86
|
|
|
76
87
|
@property
|
|
77
|
-
def is_from_mirror(self):
|
|
88
|
+
def is_from_mirror(self) -> bool:
|
|
78
89
|
return self.stage.ixconfig['type'] == 'mirror'
|
|
79
90
|
|
|
80
91
|
|
|
@@ -92,18 +103,21 @@ def iter_indexes(xom):
|
|
|
92
103
|
yield from mirrors
|
|
93
104
|
|
|
94
105
|
|
|
95
|
-
def iter_projects(xom):
|
|
106
|
+
def iter_projects(xom, *, offline=True):
|
|
96
107
|
for username, index in iter_indexes(xom):
|
|
97
108
|
stage = xom.model.getstage(username, index)
|
|
98
109
|
if stage is None: # this is async, so the stage may be gone
|
|
99
110
|
continue
|
|
100
111
|
names = stage.list_projects_perstage()
|
|
112
|
+
# only go offline after we got the projects list
|
|
113
|
+
if stage.ixconfig["type"] == "mirror":
|
|
114
|
+
stage.offline = offline
|
|
101
115
|
if isinstance(names, Mapping):
|
|
102
116
|
# since devpi-server 6.6.0 mirrors return a mapping where
|
|
103
117
|
# the un-normalized names are in the values
|
|
104
118
|
names = names.values()
|
|
119
|
+
num_names = len(names)
|
|
105
120
|
for name in names:
|
|
106
|
-
name = ensure_unicode(name)
|
|
107
121
|
yield ProjectIndexingInfo(
|
|
108
|
-
stage=stage,
|
|
109
|
-
|
|
122
|
+
stage=stage, name=ensure_unicode(name), num_names=num_names
|
|
123
|
+
)
|
|
@@ -101,9 +101,8 @@ def status_info(request):
|
|
|
101
101
|
msgs = []
|
|
102
102
|
pm = request.registry['devpiweb-pluginmanager']
|
|
103
103
|
for result in pm.hook.devpiweb_get_status_info(request=request):
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
states = set(x['status'] for x in msgs)
|
|
104
|
+
msgs.extend(result)
|
|
105
|
+
states = {x["status"] for x in msgs}
|
|
107
106
|
if 'fatal' in states:
|
|
108
107
|
status = 'fatal'
|
|
109
108
|
short_msg = 'fatal'
|
|
@@ -284,9 +283,11 @@ def devpiserver_mirror_initialnames(stage, projectnames):
|
|
|
284
283
|
# since devpi-server 6.6.0 mirrors return a mapping where
|
|
285
284
|
# the un-normalized names are in the values
|
|
286
285
|
projectnames = projectnames.values()
|
|
286
|
+
num_names = len(projectnames)
|
|
287
287
|
ix.update_projects(
|
|
288
|
-
ProjectIndexingInfo(stage=stage, name=name)
|
|
289
|
-
for name in projectnames
|
|
288
|
+
ProjectIndexingInfo(stage=stage, name=name, num_names=num_names)
|
|
289
|
+
for name in projectnames
|
|
290
|
+
)
|
|
290
291
|
threadlog.info("finished mirror indexing operation")
|
|
291
292
|
|
|
292
293
|
|
|
@@ -315,14 +316,14 @@ def delete_project(stage, name):
|
|
|
315
316
|
if stage is None:
|
|
316
317
|
return
|
|
317
318
|
ix = get_indexer(stage.xom)
|
|
318
|
-
ix.delete_projects([ProjectIndexingInfo(stage=stage, name=name)])
|
|
319
|
+
ix.delete_projects([ProjectIndexingInfo(stage=stage, name=name, num_names=1)])
|
|
319
320
|
|
|
320
321
|
|
|
321
322
|
def index_project(stage, name):
|
|
322
323
|
if stage is None:
|
|
323
324
|
return
|
|
324
325
|
ix = get_indexer(stage.xom)
|
|
325
|
-
ix.update_projects([ProjectIndexingInfo(stage=stage, name=name)])
|
|
326
|
+
ix.update_projects([ProjectIndexingInfo(stage=stage, name=name, num_names=1)])
|
|
326
327
|
|
|
327
328
|
|
|
328
329
|
@devpiserver_hookimpl
|
|
@@ -338,9 +339,10 @@ def devpiserver_on_upload(stage, project, version, link):
|
|
|
338
339
|
@devpiserver_hookimpl
|
|
339
340
|
def devpiserver_on_changed_versiondata(stage, project, version, metadata):
|
|
340
341
|
if stage is None:
|
|
341
|
-
# TODO we don't have enough info to delete the project
|
|
342
342
|
return
|
|
343
343
|
if not metadata:
|
|
344
|
+
if stage.ixconfig["type"] == "mirror":
|
|
345
|
+
stage.offline = True
|
|
344
346
|
if is_project_cached(stage, project) and not stage.has_project_perstage(project):
|
|
345
347
|
delete_project(stage, project)
|
|
346
348
|
return
|
|
@@ -24,9 +24,7 @@ class Index:
|
|
|
24
24
|
return dict(items=[])
|
|
25
25
|
|
|
26
26
|
def _matcher(self, searchinfo):
|
|
27
|
-
items =
|
|
28
|
-
re.escape(x)
|
|
29
|
-
for x in searchinfo['fields']['name'])
|
|
27
|
+
items = [re.escape(x) for x in searchinfo["fields"]["name"]]
|
|
30
28
|
return re.compile('|'.join(items)).search
|
|
31
29
|
|
|
32
30
|
def query_packages(self, searchinfo, sro):
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
from attrs import define
|
|
2
4
|
from defusedxml.xmlrpc import DefusedExpatParser
|
|
3
5
|
from devpi_common.metadata import Version
|
|
@@ -8,8 +10,10 @@ from devpi_common.validation import normalize_name
|
|
|
8
10
|
from devpi_common.viewhelp import iter_toxresults
|
|
9
11
|
from devpi_server.log import threadlog as log
|
|
10
12
|
from devpi_server.readonly import SeqViewReadonly
|
|
11
|
-
from devpi_server.views import StatusView, url_for_entrypath
|
|
12
13
|
from devpi_server.views import PyPIView
|
|
14
|
+
from devpi_server.views import StatusView
|
|
15
|
+
from devpi_server.views import is_simple_json_or_requested_by_installer
|
|
16
|
+
from devpi_server.views import url_for_entrypath
|
|
13
17
|
from devpi_web.description import get_description
|
|
14
18
|
from devpi_web.doczip import Docs
|
|
15
19
|
from devpi_web.doczip import docs_exist
|
|
@@ -19,24 +23,32 @@ from devpi_web.doczip import docs_file_path
|
|
|
19
23
|
from devpi_web.indexing import is_project_cached
|
|
20
24
|
from devpi_web.main import navigation_version
|
|
21
25
|
from email.utils import parsedate
|
|
22
|
-
from io import TextIOWrapper
|
|
23
26
|
from html import escape
|
|
24
|
-
from
|
|
27
|
+
from io import TextIOWrapper
|
|
28
|
+
from operator import attrgetter
|
|
29
|
+
from operator import itemgetter
|
|
25
30
|
from pyramid.decorator import reify
|
|
26
|
-
from pyramid.httpexceptions import HTTPBadGateway
|
|
27
|
-
from pyramid.httpexceptions import
|
|
31
|
+
from pyramid.httpexceptions import HTTPBadGateway
|
|
32
|
+
from pyramid.httpexceptions import HTTPError
|
|
33
|
+
from pyramid.httpexceptions import HTTPFound
|
|
34
|
+
from pyramid.httpexceptions import HTTPNotFound
|
|
28
35
|
from pyramid.httpexceptions import HTTPNotModified
|
|
29
36
|
from pyramid.httpexceptions import default_exceptionresponse_view
|
|
30
37
|
from pyramid.interfaces import IRoutesMapper
|
|
31
|
-
from pyramid.response import FileResponse
|
|
32
|
-
from pyramid.
|
|
38
|
+
from pyramid.response import FileResponse
|
|
39
|
+
from pyramid.response import Response
|
|
40
|
+
from pyramid.view import notfound_view_config
|
|
41
|
+
from pyramid.view import view_config
|
|
33
42
|
from time import gmtime
|
|
34
43
|
from typing import Any
|
|
35
|
-
from xmlrpc.client import Fault
|
|
44
|
+
from xmlrpc.client import Fault
|
|
45
|
+
from xmlrpc.client import Unmarshaller
|
|
46
|
+
from xmlrpc.client import dumps
|
|
36
47
|
import functools
|
|
37
48
|
import json
|
|
38
49
|
import mimetypes
|
|
39
50
|
|
|
51
|
+
|
|
40
52
|
seq_types = (list, tuple, SeqViewReadonly)
|
|
41
53
|
|
|
42
54
|
|
|
@@ -106,6 +118,8 @@ def ServerViews(context, request):
|
|
|
106
118
|
|
|
107
119
|
def tween_trailing_slash_redirect(handler, registry):
|
|
108
120
|
def request_trailing_slash_redirect_handler(request):
|
|
121
|
+
if is_simple_json_or_requested_by_installer(request):
|
|
122
|
+
return handler(request)
|
|
109
123
|
if request.path == "/":
|
|
110
124
|
return handler(request)
|
|
111
125
|
if request.method != "GET":
|
|
@@ -298,7 +312,8 @@ def sizeof_fmt(num):
|
|
|
298
312
|
|
|
299
313
|
def format_timetuple(tt):
|
|
300
314
|
if tt is not None:
|
|
301
|
-
return "{
|
|
315
|
+
return "{}-{:02d}-{:02d} {:02d}:{:02d}:{:02d}".format(*tt)
|
|
316
|
+
return None
|
|
302
317
|
|
|
303
318
|
|
|
304
319
|
def format_timestamp(ts, unset_value=None):
|
|
@@ -312,6 +327,12 @@ def format_timestamp(ts, unset_value=None):
|
|
|
312
327
|
return ts
|
|
313
328
|
|
|
314
329
|
|
|
330
|
+
def format_when(when):
|
|
331
|
+
if isinstance(when, str):
|
|
332
|
+
return when.replace("T", " ").rstrip("Z")
|
|
333
|
+
return format_timetuple(when)
|
|
334
|
+
|
|
335
|
+
|
|
315
336
|
_what_map = dict(
|
|
316
337
|
overwrite="Replaced",
|
|
317
338
|
push="Pushed",
|
|
@@ -323,7 +344,7 @@ def make_history_view_item(request, log_item):
|
|
|
323
344
|
result['what'] = _what_map.get(log_item['what'], log_item['what'])
|
|
324
345
|
result['who'] = log_item['who']
|
|
325
346
|
if log_item['what'] != 'overwrite':
|
|
326
|
-
result[
|
|
347
|
+
result["when"] = format_when(log_item["when"])
|
|
327
348
|
for key in ('dst', 'src'):
|
|
328
349
|
if key in log_item:
|
|
329
350
|
result[key] = dict(
|
|
@@ -972,8 +993,7 @@ def batch_list(num, current, left=3, right=3):
|
|
|
972
993
|
raise ValueError("Current position (%s) can't be greater than total (%s)." % (current, num))
|
|
973
994
|
result.append(0)
|
|
974
995
|
first = current - left
|
|
975
|
-
|
|
976
|
-
first = 1
|
|
996
|
+
first = max(first, 1)
|
|
977
997
|
if first > 1:
|
|
978
998
|
result.append(None)
|
|
979
999
|
last = current + right + 1
|
|
@@ -1093,7 +1113,7 @@ class SearchView:
|
|
|
1093
1113
|
highlight = None
|
|
1094
1114
|
if text_type == 'project':
|
|
1095
1115
|
continue
|
|
1096
|
-
|
|
1116
|
+
if text_type in ("title", "page"):
|
|
1097
1117
|
docs = self.get_docs(stage, data)
|
|
1098
1118
|
entry = docs[sub_data['text_path']]
|
|
1099
1119
|
text = entry['text']
|
|
@@ -1199,7 +1219,7 @@ class SearchView:
|
|
|
1199
1219
|
else:
|
|
1200
1220
|
fields = data
|
|
1201
1221
|
operator = "and"
|
|
1202
|
-
log.debug("xmlrpc_search
|
|
1222
|
+
log.debug("xmlrpc_search %s", (fields, operator))
|
|
1203
1223
|
return dict(fields=fields, operator=operator)
|
|
1204
1224
|
|
|
1205
1225
|
@view_config(
|