blob-viewer 0.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.
- blob_viewer-0.1.0/.gitignore +220 -0
- blob_viewer-0.1.0/CHANGELOG.md +24 -0
- blob_viewer-0.1.0/LICENSE +21 -0
- blob_viewer-0.1.0/PKG-INFO +206 -0
- blob_viewer-0.1.0/README.md +144 -0
- blob_viewer-0.1.0/docs/api.md +80 -0
- blob_viewer-0.1.0/docs/architecture.md +86 -0
- blob_viewer-0.1.0/docs/cli.md +78 -0
- blob_viewer-0.1.0/docs/docker.md +73 -0
- blob_viewer-0.1.0/docs/faq.md +47 -0
- blob_viewer-0.1.0/docs/getting-started.md +71 -0
- blob_viewer-0.1.0/docs/index.md +49 -0
- blob_viewer-0.1.0/docs/install.md +59 -0
- blob_viewer-0.1.0/docs/preview-cache.md +52 -0
- blob_viewer-0.1.0/docs/security.md +53 -0
- blob_viewer-0.1.0/docs/themes.md +40 -0
- blob_viewer-0.1.0/docs/workspaces.md +70 -0
- blob_viewer-0.1.0/pyproject.toml +86 -0
- blob_viewer-0.1.0/src/blob_viewer/__init__.py +17 -0
- blob_viewer-0.1.0/src/blob_viewer/api.py +469 -0
- blob_viewer-0.1.0/src/blob_viewer/auth.py +115 -0
- blob_viewer-0.1.0/src/blob_viewer/cache.py +218 -0
- blob_viewer-0.1.0/src/blob_viewer/cli.py +723 -0
- blob_viewer-0.1.0/src/blob_viewer/db.py +143 -0
- blob_viewer-0.1.0/src/blob_viewer/desktop.py +92 -0
- blob_viewer-0.1.0/src/blob_viewer/paths.py +75 -0
- blob_viewer-0.1.0/src/blob_viewer/preview.py +106 -0
- blob_viewer-0.1.0/src/blob_viewer/secrets.py +79 -0
- blob_viewer-0.1.0/src/blob_viewer/server.py +93 -0
- blob_viewer-0.1.0/src/blob_viewer/service.py +97 -0
- blob_viewer-0.1.0/src/blob_viewer/static/css/base.css +489 -0
- blob_viewer-0.1.0/src/blob_viewer/static/css/themes.css +214 -0
- blob_viewer-0.1.0/src/blob_viewer/static/favicon.svg +5 -0
- blob_viewer-0.1.0/src/blob_viewer/static/js/api.js +71 -0
- blob_viewer-0.1.0/src/blob_viewer/static/js/app.js +1026 -0
- blob_viewer-0.1.0/src/blob_viewer/static/js/icons.js +65 -0
- blob_viewer-0.1.0/src/blob_viewer/static/js/ui.js +126 -0
- blob_viewer-0.1.0/src/blob_viewer/static/vendor/highjs/github-dark.min.css +10 -0
- blob_viewer-0.1.0/src/blob_viewer/static/vendor/highjs/github.min.css +10 -0
- blob_viewer-0.1.0/src/blob_viewer/static/vendor/highjs/highlight.min.js +1244 -0
- blob_viewer-0.1.0/src/blob_viewer/static/vendor/highjs/languages/bash.min.js +21 -0
- blob_viewer-0.1.0/src/blob_viewer/static/vendor/highjs/languages/c.min.js +41 -0
- blob_viewer-0.1.0/src/blob_viewer/static/vendor/highjs/languages/cpp.min.js +47 -0
- blob_viewer-0.1.0/src/blob_viewer/static/vendor/highjs/languages/csharp.min.js +49 -0
- blob_viewer-0.1.0/src/blob_viewer/static/vendor/highjs/languages/css.min.js +31 -0
- blob_viewer-0.1.0/src/blob_viewer/static/vendor/highjs/languages/dockerfile.min.js +8 -0
- blob_viewer-0.1.0/src/blob_viewer/static/vendor/highjs/languages/go.min.js +20 -0
- blob_viewer-0.1.0/src/blob_viewer/static/vendor/highjs/languages/graphql.min.js +12 -0
- blob_viewer-0.1.0/src/blob_viewer/static/vendor/highjs/languages/ini.min.js +15 -0
- blob_viewer-0.1.0/src/blob_viewer/static/vendor/highjs/languages/java.min.js +38 -0
- blob_viewer-0.1.0/src/blob_viewer/static/vendor/highjs/languages/javascript.min.js +81 -0
- blob_viewer-0.1.0/src/blob_viewer/static/vendor/highjs/languages/json.min.js +8 -0
- blob_viewer-0.1.0/src/blob_viewer/static/vendor/highjs/languages/kotlin.min.js +46 -0
- blob_viewer-0.1.0/src/blob_viewer/static/vendor/highjs/languages/lua.min.js +15 -0
- blob_viewer-0.1.0/src/blob_viewer/static/vendor/highjs/languages/markdown.min.js +32 -0
- blob_viewer-0.1.0/src/blob_viewer/static/vendor/highjs/languages/perl.min.js +41 -0
- blob_viewer-0.1.0/src/blob_viewer/static/vendor/highjs/languages/php.min.js +59 -0
- blob_viewer-0.1.0/src/blob_viewer/static/vendor/highjs/languages/protobuf.min.js +11 -0
- blob_viewer-0.1.0/src/blob_viewer/static/vendor/highjs/languages/python.min.js +42 -0
- blob_viewer-0.1.0/src/blob_viewer/static/vendor/highjs/languages/ruby.min.js +54 -0
- blob_viewer-0.1.0/src/blob_viewer/static/vendor/highjs/languages/rust.min.js +27 -0
- blob_viewer-0.1.0/src/blob_viewer/static/vendor/highjs/languages/sql.min.js +21 -0
- blob_viewer-0.1.0/src/blob_viewer/static/vendor/highjs/languages/swift.min.js +68 -0
- blob_viewer-0.1.0/src/blob_viewer/static/vendor/highjs/languages/typescript.min.js +99 -0
- blob_viewer-0.1.0/src/blob_viewer/static/vendor/highjs/languages/xml.min.js +29 -0
- blob_viewer-0.1.0/src/blob_viewer/static/vendor/highjs/languages/yaml.min.js +28 -0
- blob_viewer-0.1.0/src/blob_viewer/static/vendor/marked.min.js +69 -0
- blob_viewer-0.1.0/src/blob_viewer/static/vendor/pdfjs/pdf.min.mjs +21 -0
- blob_viewer-0.1.0/src/blob_viewer/static/vendor/pdfjs/pdf.worker.min.mjs +21 -0
- blob_viewer-0.1.0/src/blob_viewer/static/vendor/purify.min.js +3 -0
- blob_viewer-0.1.0/src/blob_viewer/storage/__init__.py +13 -0
- blob_viewer-0.1.0/src/blob_viewer/storage/base.py +73 -0
- blob_viewer-0.1.0/src/blob_viewer/storage/factory.py +26 -0
- blob_viewer-0.1.0/src/blob_viewer/storage/local.py +152 -0
- blob_viewer-0.1.0/src/blob_viewer/storage/s3.py +191 -0
- blob_viewer-0.1.0/src/blob_viewer/templates/index.html +35 -0
- blob_viewer-0.1.0/src/blob_viewer/themes.py +31 -0
- blob_viewer-0.1.0/src/blob_viewer/workspaces.py +299 -0
- blob_viewer-0.1.0/tests/__init__.py +0 -0
- blob_viewer-0.1.0/tests/conftest.py +100 -0
- blob_viewer-0.1.0/tests/test_api.py +150 -0
- blob_viewer-0.1.0/tests/test_core.py +193 -0
- blob_viewer-0.1.0/tests/test_e2e_browser.py +154 -0
- blob_viewer-0.1.0/tests/test_e2e_rustfs.py +81 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[codz]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
# Usually these files are written by a python script from a template
|
|
31
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
32
|
+
*.manifest
|
|
33
|
+
*.spec
|
|
34
|
+
|
|
35
|
+
# Installer logs
|
|
36
|
+
pip-log.txt
|
|
37
|
+
pip-delete-this-directory.txt
|
|
38
|
+
|
|
39
|
+
# Unit test / coverage reports
|
|
40
|
+
htmlcov/
|
|
41
|
+
.tox/
|
|
42
|
+
.nox/
|
|
43
|
+
.coverage
|
|
44
|
+
.coverage.*
|
|
45
|
+
.cache
|
|
46
|
+
nosetests.xml
|
|
47
|
+
coverage.xml
|
|
48
|
+
*.cover
|
|
49
|
+
*.py.cover
|
|
50
|
+
*.lcov
|
|
51
|
+
.hypothesis/
|
|
52
|
+
.pytest_cache/
|
|
53
|
+
cover/
|
|
54
|
+
|
|
55
|
+
# Translations
|
|
56
|
+
*.mo
|
|
57
|
+
*.pot
|
|
58
|
+
|
|
59
|
+
# Django stuff:
|
|
60
|
+
*.log
|
|
61
|
+
local_settings.py
|
|
62
|
+
db.sqlite3
|
|
63
|
+
db.sqlite3-journal
|
|
64
|
+
|
|
65
|
+
# Flask stuff:
|
|
66
|
+
instance/
|
|
67
|
+
.webassets-cache
|
|
68
|
+
|
|
69
|
+
# Scrapy stuff:
|
|
70
|
+
.scrapy
|
|
71
|
+
|
|
72
|
+
# Sphinx documentation
|
|
73
|
+
docs/_build/
|
|
74
|
+
|
|
75
|
+
# PyBuilder
|
|
76
|
+
.pybuilder/
|
|
77
|
+
target/
|
|
78
|
+
|
|
79
|
+
# Jupyter Notebook
|
|
80
|
+
.ipynb_checkpoints
|
|
81
|
+
|
|
82
|
+
# IPython
|
|
83
|
+
profile_default/
|
|
84
|
+
ipython_config.py
|
|
85
|
+
|
|
86
|
+
# pyenv
|
|
87
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
88
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
89
|
+
# .python-version
|
|
90
|
+
|
|
91
|
+
# pipenv
|
|
92
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
93
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
94
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
95
|
+
# install all needed dependencies.
|
|
96
|
+
# Pipfile.lock
|
|
97
|
+
|
|
98
|
+
# uv
|
|
99
|
+
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
|
100
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
101
|
+
# commonly ignored for libraries.
|
|
102
|
+
# uv.lock
|
|
103
|
+
|
|
104
|
+
# poetry
|
|
105
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
106
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
107
|
+
# commonly ignored for libraries.
|
|
108
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
109
|
+
# poetry.lock
|
|
110
|
+
# poetry.toml
|
|
111
|
+
|
|
112
|
+
# pdm
|
|
113
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
114
|
+
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
|
|
115
|
+
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
|
|
116
|
+
# pdm.lock
|
|
117
|
+
# pdm.toml
|
|
118
|
+
.pdm-python
|
|
119
|
+
.pdm-build/
|
|
120
|
+
|
|
121
|
+
# pixi
|
|
122
|
+
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
|
|
123
|
+
# pixi.lock
|
|
124
|
+
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
|
|
125
|
+
# in the .venv directory. It is recommended not to include this directory in version control.
|
|
126
|
+
.pixi/*
|
|
127
|
+
!.pixi/config.toml
|
|
128
|
+
|
|
129
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
130
|
+
__pypackages__/
|
|
131
|
+
|
|
132
|
+
# Celery stuff
|
|
133
|
+
celerybeat-schedule*
|
|
134
|
+
celerybeat.pid
|
|
135
|
+
|
|
136
|
+
# Redis
|
|
137
|
+
*.rdb
|
|
138
|
+
*.aof
|
|
139
|
+
*.pid
|
|
140
|
+
|
|
141
|
+
# RabbitMQ
|
|
142
|
+
mnesia/
|
|
143
|
+
rabbitmq/
|
|
144
|
+
rabbitmq-data/
|
|
145
|
+
|
|
146
|
+
# ActiveMQ
|
|
147
|
+
activemq-data/
|
|
148
|
+
|
|
149
|
+
# SageMath parsed files
|
|
150
|
+
*.sage.py
|
|
151
|
+
|
|
152
|
+
# Environments
|
|
153
|
+
.env
|
|
154
|
+
.envrc
|
|
155
|
+
.venv
|
|
156
|
+
env/
|
|
157
|
+
venv/
|
|
158
|
+
ENV/
|
|
159
|
+
env.bak/
|
|
160
|
+
venv.bak/
|
|
161
|
+
|
|
162
|
+
# Spyder project settings
|
|
163
|
+
.spyderproject
|
|
164
|
+
.spyproject
|
|
165
|
+
|
|
166
|
+
# Rope project settings
|
|
167
|
+
.ropeproject
|
|
168
|
+
|
|
169
|
+
# mkdocs/Zensical documentation
|
|
170
|
+
/site
|
|
171
|
+
|
|
172
|
+
# mypy
|
|
173
|
+
.mypy_cache/
|
|
174
|
+
.dmypy.json
|
|
175
|
+
dmypy.json
|
|
176
|
+
|
|
177
|
+
# Pyre type checker
|
|
178
|
+
.pyre/
|
|
179
|
+
|
|
180
|
+
# pytype static type analyzer
|
|
181
|
+
.pytype/
|
|
182
|
+
|
|
183
|
+
# Cython debug symbols
|
|
184
|
+
cython_debug/
|
|
185
|
+
|
|
186
|
+
# PyCharm
|
|
187
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
188
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
189
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
190
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
191
|
+
# .idea/
|
|
192
|
+
|
|
193
|
+
# Abstra
|
|
194
|
+
# Abstra is an AI-powered process automation framework.
|
|
195
|
+
# Ignore directories containing user credentials, local state, and settings.
|
|
196
|
+
# Learn more at https://abstra.io/docs
|
|
197
|
+
.abstra/
|
|
198
|
+
|
|
199
|
+
# Visual Studio Code
|
|
200
|
+
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore that
|
|
201
|
+
# can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
|
|
202
|
+
# and can be added to the global gitignore or merged into this file. However, if you prefer, you
|
|
203
|
+
# could uncomment the following to ignore the entire vscode folder
|
|
204
|
+
# .vscode/
|
|
205
|
+
# Temporary file for partial code execution
|
|
206
|
+
tempCodeRunnerFile.py
|
|
207
|
+
|
|
208
|
+
# Ruff stuff:
|
|
209
|
+
.ruff_cache/
|
|
210
|
+
|
|
211
|
+
# PyPI configuration file
|
|
212
|
+
.pypirc
|
|
213
|
+
|
|
214
|
+
# Marimo
|
|
215
|
+
marimo/_static/
|
|
216
|
+
marimo/_lsp/
|
|
217
|
+
__marimo__/
|
|
218
|
+
|
|
219
|
+
# Streamlit
|
|
220
|
+
.streamlit/secrets.toml
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to Blob Viewer are documented here. Format based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versioning follows [SemVer](https://semver.org/).
|
|
4
|
+
|
|
5
|
+
## [0.1.0] — 2026-10-11
|
|
6
|
+
|
|
7
|
+
First public release.
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Multiple workspaces: S3-compatible buckets (AWS S3, MinIO, RustFS, Backblaze B2, Cloudflare R2, DigitalOcean Spaces, Wasabi…) and local folders.
|
|
12
|
+
- Universal file preview: markdown (sanitised), source code with syntax highlighting (26 languages), PDF (pdf.js), images, audio, video, CSV tables and plain text.
|
|
13
|
+
- Local download cache with ETag-based version tracking, "update available" badges and one-click sync. Download-once semantics; offline access to cached files.
|
|
14
|
+
- OneDrive/MinIO-style web UI: sidebar workspaces, breadcrumbs, list/grid views, sorting, workspace-wide search, context menus, toasts.
|
|
15
|
+
- Eight themes (5 dark, 3 light) switchable live from the UI or CLI.
|
|
16
|
+
- Fully vendored frontend (marked, DOMPurify, highlight.js, pdf.js) — no CDN, air-gap friendly.
|
|
17
|
+
- Encrypted credential storage (Fernet at rest, redacted everywhere else).
|
|
18
|
+
- Locked mode (`--locked`) with master-admin bootstrap, PBKDF2 password hashing and server-side sessions.
|
|
19
|
+
- Guided CLI: `init`, `run`, `serve`, `workspace`, `user`, `cache`, `theme`, `doctor`, `version` — interactive and scriptable.
|
|
20
|
+
- Desktop app (pywebview) with automatic server-mode fallback.
|
|
21
|
+
- Docker image (multi-stage, non-root, ~195 MB) with healthcheck and volume-based persistence.
|
|
22
|
+
- Comprehensive docs, HTTP API reference and tests (unit, API, real-S3 e2e, Playwright browser e2e).
|
|
23
|
+
|
|
24
|
+
[0.1.0]: https://github.com/jasonjimnz/blob-viewer/releases/tag/v0.1.0
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Jason Jiménez Cruz
|
|
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.
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: blob-viewer
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A personal S3/MinIO bucket browser and file previewer. Desktop app (pywebview) and server, with a local download cache, multiple workspaces and a guided CLI.
|
|
5
|
+
Project-URL: Homepage, https://github.com/jasonjimnz/blob-viewer
|
|
6
|
+
Project-URL: Documentation, https://github.com/jasonjimnz/blob-viewer#readme
|
|
7
|
+
Project-URL: Repository, https://github.com/jasonjimnz/blob-viewer
|
|
8
|
+
Project-URL: Issues, https://github.com/jasonjimnz/blob-viewer/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/jasonjimnz/blob-viewer/blob/main/CHANGELOG.md
|
|
10
|
+
Author-email: Jason Jiménez Cruz <jasonjimenezcruz@gmail.com>
|
|
11
|
+
License: MIT License
|
|
12
|
+
|
|
13
|
+
Copyright (c) 2026 Jason Jiménez Cruz
|
|
14
|
+
|
|
15
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
16
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
17
|
+
in the Software without restriction, including without limitation the rights
|
|
18
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
19
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
20
|
+
furnished to do so, subject to the following conditions:
|
|
21
|
+
|
|
22
|
+
The above copyright notice and this permission notice shall be included in all
|
|
23
|
+
copies or substantial portions of the Software.
|
|
24
|
+
|
|
25
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
26
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
27
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
28
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
29
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
30
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
31
|
+
SOFTWARE.
|
|
32
|
+
License-File: LICENSE
|
|
33
|
+
Keywords: blob,boto3,bucket-browser,file-preview,minio,pywebview,s3,viewer
|
|
34
|
+
Classifier: Development Status :: 4 - Beta
|
|
35
|
+
Classifier: Environment :: Web Environment
|
|
36
|
+
Classifier: Environment :: X11 Applications
|
|
37
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
38
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
39
|
+
Classifier: Operating System :: OS Independent
|
|
40
|
+
Classifier: Programming Language :: Python :: 3
|
|
41
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
42
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
43
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
44
|
+
Classifier: Topic :: Desktop Environment :: File Managers
|
|
45
|
+
Classifier: Topic :: Utilities
|
|
46
|
+
Requires-Python: >=3.11
|
|
47
|
+
Requires-Dist: boto3>=1.35
|
|
48
|
+
Requires-Dist: cryptography>=43.0
|
|
49
|
+
Requires-Dist: flask>=3.1
|
|
50
|
+
Requires-Dist: pywebview>=5.4; python_version >= '3.11'
|
|
51
|
+
Requires-Dist: rich>=13.9
|
|
52
|
+
Requires-Dist: waitress>=3.0
|
|
53
|
+
Provides-Extra: dev
|
|
54
|
+
Requires-Dist: build>=1.2; extra == 'dev'
|
|
55
|
+
Requires-Dist: hatchling>=1.27; extra == 'dev'
|
|
56
|
+
Requires-Dist: markdown>=3.7; extra == 'dev'
|
|
57
|
+
Requires-Dist: pytest-cov>=6.0; extra == 'dev'
|
|
58
|
+
Requires-Dist: pytest>=8.3; extra == 'dev'
|
|
59
|
+
Requires-Dist: ruff>=0.8; extra == 'dev'
|
|
60
|
+
Requires-Dist: twine>=6.0; extra == 'dev'
|
|
61
|
+
Description-Content-Type: text/markdown
|
|
62
|
+
|
|
63
|
+
# Blob Viewer
|
|
64
|
+
|
|
65
|
+
**A personal S3/MinIO bucket browser and file previewer.**
|
|
66
|
+
|
|
67
|
+
Blob Viewer connects to any S3-compatible bucket — AWS S3, MinIO, Backblaze B2, Cloudflare R2, DigitalOcean Spaces, Wasabi — or to a plain local folder, and gives you a fast, modern file browser with previews for markdown, source code, PDFs, images, audio, video, CSV and more. Every file you open is cached locally, so your workspace is always available — even offline — and nothing is downloaded twice.
|
|
68
|
+
|
|
69
|
+
> Built for personal use by [Jason Jiménez Cruz](https://github.com/jasonjimnz).
|
|
70
|
+
|
|
71
|
+
## Highlights
|
|
72
|
+
|
|
73
|
+
- **Many workspaces** — register as many S3 buckets or local folders as you want and switch between them instantly.
|
|
74
|
+
- **Universal preview** — markdown, code with syntax highlighting, PDF, images, audio, video, CSV tables, plain text. Anything else is one click away as a download.
|
|
75
|
+
- **Local download cache** — files are fetched once and reused. When a newer version exists upstream, Blob Viewer tells you and lets you sync.
|
|
76
|
+
- **Remote workspaces are read-only** — blobs are never modified in place. Local workspaces stay fully writable.
|
|
77
|
+
- **Encrypted credentials** — access keys are encrypted at rest and always redacted in the UI and API; nobody can read them back from a config dump.
|
|
78
|
+
- **Locked mode** — start with `--locked` to require a master-admin login in the desktop app and the server.
|
|
79
|
+
- **Runs anywhere** — as a desktop app (pywebview), a headless server, or a small Docker container. The frontend is plain HTML/JS/CSS with vendored libraries: no CDN, no build step, works in isolated environments.
|
|
80
|
+
- **Many themes** — dark, light and coloured themes switchable from the UI.
|
|
81
|
+
|
|
82
|
+
## Install
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
pip install blob-viewer
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Python 3.11+ (3.13 recommended). For the desktop window on Linux you may need GTK/Qt libraries (`sudo apt install python3-gi gir1.2-webkit2-4.1` on Debian/Ubuntu); on Windows and macOS there are no extra requirements. If a GUI is unavailable, use server mode — everything works in the browser.
|
|
89
|
+
|
|
90
|
+
## Quick start
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
# guided setup: create your first workspace, pick a theme
|
|
94
|
+
blob-viewer init
|
|
95
|
+
|
|
96
|
+
# open the desktop app
|
|
97
|
+
blob-viewer run
|
|
98
|
+
|
|
99
|
+
# or serve it on the network (e.g. a home server / container)
|
|
100
|
+
blob-viewer serve --host 0.0.0.0 --port 8585
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Then open <http://127.0.0.1:8585> if you used `serve`.
|
|
104
|
+
|
|
105
|
+
### Locked mode
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
# first run asks you to create the master admin
|
|
109
|
+
blob-viewer run --locked
|
|
110
|
+
|
|
111
|
+
# CLI login is enforced in the desktop app and the server
|
|
112
|
+
blob-viewer serve --locked
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Managing workspaces
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
blob-viewer workspace add # guided wizard (S3 or local)
|
|
119
|
+
blob-viewer workspace list
|
|
120
|
+
blob-viewer workspace test my-bucket
|
|
121
|
+
blob-viewer workspace remove my-bucket
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Or do everything from the UI: **Settings → Workspaces → Add workspace**.
|
|
125
|
+
|
|
126
|
+
| Field | S3 workspace | Local workspace |
|
|
127
|
+
|---|---|---|
|
|
128
|
+
| Endpoint | `https://s3.amazonaws.com`, `http://localhost:9000`, ... | — |
|
|
129
|
+
| Bucket | required | — |
|
|
130
|
+
| Access / Secret key | encrypted at rest | — |
|
|
131
|
+
| Region | optional (`us-east-1` default) | — |
|
|
132
|
+
| Prefix | optional root path inside the bucket | — |
|
|
133
|
+
| Path style | on by default (MinIO/R2/B2) | — |
|
|
134
|
+
| Folder | — | any local path |
|
|
135
|
+
| Writable | never (read-only by design) | yes |
|
|
136
|
+
|
|
137
|
+
## CLI overview
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
blob-viewer init Guided first-run configuration
|
|
141
|
+
blob-viewer run [--locked] [--port] Launch the desktop app
|
|
142
|
+
blob-viewer serve [--locked] Headless server mode
|
|
143
|
+
blob-viewer workspace add|list|show|test|remove|edit
|
|
144
|
+
blob-viewer user create|reset|status Master admin for locked mode
|
|
145
|
+
blob-viewer cache stats|clear Inspect / empty the download cache
|
|
146
|
+
blob-viewer theme list|set Change the UI theme
|
|
147
|
+
blob-viewer doctor Diagnose installation problems
|
|
148
|
+
blob-viewer version Show version
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Run `blob-viewer <command> --help` for details on every command.
|
|
152
|
+
|
|
153
|
+
## Where is my data?
|
|
154
|
+
|
|
155
|
+
Everything lives in one folder (default `~/.blob-viewer`, override with `BLOB_VIEWER_HOME` or `--home`):
|
|
156
|
+
|
|
157
|
+
```
|
|
158
|
+
~/.blob-viewer/
|
|
159
|
+
├── blob-viewer.db # workspaces, settings, cache index (secrets encrypted)
|
|
160
|
+
├── secrets.key # per-installation encryption key (chmod 600)
|
|
161
|
+
└── cache/ # downloaded files, one folder per workspace
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Delete the folder = factory reset. Credentials are encrypted with a key that never leaves your machine; the API never returns secret values, only masked hints like `••••ab12`.
|
|
165
|
+
|
|
166
|
+
## Docker
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
docker run -d --name blob-viewer \
|
|
170
|
+
-p 8585:8585 -v blob-viewer-data:/data \
|
|
171
|
+
ghcr.io/jasonjimnz/blob-viewer:latest
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
The image is multi-stage, runs as a non-root user and stores state in the `/data` volume. `--locked` is honoured via the `BLOB_VIEWER_LOCKED=1` environment variable or the container command.
|
|
175
|
+
|
|
176
|
+
## Documentation
|
|
177
|
+
|
|
178
|
+
Full documentation lives in [`docs/`](docs/index.md):
|
|
179
|
+
|
|
180
|
+
- [Installation](docs/install.md)
|
|
181
|
+
- [Getting started](docs/getting-started.md)
|
|
182
|
+
- [Workspaces](docs/workspaces.md)
|
|
183
|
+
- [File preview & the cache](docs/preview-cache.md)
|
|
184
|
+
- [Security & locked mode](docs/security.md)
|
|
185
|
+
- [CLI reference](docs/cli.md)
|
|
186
|
+
- [HTTP API reference](docs/api.md)
|
|
187
|
+
- [Themes & customisation](docs/themes.md)
|
|
188
|
+
- [Docker deployment](docs/docker.md)
|
|
189
|
+
- [Architecture](docs/architecture.md)
|
|
190
|
+
- [Troubleshooting / FAQ](docs/faq.md)
|
|
191
|
+
|
|
192
|
+
## Development
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
git clone https://github.com/jasonjimnz/blob-viewer.git
|
|
196
|
+
cd blob-viewer
|
|
197
|
+
python -m venv .venv && .venv/Scripts/pip install -e .[dev] # POSIX: .venv/bin/pip
|
|
198
|
+
pytest # unit tests
|
|
199
|
+
pytest -m e2e # end-to-end tests (needs Docker; uses a throwaway MinIO)
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
See [docs/architecture.md](docs/architecture.md) for a tour of the codebase and how the pieces fit together.
|
|
203
|
+
|
|
204
|
+
## License
|
|
205
|
+
|
|
206
|
+
[MIT](LICENSE) © Jason Jiménez Cruz
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Blob Viewer
|
|
2
|
+
|
|
3
|
+
**A personal S3/MinIO bucket browser and file previewer.**
|
|
4
|
+
|
|
5
|
+
Blob Viewer connects to any S3-compatible bucket — AWS S3, MinIO, Backblaze B2, Cloudflare R2, DigitalOcean Spaces, Wasabi — or to a plain local folder, and gives you a fast, modern file browser with previews for markdown, source code, PDFs, images, audio, video, CSV and more. Every file you open is cached locally, so your workspace is always available — even offline — and nothing is downloaded twice.
|
|
6
|
+
|
|
7
|
+
> Built for personal use by [Jason Jiménez Cruz](https://github.com/jasonjimnz).
|
|
8
|
+
|
|
9
|
+
## Highlights
|
|
10
|
+
|
|
11
|
+
- **Many workspaces** — register as many S3 buckets or local folders as you want and switch between them instantly.
|
|
12
|
+
- **Universal preview** — markdown, code with syntax highlighting, PDF, images, audio, video, CSV tables, plain text. Anything else is one click away as a download.
|
|
13
|
+
- **Local download cache** — files are fetched once and reused. When a newer version exists upstream, Blob Viewer tells you and lets you sync.
|
|
14
|
+
- **Remote workspaces are read-only** — blobs are never modified in place. Local workspaces stay fully writable.
|
|
15
|
+
- **Encrypted credentials** — access keys are encrypted at rest and always redacted in the UI and API; nobody can read them back from a config dump.
|
|
16
|
+
- **Locked mode** — start with `--locked` to require a master-admin login in the desktop app and the server.
|
|
17
|
+
- **Runs anywhere** — as a desktop app (pywebview), a headless server, or a small Docker container. The frontend is plain HTML/JS/CSS with vendored libraries: no CDN, no build step, works in isolated environments.
|
|
18
|
+
- **Many themes** — dark, light and coloured themes switchable from the UI.
|
|
19
|
+
|
|
20
|
+
## Install
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pip install blob-viewer
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Python 3.11+ (3.13 recommended). For the desktop window on Linux you may need GTK/Qt libraries (`sudo apt install python3-gi gir1.2-webkit2-4.1` on Debian/Ubuntu); on Windows and macOS there are no extra requirements. If a GUI is unavailable, use server mode — everything works in the browser.
|
|
27
|
+
|
|
28
|
+
## Quick start
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
# guided setup: create your first workspace, pick a theme
|
|
32
|
+
blob-viewer init
|
|
33
|
+
|
|
34
|
+
# open the desktop app
|
|
35
|
+
blob-viewer run
|
|
36
|
+
|
|
37
|
+
# or serve it on the network (e.g. a home server / container)
|
|
38
|
+
blob-viewer serve --host 0.0.0.0 --port 8585
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Then open <http://127.0.0.1:8585> if you used `serve`.
|
|
42
|
+
|
|
43
|
+
### Locked mode
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
# first run asks you to create the master admin
|
|
47
|
+
blob-viewer run --locked
|
|
48
|
+
|
|
49
|
+
# CLI login is enforced in the desktop app and the server
|
|
50
|
+
blob-viewer serve --locked
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Managing workspaces
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
blob-viewer workspace add # guided wizard (S3 or local)
|
|
57
|
+
blob-viewer workspace list
|
|
58
|
+
blob-viewer workspace test my-bucket
|
|
59
|
+
blob-viewer workspace remove my-bucket
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Or do everything from the UI: **Settings → Workspaces → Add workspace**.
|
|
63
|
+
|
|
64
|
+
| Field | S3 workspace | Local workspace |
|
|
65
|
+
|---|---|---|
|
|
66
|
+
| Endpoint | `https://s3.amazonaws.com`, `http://localhost:9000`, ... | — |
|
|
67
|
+
| Bucket | required | — |
|
|
68
|
+
| Access / Secret key | encrypted at rest | — |
|
|
69
|
+
| Region | optional (`us-east-1` default) | — |
|
|
70
|
+
| Prefix | optional root path inside the bucket | — |
|
|
71
|
+
| Path style | on by default (MinIO/R2/B2) | — |
|
|
72
|
+
| Folder | — | any local path |
|
|
73
|
+
| Writable | never (read-only by design) | yes |
|
|
74
|
+
|
|
75
|
+
## CLI overview
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
blob-viewer init Guided first-run configuration
|
|
79
|
+
blob-viewer run [--locked] [--port] Launch the desktop app
|
|
80
|
+
blob-viewer serve [--locked] Headless server mode
|
|
81
|
+
blob-viewer workspace add|list|show|test|remove|edit
|
|
82
|
+
blob-viewer user create|reset|status Master admin for locked mode
|
|
83
|
+
blob-viewer cache stats|clear Inspect / empty the download cache
|
|
84
|
+
blob-viewer theme list|set Change the UI theme
|
|
85
|
+
blob-viewer doctor Diagnose installation problems
|
|
86
|
+
blob-viewer version Show version
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Run `blob-viewer <command> --help` for details on every command.
|
|
90
|
+
|
|
91
|
+
## Where is my data?
|
|
92
|
+
|
|
93
|
+
Everything lives in one folder (default `~/.blob-viewer`, override with `BLOB_VIEWER_HOME` or `--home`):
|
|
94
|
+
|
|
95
|
+
```
|
|
96
|
+
~/.blob-viewer/
|
|
97
|
+
├── blob-viewer.db # workspaces, settings, cache index (secrets encrypted)
|
|
98
|
+
├── secrets.key # per-installation encryption key (chmod 600)
|
|
99
|
+
└── cache/ # downloaded files, one folder per workspace
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Delete the folder = factory reset. Credentials are encrypted with a key that never leaves your machine; the API never returns secret values, only masked hints like `••••ab12`.
|
|
103
|
+
|
|
104
|
+
## Docker
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
docker run -d --name blob-viewer \
|
|
108
|
+
-p 8585:8585 -v blob-viewer-data:/data \
|
|
109
|
+
ghcr.io/jasonjimnz/blob-viewer:latest
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
The image is multi-stage, runs as a non-root user and stores state in the `/data` volume. `--locked` is honoured via the `BLOB_VIEWER_LOCKED=1` environment variable or the container command.
|
|
113
|
+
|
|
114
|
+
## Documentation
|
|
115
|
+
|
|
116
|
+
Full documentation lives in [`docs/`](docs/index.md):
|
|
117
|
+
|
|
118
|
+
- [Installation](docs/install.md)
|
|
119
|
+
- [Getting started](docs/getting-started.md)
|
|
120
|
+
- [Workspaces](docs/workspaces.md)
|
|
121
|
+
- [File preview & the cache](docs/preview-cache.md)
|
|
122
|
+
- [Security & locked mode](docs/security.md)
|
|
123
|
+
- [CLI reference](docs/cli.md)
|
|
124
|
+
- [HTTP API reference](docs/api.md)
|
|
125
|
+
- [Themes & customisation](docs/themes.md)
|
|
126
|
+
- [Docker deployment](docs/docker.md)
|
|
127
|
+
- [Architecture](docs/architecture.md)
|
|
128
|
+
- [Troubleshooting / FAQ](docs/faq.md)
|
|
129
|
+
|
|
130
|
+
## Development
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
git clone https://github.com/jasonjimnz/blob-viewer.git
|
|
134
|
+
cd blob-viewer
|
|
135
|
+
python -m venv .venv && .venv/Scripts/pip install -e .[dev] # POSIX: .venv/bin/pip
|
|
136
|
+
pytest # unit tests
|
|
137
|
+
pytest -m e2e # end-to-end tests (needs Docker; uses a throwaway MinIO)
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
See [docs/architecture.md](docs/architecture.md) for a tour of the codebase and how the pieces fit together.
|
|
141
|
+
|
|
142
|
+
## License
|
|
143
|
+
|
|
144
|
+
[MIT](LICENSE) © Jason Jiménez Cruz
|