work on improving stability
This commit is contained in:
@@ -8,7 +8,7 @@ tono is a node-based SPM image processing and analysis tool. The main focus is o
|
|||||||
|
|
||||||
It is heavily inspired by [Gwyddion](https://gwyddion.net/), one of my favorite scientific FOSS programs on the web.
|
It is heavily inspired by [Gwyddion](https://gwyddion.net/), one of my favorite scientific FOSS programs on the web.
|
||||||
|
|
||||||
<img src="frontend/public/default-workflow.png" width="600">
|
<img src="frontend/public/default-workflow.png" width="800">
|
||||||
|
|
||||||
## Quick start
|
## Quick start
|
||||||
Install a local binary from the Releases section, or run locally:
|
Install a local binary from the Releases section, or run locally:
|
||||||
@@ -28,9 +28,10 @@ npm run dev # terminal 2 — Vite dev server, open the URL it prints
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/VIPQualityPost/tono.git && cd tono
|
git clone https://github.com/VIPQualityPost/tono.git && cd tono
|
||||||
|
python -m venv .venv && source .venv/bin/activate
|
||||||
pip install -e .
|
pip install -e .
|
||||||
cd frontend && npm ci && npm run build && cd ..
|
cd frontend && npm ci && npm run build && cd ..
|
||||||
TONO_HOST=0.0.0.0 tono
|
TONO_HOST=0.0.0.0 python -m backend.main
|
||||||
```
|
```
|
||||||
|
|
||||||
See [Self-Hosting](docs/self-hosting.md) for reverse proxy setup, environment variables, and configuration.
|
See [Self-Hosting](docs/self-hosting.md) for reverse proxy setup, environment variables, and configuration.
|
||||||
|
|||||||
@@ -715,10 +715,18 @@ def create_app(
|
|||||||
app.router.add_get("/check-update", check_update)
|
app.router.add_get("/check-update", check_update)
|
||||||
app.router.add_get("/ws", websocket_handler)
|
app.router.add_get("/ws", websocket_handler)
|
||||||
|
|
||||||
|
async def dist_file(request: web.Request) -> web.Response:
|
||||||
|
filename = request.match_info["filename"]
|
||||||
|
path = (DIST_DIR / filename).resolve()
|
||||||
|
if not path.is_relative_to(DIST_DIR.resolve()) or not path.is_file():
|
||||||
|
raise web.HTTPNotFound()
|
||||||
|
return web.FileResponse(path)
|
||||||
|
|
||||||
if (DIST_DIR / "assets").exists():
|
if (DIST_DIR / "assets").exists():
|
||||||
app.router.add_static("/assets", DIST_DIR / "assets")
|
app.router.add_static("/assets", DIST_DIR / "assets")
|
||||||
if FRONTEND_DIR.exists():
|
if FRONTEND_DIR.exists():
|
||||||
app.router.add_static("/static", FRONTEND_DIR)
|
app.router.add_static("/static", FRONTEND_DIR)
|
||||||
|
app.router.add_get("/{filename}", dist_file)
|
||||||
|
|
||||||
async def _cors_middleware(app_, handler):
|
async def _cors_middleware(app_, handler):
|
||||||
async def middleware(request):
|
async def middleware(request):
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ git clone https://github.com/VIPQualityPost/tono.git && cd tono
|
|||||||
python -m venv .venv && source .venv/bin/activate
|
python -m venv .venv && source .venv/bin/activate
|
||||||
pip install -e .
|
pip install -e .
|
||||||
cd frontend && npm ci && npm run build && cd ..
|
cd frontend && npm ci && npm run build && cd ..
|
||||||
TONO_HOST=0.0.0.0 tono
|
TONO_HOST=0.0.0.0 python -m backend.main
|
||||||
```
|
```
|
||||||
|
|
||||||
The server will be available at `http://<your-server-ip>:8188`.
|
The server will be available at `http://<your-server-ip>:8188`.
|
||||||
@@ -48,7 +48,7 @@ After=network.target
|
|||||||
Type=simple
|
Type=simple
|
||||||
User=tono
|
User=tono
|
||||||
WorkingDirectory=/opt/tono
|
WorkingDirectory=/opt/tono
|
||||||
ExecStart=/opt/tono/.venv/bin/tono
|
ExecStart=/opt/tono/.venv/bin/python -m backend.main
|
||||||
Environment=TONO_HOST=127.0.0.1
|
Environment=TONO_HOST=127.0.0.1
|
||||||
Environment=TONO_PORT=8188
|
Environment=TONO_PORT=8188
|
||||||
Environment=TONO_APPDATA=/var/lib/tono
|
Environment=TONO_APPDATA=/var/lib/tono
|
||||||
|
|||||||
@@ -4,16 +4,18 @@ import { marked } from 'marked';
|
|||||||
import DOMPurify from 'dompurify';
|
import DOMPurify from 'dompurify';
|
||||||
|
|
||||||
// Open external links in new tabs
|
// Open external links in new tabs
|
||||||
const renderer = new marked.Renderer();
|
marked.use({
|
||||||
const defaultLinkRenderer = renderer.link.bind(renderer);
|
renderer: {
|
||||||
renderer.link = function (token) {
|
link({ href, title, tokens }) {
|
||||||
const html = defaultLinkRenderer(token);
|
const text = this.parser.parseInline(tokens ?? []);
|
||||||
if (token.href && /^https?:\/\//.test(token.href)) {
|
const titleAttr = title ? ` title="${title}"` : '';
|
||||||
return html.replace(/^<a /, '<a target="_blank" rel="noopener noreferrer" ');
|
if (href && /^https?:\/\//.test(href)) {
|
||||||
|
return `<a href="${href}"${titleAttr} target="_blank" rel="noopener noreferrer">${text}</a>`;
|
||||||
}
|
}
|
||||||
return html;
|
return `<a href="${href || ''}"${titleAttr}>${text}</a>`;
|
||||||
};
|
},
|
||||||
marked.use({ renderer });
|
},
|
||||||
|
});
|
||||||
|
|
||||||
interface Heading {
|
interface Heading {
|
||||||
level: number;
|
level: number;
|
||||||
|
|||||||
@@ -608,10 +608,10 @@ html, body, #root {
|
|||||||
|
|
||||||
.node-help-panel {
|
.node-help-panel {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 60px;
|
top: 12px;
|
||||||
right: 20px;
|
right: 20px;
|
||||||
width: 620px;
|
width: 620px;
|
||||||
max-height: calc(100vh - 80px);
|
max-height: calc(100vh - 32px);
|
||||||
background: #1e293b;
|
background: #1e293b;
|
||||||
border: 1px solid #334155;
|
border: 1px solid #334155;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
|
|||||||
Reference in New Issue
Block a user