webdev 2.0.1__tar.gz → 2.1.0__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.
- {webdev-2.0.1 → webdev-2.1.0}/PKG-INFO +13 -1
- {webdev-2.0.1 → webdev-2.1.0}/README.rst +12 -0
- webdev-2.1.0/tests/test_mime.py +47 -0
- {webdev-2.0.1 → webdev-2.1.0}/tests/test_static.py +27 -2
- webdev-2.1.0/tests/testfiles/app.config +2 -0
- webdev-2.1.0/tests/testfiles/config.yaml +2 -0
- webdev-2.1.0/tests/testfiles/config.yml +2 -0
- webdev-2.1.0/tests/testfiles/data.json +4 -0
- webdev-2.1.0/tests/testfiles/email.j2 +1 -0
- webdev-2.1.0/tests/testfiles/newsletter.jinja2 +1 -0
- webdev-2.1.0/tests/testfiles/page.tpl +1 -0
- webdev-2.1.0/tests/testfiles/sample.toml +2 -0
- webdev-2.1.0/tests/testfiles/sample.txt +1 -0
- webdev-2.1.0/tests/testfiles/setup.ini +2 -0
- webdev-2.1.0/tests/testfiles/site.template +1 -0
- {webdev-2.0.1 → webdev-2.1.0}/webdev/__init__.py +1 -1
- {webdev-2.0.1 → webdev-2.1.0}/webdev/static.py +7 -0
- {webdev-2.0.1 → webdev-2.1.0}/.gitignore +0 -0
- {webdev-2.0.1 → webdev-2.1.0}/LICENSE +0 -0
- {webdev-2.0.1 → webdev-2.1.0}/pyproject.toml +0 -0
- {webdev-2.0.1 → webdev-2.1.0}/tests/conftest.py +0 -0
- {webdev-2.0.1 → webdev-2.1.0}/tests/test_config.py +0 -0
- {webdev-2.0.1 → webdev-2.1.0}/tests/test_index.py +0 -0
- {webdev-2.0.1 → webdev-2.1.0}/tests/test_livereload.py +0 -0
- {webdev-2.0.1 → webdev-2.1.0}/tests/test_net.py +0 -0
- {webdev-2.0.1 → webdev-2.1.0}/tests/test_server.py +0 -0
- {webdev-2.0.1 → webdev-2.1.0}/webdev/__main__.py +0 -0
- {webdev-2.0.1 → webdev-2.1.0}/webdev/cli.py +0 -0
- {webdev-2.0.1 → webdev-2.1.0}/webdev/config.py +0 -0
- {webdev-2.0.1 → webdev-2.1.0}/webdev/index.py +0 -0
- {webdev-2.0.1 → webdev-2.1.0}/webdev/livereload.py +0 -0
- {webdev-2.0.1 → webdev-2.1.0}/webdev/net.py +0 -0
- {webdev-2.0.1 → webdev-2.1.0}/webdev/run.py +0 -0
- {webdev-2.0.1 → webdev-2.1.0}/webdev/server.py +0 -0
- {webdev-2.0.1 → webdev-2.1.0}/webdev/templates/dark/base.html.jinja2 +0 -0
- {webdev-2.0.1 → webdev-2.1.0}/webdev/templates/dark/index.html.jinja2 +0 -0
- {webdev-2.0.1 → webdev-2.1.0}/webdev/templates/dark/partials/sort.js.jinja2 +0 -0
- {webdev-2.0.1 → webdev-2.1.0}/webdev/templates/dark/partials/styles.css.jinja2 +0 -0
- {webdev-2.0.1 → webdev-2.1.0}/webdev/tls.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: webdev
|
|
3
|
-
Version: 2.0
|
|
3
|
+
Version: 2.1.0
|
|
4
4
|
Summary: Small, fast development web server with a modern dark directory index
|
|
5
5
|
Project-URL: Homepage, https://github.com/kuralabs/webdev
|
|
6
6
|
Project-URL: Repository, https://github.com/kuralabs/webdev
|
|
@@ -94,6 +94,9 @@ Features
|
|
|
94
94
|
startup so you can open the site on your phone.
|
|
95
95
|
- 🌈 **Colorized, level-aware logs** for readable output.
|
|
96
96
|
- ⚡ **No-cache headers** for always-fresh development content.
|
|
97
|
+
- 👀 **Previews text inline** — plain-text, config and template files (``.txt``,
|
|
98
|
+
``.json``, ``.yaml``, ``.ini``, ``.toml``, ``.j2``/``.jinja2``, ``.template``,
|
|
99
|
+
``.config`` and more) open in the browser instead of being downloaded.
|
|
97
100
|
- 🧭 **SPA fallback** — optionally serve ``index.html`` for unknown routes.
|
|
98
101
|
- 📦 **Gzip**, **CORS** and optional **HTTPS** (self-signed if no cert/key is
|
|
99
102
|
given).
|
|
@@ -191,6 +194,15 @@ installs only what it needs.
|
|
|
191
194
|
Changelog
|
|
192
195
|
=========
|
|
193
196
|
|
|
197
|
+
2.1.0
|
|
198
|
+
-----
|
|
199
|
+
|
|
200
|
+
**New**
|
|
201
|
+
|
|
202
|
+
- Plain-text, config and template files (such as ``.yaml``, ``.tpl``, ``.j2``,
|
|
203
|
+
``.jinja2``, ``.template`` and ``.config``) now open inline in the browser
|
|
204
|
+
instead of being downloaded (issue #8). Thanks to zaro0508 for the report.
|
|
205
|
+
|
|
194
206
|
2.0.1
|
|
195
207
|
-----
|
|
196
208
|
|
|
@@ -64,6 +64,9 @@ Features
|
|
|
64
64
|
startup so you can open the site on your phone.
|
|
65
65
|
- 🌈 **Colorized, level-aware logs** for readable output.
|
|
66
66
|
- ⚡ **No-cache headers** for always-fresh development content.
|
|
67
|
+
- 👀 **Previews text inline** — plain-text, config and template files (``.txt``,
|
|
68
|
+
``.json``, ``.yaml``, ``.ini``, ``.toml``, ``.j2``/``.jinja2``, ``.template``,
|
|
69
|
+
``.config`` and more) open in the browser instead of being downloaded.
|
|
67
70
|
- 🧭 **SPA fallback** — optionally serve ``index.html`` for unknown routes.
|
|
68
71
|
- 📦 **Gzip**, **CORS** and optional **HTTPS** (self-signed if no cert/key is
|
|
69
72
|
given).
|
|
@@ -161,6 +164,15 @@ installs only what it needs.
|
|
|
161
164
|
Changelog
|
|
162
165
|
=========
|
|
163
166
|
|
|
167
|
+
2.1.0
|
|
168
|
+
-----
|
|
169
|
+
|
|
170
|
+
**New**
|
|
171
|
+
|
|
172
|
+
- Plain-text, config and template files (such as ``.yaml``, ``.tpl``, ``.j2``,
|
|
173
|
+
``.jinja2``, ``.template`` and ``.config``) now open inline in the browser
|
|
174
|
+
instead of being downloaded (issue #8). Thanks to zaro0508 for the report.
|
|
175
|
+
|
|
164
176
|
2.0.1
|
|
165
177
|
-----
|
|
166
178
|
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Serve the committed ``testfiles`` fixtures and assert plain-text, config and
|
|
3
|
+
template files load inline in the browser instead of being downloaded.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
import pytest
|
|
11
|
+
from starlette.testclient import TestClient
|
|
12
|
+
|
|
13
|
+
from webdev.config import Settings
|
|
14
|
+
from webdev.server import create_app
|
|
15
|
+
from webdev.static import guess_media_type
|
|
16
|
+
|
|
17
|
+
TESTFILES = Path(__file__).parent / 'testfiles'
|
|
18
|
+
|
|
19
|
+
#: Every committed fixture, discovered dynamically.
|
|
20
|
+
FIXTURES = sorted(p for p in TESTFILES.iterdir() if p.is_file())
|
|
21
|
+
|
|
22
|
+
#: Content types browsers render inline rather than offering to download.
|
|
23
|
+
INLINE_TYPES = {'text/plain', 'application/json'}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@pytest.fixture
|
|
27
|
+
def testfiles_client() -> TestClient:
|
|
28
|
+
settings = Settings(
|
|
29
|
+
path=str(TESTFILES),
|
|
30
|
+
reload=False,
|
|
31
|
+
qr=False,
|
|
32
|
+
gzip=False,
|
|
33
|
+
).normalized()
|
|
34
|
+
return TestClient(create_app(settings))
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@pytest.mark.parametrize('fixture', FIXTURES, ids=lambda p: p.name)
|
|
38
|
+
def test_file_served_inline(testfiles_client: TestClient, fixture: Path) -> None:
|
|
39
|
+
with testfiles_client as c:
|
|
40
|
+
resp = c.get('/{}'.format(fixture.name))
|
|
41
|
+
assert resp.status_code == 200
|
|
42
|
+
|
|
43
|
+
content_type = resp.headers['content-type'].split(';')[0]
|
|
44
|
+
assert content_type == guess_media_type(fixture)
|
|
45
|
+
assert content_type in INLINE_TYPES
|
|
46
|
+
# The browser must render the file, never download it.
|
|
47
|
+
assert 'attachment' not in resp.headers.get('content-disposition', '')
|
|
@@ -46,10 +46,35 @@ def test_find_index_file(served_dir: Path) -> None:
|
|
|
46
46
|
|
|
47
47
|
|
|
48
48
|
def test_guess_media_type_registered_extensions(tmp_path: Path) -> None:
|
|
49
|
-
|
|
49
|
+
extensions = (
|
|
50
|
+
'conf.toml',
|
|
51
|
+
'setup.ini',
|
|
52
|
+
'app.cfg',
|
|
53
|
+
'notes.log',
|
|
54
|
+
'config.yaml',
|
|
55
|
+
'config.yml',
|
|
56
|
+
'site.template',
|
|
57
|
+
'page.tmpl',
|
|
58
|
+
'legacy.tpl',
|
|
59
|
+
'email.j2',
|
|
60
|
+
'base.jinja',
|
|
61
|
+
'newsletter.jinja2',
|
|
62
|
+
'app.config',
|
|
63
|
+
)
|
|
64
|
+
for name in extensions:
|
|
50
65
|
f = tmp_path / name
|
|
51
66
|
f.write_text('key = 1')
|
|
52
|
-
assert guess_media_type(f) == 'text/plain'
|
|
67
|
+
assert guess_media_type(f) == 'text/plain', name
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def test_guess_media_type_txt_and_json(tmp_path: Path) -> None:
|
|
71
|
+
txt = tmp_path / 'notes.txt'
|
|
72
|
+
txt.write_text('hello')
|
|
73
|
+
assert guess_media_type(txt) == 'text/plain'
|
|
74
|
+
|
|
75
|
+
data = tmp_path / 'data.json'
|
|
76
|
+
data.write_text('{"ok": true}')
|
|
77
|
+
assert guess_media_type(data) == 'application/json'
|
|
53
78
|
|
|
54
79
|
|
|
55
80
|
def test_guess_media_type_known_binary(tmp_path: Path) -> None:
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Hello {{ name }}, this is a Jinja2 template.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<p>Hello {{ name }}</p>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Hello {{ name }}, this is a .tpl template.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Just a plain text note.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Hello {{ name }}, this is a .template file.
|
|
@@ -50,6 +50,13 @@ EXTRA_MIME_TYPES = {
|
|
|
50
50
|
'.svelte': 'text/plain',
|
|
51
51
|
'.yml': 'text/plain',
|
|
52
52
|
'.yaml': 'text/plain',
|
|
53
|
+
'.template': 'text/plain',
|
|
54
|
+
'.tmpl': 'text/plain',
|
|
55
|
+
'.tpl': 'text/plain',
|
|
56
|
+
'.j2': 'text/plain',
|
|
57
|
+
'.jinja': 'text/plain',
|
|
58
|
+
'.jinja2': 'text/plain',
|
|
59
|
+
'.config': 'text/plain',
|
|
53
60
|
}
|
|
54
61
|
|
|
55
62
|
#: Number of bytes inspected when sniffing whether an unknown file is text.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|