from db import get_db, return_db, get_setting, set_setting, get_site_name import templates as templates_mod from templates import esc, DEFAULT_TEMPLATE from ._helpers import _respond, _redirect, _json_response, _csrf_field, _get_bookmark_token, _request_local from .subscriptions import _count_shared_pages _flash = {} def _set_flash(msg): _flash[_request_local.csrf_token] = msg def _get_flash(): return _flash.pop(_request_local.csrf_token, "") def handle_style_form(msg="", gateway_host="", scheme="http"): template = get_setting("custom_template") or DEFAULT_TEMPLATE name = get_site_name() sharing = get_setting("sharing_enabled", "0") checked = " checked" if sharing == "1" else "" sharing_mode = get_setting("sharing_mode", "exclude_private") forum = get_setting("forum_enabled", "0") forum_checked = " checked" if forum == "1" else "" exclude_checked = " checked" if sharing_mode != "require_public" else "" require_checked = " checked" if sharing_mode == "require_public" else "" shared_count = _count_shared_pages() semantic = get_setting("semantic_search", "0") semantic_checked = " checked" if semantic == "1" else "" reranker = get_setting("use_reranker", "0") reranker_checked = " checked" if reranker == "1" else "" disabled = "" if semantic == "1" else " disabled" tcp_enabled = get_setting("tcp_enabled", "1") tcp_checked = " checked" if tcp_enabled == "1" else "" tcp_disabled = "" if tcp_enabled == "1" else " disabled" transport_host = get_setting("transport_host", "rnode.bre.land") transport_port = get_setting("transport_port", "4242") compress = get_setting("compress_embeddings", "0") compress_checked = " checked" if compress == "1" else "" lora_enabled = get_setting("lora_enabled", "0") lora_checked = " checked" if lora_enabled == "1" else "" lora_disabled = "" if lora_enabled == "1" else " disabled" lora_port = get_setting("lora_port", "") lora_frequency = get_setting("lora_frequency", "867200000") lora_bandwidth = get_setting("lora_bandwidth", "125000") lora_txpower = get_setting("lora_txpower", "7") lora_sf = get_setting("lora_sf", "8") lora_cr = get_setting("lora_cr", "5") csrf = _csrf_field() from handlers import forum_plugin as _fp if _fp is not None: forum_body = ( f"
" f'
' f"{csrf}" f'' f"

forum

" f'
" f"Share URLs and discuss them with other TinyWeb instances.

" f'' f"
" f"
" ) forum_nav = ' · forum' else: forum_body = "" forum_nav = "" msg = _get_flash() or msg msg_html = "" if msg: msg_html = '

{msg}

'.format(msg=esc(msg)) return _respond( f"

customize

" f"{msg_html}" f'' f"
" f"
" f'
' f"{csrf}" f'' f"

site name

" f'' f' ' f"
" f"
" f"
" f"
" f'
' f"{csrf}" f'' f"

sharing

" f'
" f'
' f"What to share:
" f'
' f'
' f"
" f'

' f'Currently sharing {shared_count} page(s). ' f'preview' f"

" f'' f"
" f"
" f"
" f"{forum_body}" f"
" f"
" f'
' f"{csrf}" f'' f"

search

" f'

" f'

" f'

" f'manage semantic index' f'
' f"
" f"
" f"
" f"
" f'
' f"{csrf}" f'' f"

mesh network

" f"

Choose how to connect to the mesh.

" f"

internet

" f'
" f"Default: rnode.bre.land:4242
" f'' f'
' f"

LoRa

" f'
" f'
' f"
advanced radio settings" f'
' f"ISM band frequency. Default: 867200000 (868 MHz EU). US: 915000000.

" f'
' f"Default: 125000

" f'
' f"0-17 typical. Check local regulations.

" f'
' f"5-12. Higher = longer range, slower speed.

" f'
' f"5-8. Higher = more error correction." f"
" f'
' f"
" f"
" f"
" f"
" f"

template

" f"

Edit the full page template.

" f'
' f"{csrf}" f'

' f'' f"
" f"
" f"
" f"
" f"

tools

" f"

bookmarklet

" f"

Drag this link to your bookmarks bar.

" f'

r.text()).then(t=>alert(t)).catch(()=>alert(\'tinyweb not running\')))">+ save to {esc(name)}

' f"

reset template

" f'
' f"{csrf}" f'' f"
" f"

vacuum database

" f'
' f"{csrf}" f'' f"
" f"
" f'back', use_default=True, ) def handle_style_submit(body, gateway_host="", scheme="http"): action = body.get("_action", [""])[0] if action == "name": name = body.get("site_name", ["tinyweb"])[0].strip() set_setting("site_name", name or "tinyweb") _set_flash("Saved.") return _redirect("/style") if action == "sharing": sharing = "1" if body.get("sharing_enabled") else "0" sharing_mode = body.get("sharing_mode", ["exclude_private"])[0] if sharing_mode not in ("exclude_private", "require_public"): sharing_mode = "exclude_private" set_setting("sharing_mode", sharing_mode) set_setting("sharing_enabled", sharing) _set_flash("Saved.") return _redirect("/style") if action == "forum": forum_enabled = "1" if body.get("forum_enabled") else "0" current_forum = get_setting("forum_enabled", "0") if forum_enabled != current_forum: from handlers import forum_plugin if forum_enabled == "1" and forum_plugin is None: _set_flash("Forum plugin not installed. Run: pip install tinyweb-forum") return _redirect("/style") if forum_enabled == "1": forum_plugin.enable() try: forum_plugin.fdb.set_setting("forum_enabled", "1") except Exception: pass else: forum_plugin.disable() try: forum_plugin.fdb.set_setting("forum_enabled", "0") except Exception: pass set_setting("forum_enabled", forum_enabled) templates_mod.FORUM_ENABLED = (forum_enabled == "1") _set_flash("Saved.") return _redirect("/style") if action == "search": semantic = "1" if body.get("semantic_search") else "0" reranker = "1" if body.get("use_reranker") else "0" compress = "1" if body.get("compress_embeddings") else "0" set_setting("semantic_search", semantic) set_setting("use_reranker", reranker) set_setting("compress_embeddings", compress) _set_flash("Saved.") return _redirect("/style") if action == "mesh": tcp_enabled = "1" if body.get("tcp_enabled") else "0" transport_host = body.get("transport_host", [""])[0].strip() transport_port = body.get("transport_port", [""])[0].strip() set_setting("tcp_enabled", tcp_enabled) if transport_host: set_setting("transport_host", transport_host) if transport_port: set_setting("transport_port", transport_port) lora_enabled = "1" if body.get("lora_enabled") else "0" set_setting("lora_enabled", lora_enabled) set_setting("lora_port", body.get("lora_port", [""])[0].strip()) set_setting("lora_frequency", body.get("lora_frequency", ["867200000"])[0].strip()) set_setting("lora_bandwidth", body.get("lora_bandwidth", ["125000"])[0].strip()) set_setting("lora_txpower", body.get("lora_txpower", ["7"])[0].strip()) set_setting("lora_sf", body.get("lora_sf", ["8"])[0].strip()) set_setting("lora_cr", body.get("lora_cr", ["5"])[0].strip()) _set_flash("Saved.") return _redirect("/style") def handle_style_template_submit(body, gateway_host="", scheme="http"): template = body.get("template", [""])[0].replace("\r\n", "\n").replace("\r", "\n") set_setting("custom_template", template if template.strip() != DEFAULT_TEMPLATE.strip() else "") _set_flash("Template saved.") return _redirect("/style") def handle_field_save(body): key = body.get("key", [""])[0].strip() value = body.get("value", [""])[0].strip() if not key: return _json_response({"status": "error", "message": "No key provided."}, 400) if key == "forum_enabled": from handlers import forum_plugin if value == "1" and forum_plugin is None: return _json_response({"status": "error", "message": "Forum plugin not installed."}, 400) if value == "1": forum_plugin.enable() try: forum_plugin.fdb.set_setting("forum_enabled", "1") except Exception: pass else: forum_plugin.disable() try: forum_plugin.fdb.set_setting("forum_enabled", "0") except Exception: pass templates_mod.FORUM_ENABLED = (value == "1") set_setting(key, value) return _json_response({"status": "ok", "message": ""}) def handle_about(): name = get_site_name() dest_hash = get_setting("dest_hash") sharing = get_setting("sharing_enabled", "0") == "1" db = get_db() try: page_count = db.execute("SELECT count(*) FROM pages").fetchone()[0] tag_count = db.execute("SELECT count(DISTINCT tag_id) FROM page_tags").fetchone()[0] sub_count = db.execute("SELECT count(*) FROM subscriptions").fetchone()[0] finally: return_db(db) sharing_html = ( '

This instance shares its index publicly. Subscribe to join the network.

' if sharing else '

This instance is private.

' ) hash_html = "" if dest_hash: hash_html = ( f'

subscribe

' f'

To subscribe to this instance, add this destination hash in your TinyWeb:

' f'
{esc(dest_hash)}
' ) return _respond( f'

{esc(name)}

' f'

A personal, decentralized search engine.

' f'

You save pages you find. They are stored locally and shared over a mesh network ' f'so other people can find them too.

' f'

Search results come from your index and the indexes of people you are connected to.

' f'' f'{sharing_html}' f'{hash_html}' f'

your data

' f'

Everything is stored locally under ~/.tinyweb/:

' f'' f'

Back up ~/.tinyweb/ periodically. ' f'Copying the whole directory to another device preserves your identity and index together. ' f'The export page gives you a JSON dump of pages only — ' f'it does not preserve your identity or subscription state, so it is a migration aid, ' f'not a substitute for a full backup.

' f'

search | browse | tags

' )