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.
Files changed (39) hide show
  1. {webdev-2.0.1 → webdev-2.1.0}/PKG-INFO +13 -1
  2. {webdev-2.0.1 → webdev-2.1.0}/README.rst +12 -0
  3. webdev-2.1.0/tests/test_mime.py +47 -0
  4. {webdev-2.0.1 → webdev-2.1.0}/tests/test_static.py +27 -2
  5. webdev-2.1.0/tests/testfiles/app.config +2 -0
  6. webdev-2.1.0/tests/testfiles/config.yaml +2 -0
  7. webdev-2.1.0/tests/testfiles/config.yml +2 -0
  8. webdev-2.1.0/tests/testfiles/data.json +4 -0
  9. webdev-2.1.0/tests/testfiles/email.j2 +1 -0
  10. webdev-2.1.0/tests/testfiles/newsletter.jinja2 +1 -0
  11. webdev-2.1.0/tests/testfiles/page.tpl +1 -0
  12. webdev-2.1.0/tests/testfiles/sample.toml +2 -0
  13. webdev-2.1.0/tests/testfiles/sample.txt +1 -0
  14. webdev-2.1.0/tests/testfiles/setup.ini +2 -0
  15. webdev-2.1.0/tests/testfiles/site.template +1 -0
  16. {webdev-2.0.1 → webdev-2.1.0}/webdev/__init__.py +1 -1
  17. {webdev-2.0.1 → webdev-2.1.0}/webdev/static.py +7 -0
  18. {webdev-2.0.1 → webdev-2.1.0}/.gitignore +0 -0
  19. {webdev-2.0.1 → webdev-2.1.0}/LICENSE +0 -0
  20. {webdev-2.0.1 → webdev-2.1.0}/pyproject.toml +0 -0
  21. {webdev-2.0.1 → webdev-2.1.0}/tests/conftest.py +0 -0
  22. {webdev-2.0.1 → webdev-2.1.0}/tests/test_config.py +0 -0
  23. {webdev-2.0.1 → webdev-2.1.0}/tests/test_index.py +0 -0
  24. {webdev-2.0.1 → webdev-2.1.0}/tests/test_livereload.py +0 -0
  25. {webdev-2.0.1 → webdev-2.1.0}/tests/test_net.py +0 -0
  26. {webdev-2.0.1 → webdev-2.1.0}/tests/test_server.py +0 -0
  27. {webdev-2.0.1 → webdev-2.1.0}/webdev/__main__.py +0 -0
  28. {webdev-2.0.1 → webdev-2.1.0}/webdev/cli.py +0 -0
  29. {webdev-2.0.1 → webdev-2.1.0}/webdev/config.py +0 -0
  30. {webdev-2.0.1 → webdev-2.1.0}/webdev/index.py +0 -0
  31. {webdev-2.0.1 → webdev-2.1.0}/webdev/livereload.py +0 -0
  32. {webdev-2.0.1 → webdev-2.1.0}/webdev/net.py +0 -0
  33. {webdev-2.0.1 → webdev-2.1.0}/webdev/run.py +0 -0
  34. {webdev-2.0.1 → webdev-2.1.0}/webdev/server.py +0 -0
  35. {webdev-2.0.1 → webdev-2.1.0}/webdev/templates/dark/base.html.jinja2 +0 -0
  36. {webdev-2.0.1 → webdev-2.1.0}/webdev/templates/dark/index.html.jinja2 +0 -0
  37. {webdev-2.0.1 → webdev-2.1.0}/webdev/templates/dark/partials/sort.js.jinja2 +0 -0
  38. {webdev-2.0.1 → webdev-2.1.0}/webdev/templates/dark/partials/styles.css.jinja2 +0 -0
  39. {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.1
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
- for name in ('conf.toml', 'setup.ini', 'app.cfg', 'notes.log'):
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,2 @@
1
+ debug = true
2
+ host = localhost
@@ -0,0 +1,2 @@
1
+ name: webdev
2
+ enabled: true
@@ -0,0 +1,2 @@
1
+ name: webdev
2
+ enabled: true
@@ -0,0 +1,4 @@
1
+ {
2
+ "name": "webdev",
3
+ "ok": true
4
+ }
@@ -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,2 @@
1
+ [tool.webdev]
2
+ port = 8080
@@ -0,0 +1 @@
1
+ Just a plain text note.
@@ -0,0 +1,2 @@
1
+ [server]
2
+ port = 8080
@@ -0,0 +1 @@
1
+ Hello {{ name }}, this is a .template file.
@@ -25,6 +25,6 @@ index, optional HTTPS, and more.
25
25
 
26
26
  from __future__ import annotations
27
27
 
28
- __version__ = '2.0.1'
28
+ __version__ = '2.1.0'
29
29
 
30
30
  __all__ = ['__version__']
@@ -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