From ed711a25219e9f08c1c2cb92c2f08a280c4b8203 Mon Sep 17 00:00:00 2001 From: Anthony Donlon Date: Tue, 16 Dec 2025 21:39:48 +0800 Subject: [PATCH] editor: support shortened share URLs --- editor/server/__init__.py | 2 ++ editor/server/config.example.toml | 6 ++++++ editor/server/share.py | 19 ++++++++++++++++--- editor/web/vite.config.ts | 2 +- 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/editor/server/__init__.py b/editor/server/__init__.py index 798a33e..f5365e0 100644 --- a/editor/server/__init__.py +++ b/editor/server/__init__.py @@ -92,9 +92,11 @@ def create_app(test_config=None) -> Flask: return '', 204 url_prefix = app.config.get('URL_PREFIX', '') + short_share_url = app.config.get('SHORT_SHARE_URL', False) app.register_blueprint(editor.bp, url_prefix=f'{url_prefix}/editor') app.register_blueprint(examples.bp, url_prefix=f'{url_prefix}/examples') app.register_blueprint(share.bp, url_prefix=f'{url_prefix}/s') + app.register_blueprint(share.bp_short, url_prefix=f'{url_prefix}' + ('' if short_share_url else '/s')) return app diff --git a/editor/server/config.example.toml b/editor/server/config.example.toml index f1dbad0..b9cc60c 100644 --- a/editor/server/config.example.toml +++ b/editor/server/config.example.toml @@ -1,6 +1,12 @@ # Url prefix for app urls URL_PREFIX = '' +# Digits of item name in shared links +SHARE_LINK_DIGITS = 7 + +# Use short share url (without '/s' path) +SHORT_SHARE_URL = false + # Set to true if trust X-Forwarded-For/X-Forwarded-Proto header BEHIND_PROXY = true diff --git a/editor/server/share.py b/editor/server/share.py index cda7465..02ccc5d 100644 --- a/editor/server/share.py +++ b/editor/server/share.py @@ -6,9 +6,11 @@ import string from flask import ( Blueprint, + current_app, request, abort, jsonify, + redirect, url_for, ) from jinja2 import Environment, select_autoescape @@ -51,6 +53,7 @@ template = env.from_string(''' ''') bp = Blueprint('share', __name__, url_prefix='/') +bp_short = Blueprint('share_short', __name__, url_prefix='/') rand_charset = string.ascii_lowercase + string.digits @@ -81,7 +84,8 @@ def create(): # TODO: strip unused params try: item = models.Item() - item.name = get_rand_name() + digits = current_app.config.get('SHARE_LINK_DIGITS', 7) + item.name = get_rand_name(digits) item.params = params db.session.add(item) db.session.commit() @@ -93,12 +97,12 @@ def create(): return jsonify({ 'status': 'ok', 'name': item.name, - 'url': request.host_url[:-1] + url_for('share.get', name=item.name), + 'url': request.host_url[:-1] + url_for('share_short.get', name=item.name), # TODO: better way to handle this }) -@bp.get('/') +@bp_short.get('/') def get(name: str): accept = request.headers.get('Accept', '') is_json = 'application/json' in accept @@ -136,3 +140,12 @@ def get(name: str): base=cf_template, url=request.url, description='Cloudflare error page') + + +@bp.get('/') +def get_redir(name: str): + short_share_url = current_app.config.get('SHORT_SHARE_URL', False) + if short_share_url: + return redirect(f'../{name}', code=308) + else: + return get(name=name) diff --git a/editor/web/vite.config.ts b/editor/web/vite.config.ts index 8d9f53c..87161f2 100644 --- a/editor/web/vite.config.ts +++ b/editor/web/vite.config.ts @@ -17,7 +17,7 @@ export default defineConfig(({ mode }) => { server: { port: 3000, proxy: { - '/s': { + '/s/': { target: 'http://localhost:5000', }, },