uploadserver-preview 0.1.13__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 (31) hide show
  1. uploadserver_preview-0.1.13/LICENSE +35 -0
  2. uploadserver_preview-0.1.13/PKG-INFO +155 -0
  3. uploadserver_preview-0.1.13/README.md +129 -0
  4. uploadserver_preview-0.1.13/pyproject.toml +45 -0
  5. uploadserver_preview-0.1.13/setup.cfg +4 -0
  6. uploadserver_preview-0.1.13/uploadserver_preview/__init__.py +1027 -0
  7. uploadserver_preview-0.1.13/uploadserver_preview/__main__.py +3 -0
  8. uploadserver_preview-0.1.13/uploadserver_preview/assets/app.css +1078 -0
  9. uploadserver_preview-0.1.13/uploadserver_preview/assets/diff2html.core.min.js +1 -0
  10. uploadserver_preview-0.1.13/uploadserver_preview/assets/diff2html.min.css +1 -0
  11. uploadserver_preview-0.1.13/uploadserver_preview/assets/explorer.js +280 -0
  12. uploadserver_preview-0.1.13/uploadserver_preview/assets/git.js +233 -0
  13. uploadserver_preview-0.1.13/uploadserver_preview/assets/hljs-dockerfile.min.js +8 -0
  14. uploadserver_preview-0.1.13/uploadserver_preview/assets/hljs-github-dark.min.css +10 -0
  15. uploadserver_preview-0.1.13/uploadserver_preview/assets/hljs-github.min.css +10 -0
  16. uploadserver_preview-0.1.13/uploadserver_preview/assets/hljs.min.js +1244 -0
  17. uploadserver_preview-0.1.13/uploadserver_preview/assets/json-viewer.js +28 -0
  18. uploadserver_preview-0.1.13/uploadserver_preview/assets/marked.umd.js +79 -0
  19. uploadserver_preview-0.1.13/uploadserver_preview/assets/mobile.js +148 -0
  20. uploadserver_preview-0.1.13/uploadserver_preview/assets/papaparse.min.js +7 -0
  21. uploadserver_preview-0.1.13/uploadserver_preview/assets/purify.min.js +3 -0
  22. uploadserver_preview-0.1.13/uploadserver_preview/assets/themes.css +178 -0
  23. uploadserver_preview-0.1.13/uploadserver_preview/assets/upload.js +232 -0
  24. uploadserver_preview-0.1.13/uploadserver_preview/assets/viewer.js +481 -0
  25. uploadserver_preview-0.1.13/uploadserver_preview/gitinfo.py +203 -0
  26. uploadserver_preview-0.1.13/uploadserver_preview.egg-info/PKG-INFO +155 -0
  27. uploadserver_preview-0.1.13/uploadserver_preview.egg-info/SOURCES.txt +29 -0
  28. uploadserver_preview-0.1.13/uploadserver_preview.egg-info/dependency_links.txt +1 -0
  29. uploadserver_preview-0.1.13/uploadserver_preview.egg-info/entry_points.txt +2 -0
  30. uploadserver_preview-0.1.13/uploadserver_preview.egg-info/requires.txt +1 -0
  31. uploadserver_preview-0.1.13/uploadserver_preview.egg-info/top_level.txt +1 -0
@@ -0,0 +1,35 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Josey Mathew
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
23
+ ---
24
+
25
+ This package bundles third-party JavaScript libraries under
26
+ `uploadserver_preview/assets/`. Each is redistributed under its own license:
27
+
28
+ highlight.js BSD-3-Clause (github.com/highlightjs/highlight.js)
29
+ marked MIT (github.com/markedjs/marked)
30
+ DOMPurify Apache-2.0/MPL-2.0 (github.com/cure53/DOMPurify)
31
+ PapaParse MIT (github.com/mholt/PapaParse)
32
+ diff2html MIT (github.com/rtfpessoa/diff2html)
33
+ @andypf/json-viewer MIT (github.com/andypf/json-viewer)
34
+
35
+ When redistributing, retain the corresponding upstream license notices.
@@ -0,0 +1,155 @@
1
+ Metadata-Version: 2.4
2
+ Name: uploadserver-preview
3
+ Version: 0.1.13
4
+ Summary: uploadserver plus an in-browser previewer for developer files (Markdown, JSON, code, CSV, diffs, images). No build step; works offline on a LAN.
5
+ Author-email: Josey Mathew <tijoseymathew@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Repository, https://github.com/tijoseymathew/uploadserver-preview
8
+ Project-URL: Issues, https://github.com/tijoseymathew/uploadserver-preview/issues
9
+ Keywords: http,server,upload,file-server,preview,markdown,syntax-highlighting,diff
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Environment :: Web Environment
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Operating System :: OS Independent
20
+ Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
21
+ Requires-Python: >=3.9
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Requires-Dist: uploadserver<7,>=6.0
25
+ Dynamic: license-file
26
+
27
+ # uploadserver-preview
28
+
29
+ An in-browser previewer bolted onto [`uploadserver`](https://github.com/Densaugeo/uploadserver).
30
+ Browse a directory over HTTP and click a file to see it **rendered** instead of
31
+ downloaded: Markdown as formatted prose, JSON as a collapsible tree, source code
32
+ with syntax highlighting and line numbers, CSV/TSV as tables, unified diffs the
33
+ way GitHub shows them, and images inline.
34
+
35
+ Everything renders **client-side with vendored JavaScript** — no build step, no
36
+ CDN, no outbound network. It works on an air-gapped LAN, which is where a file
37
+ server like this usually lives. Uploads and every other `uploadserver` feature
38
+ (basic auth, TLS/mTLS, `--directory`, `--theme`, ...) are untouched.
39
+
40
+ ## Install
41
+
42
+ Published on PyPI as [`uploadserver-preview`](https://pypi.org/project/uploadserver-preview/).
43
+
44
+ With [`uv`](https://docs.astral.sh/uv/) (recommended — no separate install step):
45
+
46
+ ```bash
47
+ uvx uploadserver-preview # run once, in an ephemeral environment
48
+ uvx uploadserver-preview 9000 -d /srv
49
+ ```
50
+
51
+ Or install it properly, with either `uv` or `pip`:
52
+
53
+ ```bash
54
+ uv tool install uploadserver-preview
55
+ pip install uploadserver-preview
56
+ ```
57
+
58
+ This pulls in `uploadserver` as a dependency. Python 3.9+.
59
+
60
+ ## Use
61
+
62
+ Exactly like `uploadserver` — same arguments, same behaviour, plus previews:
63
+
64
+ ```bash
65
+ uploadserver-preview # serve ./ on :8000
66
+ uploadserver-preview 9000 -d /srv # port 9000, serve /srv
67
+ uploadserver-preview --theme dark
68
+ uploadserver-preview --basic-auth me:secret
69
+ python -m uploadserver_preview 8080 # module form also works
70
+ ```
71
+
72
+ Then open `http://<host>:8000/`, browse, and click a file. Each row shows a small
73
+ type tag (`md`, `json`, `py`, `csv`, …); previewable files open in the viewer,
74
+ anything else downloads. Every file also has a **raw** link.
75
+
76
+ ### Flags
77
+
78
+ All of `uploadserver`'s flags are accepted (`port`, `--directory/-d`,
79
+ `--bind/-b`, `--theme`, `--allow-replace`, `--server-certificate/-c`,
80
+ `--client-certificate`, `--basic-auth`, `--basic-auth-upload`, `--cgi`), plus:
81
+
82
+ | Flag | Effect |
83
+ |------|--------|
84
+ | `--no-preview` | Disable the previewer; behave like plain `uploadserver`. |
85
+
86
+ `--cgi` also disables the previewer (CGI mode is left to stock `uploadserver`).
87
+
88
+ ## What it renders
89
+
90
+ | Type | Extensions | Rendered as |
91
+ |------|-----------|-------------|
92
+ | Markdown | `.md .markdown .mdown .mkd` | Sanitized HTML prose; fenced code highlighted |
93
+ | JSON | `.json .geojson .ipynb` | Collapsible tree (falls back to highlighted source if invalid) |
94
+ | Config | `.yaml .yml .toml .ini .cfg .conf` | Highlighted source (comments preserved) |
95
+ | Code | `.py .js .ts .tsx .rs .go .java .c .cpp .rb .php .lua .sql .sh` and more | Highlighted, line-numbered |
96
+ | Tables | `.csv .tsv` | Sortable-width HTML table with row numbers |
97
+ | Diffs | `.diff .patch` | Line-by-line diff view |
98
+ | Images | `.png .jpg .jpeg .gif .webp .bmp .ico .avif .svg` | Inline, with dimensions |
99
+ | Markup | `.html .htm .xml .xhtml` | **Source only** — never executed |
100
+
101
+ Unrecognized extensions are shown as text when they look textual, and flagged as
102
+ binary otherwise. Text rendering is capped at 3 MB and tables at 5,000 rows to
103
+ keep the browser responsive; the raw link always serves the full file.
104
+
105
+ ## How it works
106
+
107
+ `uploadserver` exposes its request handler as a module-level name that
108
+ `serve_forever()` resolves at call time. This package subclasses that handler and
109
+ swaps it in before serving, so uploads and auth keep working while a few extra
110
+ routes are added:
111
+
112
+ - A browser navigating to a previewable file's own URL (detected via
113
+ `Sec-Fetch-Dest: document`) gets the explorer shell instead of raw bytes; the
114
+ client then fetches the file same-origin, dispatches on extension, and renders
115
+ it. `curl`/`wget`, `fetch()`, iframes — and anything with `?raw` — keep
116
+ getting the raw file, so scripted downloads behave like stock `uploadserver`.
117
+ - `GET /__view__?path=…` returns a small static viewer shell (kept for old
118
+ links). The server never reflects `path` into HTML.
119
+ - `GET /__preview_asset__/<name>` serves the vendored JS/CSS by basename from a
120
+ fixed whitelist (traversal-proof).
121
+ - Directory listings are replaced with a richer, themed listing that adds view
122
+ and raw links and the type tags.
123
+
124
+ Everything else — raw files, `/upload`, redirects — falls through to
125
+ `uploadserver` unchanged.
126
+
127
+ ## Security notes
128
+
129
+ - **Uploaded content is untrusted.** Markdown is sanitized with DOMPurify before
130
+ it touches the DOM. Code, JSON, YAML, CSV, and diffs are escaped or inserted as
131
+ text. HTML/SVG/XML files are shown as **source and never executed**; images are
132
+ loaded via `<img>`, where scripts do not run.
133
+ - A strict **Content-Security-Policy** is sent on preview pages: `script-src
134
+ 'self'` (all JS is external — there are no inline scripts), `default-src 'self'`,
135
+ `object-src 'none'`. Inline styles are permitted because the JSON component and
136
+ highlight/diff themes rely on them.
137
+ - Preview routes and assets are behind the same **basic auth** as the rest of the
138
+ server, so nothing is exposed before authentication.
139
+ - This is still a simple file server. Don't expose it to the public internet
140
+ without auth + TLS, exactly as with stock `uploadserver`.
141
+
142
+ ## Offline / vendored assets
143
+
144
+ All rendering libraries live under `uploadserver_preview/assets/` and are served
145
+ locally, so the previewer needs no internet access. Bundled: highlight.js
146
+ (common languages + Dockerfile), marked, DOMPurify, PapaParse, diff2html (core),
147
+ and `@andypf/json-viewer`. See `LICENSE` for their licenses.
148
+
149
+ ## Limitations
150
+
151
+ - No preview for PDF or Office documents (they open via the raw link, and modern
152
+ browsers render PDFs natively).
153
+ - Diffs are colored by line; intra-line syntax highlighting inside diffs is
154
+ omitted to keep the bundle small.
155
+ - CGI mode (`--cgi`) is served by stock `uploadserver` without previews.
@@ -0,0 +1,129 @@
1
+ # uploadserver-preview
2
+
3
+ An in-browser previewer bolted onto [`uploadserver`](https://github.com/Densaugeo/uploadserver).
4
+ Browse a directory over HTTP and click a file to see it **rendered** instead of
5
+ downloaded: Markdown as formatted prose, JSON as a collapsible tree, source code
6
+ with syntax highlighting and line numbers, CSV/TSV as tables, unified diffs the
7
+ way GitHub shows them, and images inline.
8
+
9
+ Everything renders **client-side with vendored JavaScript** — no build step, no
10
+ CDN, no outbound network. It works on an air-gapped LAN, which is where a file
11
+ server like this usually lives. Uploads and every other `uploadserver` feature
12
+ (basic auth, TLS/mTLS, `--directory`, `--theme`, ...) are untouched.
13
+
14
+ ## Install
15
+
16
+ Published on PyPI as [`uploadserver-preview`](https://pypi.org/project/uploadserver-preview/).
17
+
18
+ With [`uv`](https://docs.astral.sh/uv/) (recommended — no separate install step):
19
+
20
+ ```bash
21
+ uvx uploadserver-preview # run once, in an ephemeral environment
22
+ uvx uploadserver-preview 9000 -d /srv
23
+ ```
24
+
25
+ Or install it properly, with either `uv` or `pip`:
26
+
27
+ ```bash
28
+ uv tool install uploadserver-preview
29
+ pip install uploadserver-preview
30
+ ```
31
+
32
+ This pulls in `uploadserver` as a dependency. Python 3.9+.
33
+
34
+ ## Use
35
+
36
+ Exactly like `uploadserver` — same arguments, same behaviour, plus previews:
37
+
38
+ ```bash
39
+ uploadserver-preview # serve ./ on :8000
40
+ uploadserver-preview 9000 -d /srv # port 9000, serve /srv
41
+ uploadserver-preview --theme dark
42
+ uploadserver-preview --basic-auth me:secret
43
+ python -m uploadserver_preview 8080 # module form also works
44
+ ```
45
+
46
+ Then open `http://<host>:8000/`, browse, and click a file. Each row shows a small
47
+ type tag (`md`, `json`, `py`, `csv`, …); previewable files open in the viewer,
48
+ anything else downloads. Every file also has a **raw** link.
49
+
50
+ ### Flags
51
+
52
+ All of `uploadserver`'s flags are accepted (`port`, `--directory/-d`,
53
+ `--bind/-b`, `--theme`, `--allow-replace`, `--server-certificate/-c`,
54
+ `--client-certificate`, `--basic-auth`, `--basic-auth-upload`, `--cgi`), plus:
55
+
56
+ | Flag | Effect |
57
+ |------|--------|
58
+ | `--no-preview` | Disable the previewer; behave like plain `uploadserver`. |
59
+
60
+ `--cgi` also disables the previewer (CGI mode is left to stock `uploadserver`).
61
+
62
+ ## What it renders
63
+
64
+ | Type | Extensions | Rendered as |
65
+ |------|-----------|-------------|
66
+ | Markdown | `.md .markdown .mdown .mkd` | Sanitized HTML prose; fenced code highlighted |
67
+ | JSON | `.json .geojson .ipynb` | Collapsible tree (falls back to highlighted source if invalid) |
68
+ | Config | `.yaml .yml .toml .ini .cfg .conf` | Highlighted source (comments preserved) |
69
+ | Code | `.py .js .ts .tsx .rs .go .java .c .cpp .rb .php .lua .sql .sh` and more | Highlighted, line-numbered |
70
+ | Tables | `.csv .tsv` | Sortable-width HTML table with row numbers |
71
+ | Diffs | `.diff .patch` | Line-by-line diff view |
72
+ | Images | `.png .jpg .jpeg .gif .webp .bmp .ico .avif .svg` | Inline, with dimensions |
73
+ | Markup | `.html .htm .xml .xhtml` | **Source only** — never executed |
74
+
75
+ Unrecognized extensions are shown as text when they look textual, and flagged as
76
+ binary otherwise. Text rendering is capped at 3 MB and tables at 5,000 rows to
77
+ keep the browser responsive; the raw link always serves the full file.
78
+
79
+ ## How it works
80
+
81
+ `uploadserver` exposes its request handler as a module-level name that
82
+ `serve_forever()` resolves at call time. This package subclasses that handler and
83
+ swaps it in before serving, so uploads and auth keep working while a few extra
84
+ routes are added:
85
+
86
+ - A browser navigating to a previewable file's own URL (detected via
87
+ `Sec-Fetch-Dest: document`) gets the explorer shell instead of raw bytes; the
88
+ client then fetches the file same-origin, dispatches on extension, and renders
89
+ it. `curl`/`wget`, `fetch()`, iframes — and anything with `?raw` — keep
90
+ getting the raw file, so scripted downloads behave like stock `uploadserver`.
91
+ - `GET /__view__?path=…` returns a small static viewer shell (kept for old
92
+ links). The server never reflects `path` into HTML.
93
+ - `GET /__preview_asset__/<name>` serves the vendored JS/CSS by basename from a
94
+ fixed whitelist (traversal-proof).
95
+ - Directory listings are replaced with a richer, themed listing that adds view
96
+ and raw links and the type tags.
97
+
98
+ Everything else — raw files, `/upload`, redirects — falls through to
99
+ `uploadserver` unchanged.
100
+
101
+ ## Security notes
102
+
103
+ - **Uploaded content is untrusted.** Markdown is sanitized with DOMPurify before
104
+ it touches the DOM. Code, JSON, YAML, CSV, and diffs are escaped or inserted as
105
+ text. HTML/SVG/XML files are shown as **source and never executed**; images are
106
+ loaded via `<img>`, where scripts do not run.
107
+ - A strict **Content-Security-Policy** is sent on preview pages: `script-src
108
+ 'self'` (all JS is external — there are no inline scripts), `default-src 'self'`,
109
+ `object-src 'none'`. Inline styles are permitted because the JSON component and
110
+ highlight/diff themes rely on them.
111
+ - Preview routes and assets are behind the same **basic auth** as the rest of the
112
+ server, so nothing is exposed before authentication.
113
+ - This is still a simple file server. Don't expose it to the public internet
114
+ without auth + TLS, exactly as with stock `uploadserver`.
115
+
116
+ ## Offline / vendored assets
117
+
118
+ All rendering libraries live under `uploadserver_preview/assets/` and are served
119
+ locally, so the previewer needs no internet access. Bundled: highlight.js
120
+ (common languages + Dockerfile), marked, DOMPurify, PapaParse, diff2html (core),
121
+ and `@andypf/json-viewer`. See `LICENSE` for their licenses.
122
+
123
+ ## Limitations
124
+
125
+ - No preview for PDF or Office documents (they open via the raw link, and modern
126
+ browsers render PDFs natively).
127
+ - Diffs are colored by line; intra-line syntax highlighting inside diffs is
128
+ omitted to keep the bundle small.
129
+ - CGI mode (`--cgi`) is served by stock `uploadserver` without previews.
@@ -0,0 +1,45 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "uploadserver-preview"
7
+ version = "0.1.13"
8
+ description = "uploadserver plus an in-browser previewer for developer files (Markdown, JSON, code, CSV, diffs, images). No build step; works offline on a LAN."
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ authors = [
14
+ { name = "Josey Mathew", email = "tijoseymathew@gmail.com" },
15
+ ]
16
+ keywords = ["http", "server", "upload", "file-server", "preview", "markdown", "syntax-highlighting", "diff"]
17
+ classifiers = [
18
+ "Development Status :: 4 - Beta",
19
+ "Environment :: Web Environment",
20
+ "Intended Audience :: Developers",
21
+ "Programming Language :: Python :: 3",
22
+ "Programming Language :: Python :: 3.9",
23
+ "Programming Language :: Python :: 3.10",
24
+ "Programming Language :: Python :: 3.11",
25
+ "Programming Language :: Python :: 3.12",
26
+ "Programming Language :: Python :: 3.13",
27
+ "Operating System :: OS Independent",
28
+ "Topic :: Internet :: WWW/HTTP :: HTTP Servers",
29
+ ]
30
+ dependencies = [
31
+ "uploadserver>=6.0,<7",
32
+ ]
33
+
34
+ [project.urls]
35
+ Repository = "https://github.com/tijoseymathew/uploadserver-preview"
36
+ Issues = "https://github.com/tijoseymathew/uploadserver-preview/issues"
37
+
38
+ [project.scripts]
39
+ uploadserver-preview = "uploadserver_preview:main"
40
+
41
+ [tool.setuptools]
42
+ packages = ["uploadserver_preview"]
43
+
44
+ [tool.setuptools.package-data]
45
+ uploadserver_preview = ["assets/*"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+