~xj9/bbnet

7a860050c02ea44b21c5b16bc76827073d65b999 — xj9 16 days ago 23bfb94
finish theme support
D bbweb.config => bbweb.config +0 -20
@@ 1,20 0,0 @@
# bbweb config
[bbnet.peer]
domain=sunshinegardens.org

[bbnet.peer]
domain=gemini.circumlunar.space

# wiki config
[wiki]
name=walkaway handbook
foreward=gemini://sunshinegardens.org/~xj9/wiki/walkaway-handbook.gmi

# redirects
[redirect]
route=/wiki/<page>/index.html
target=/~clubhouse/{page}.gmi

[redirect]
route=/wiki/<page>/
target=/~clubhouse/{page}.gmi

A bbweb.ndtl => bbweb.ndtl +15 -0
@@ 0,0 1,15 @@
bbnet.peers
  sunshinegardens.org
  gemini.circumlunar.space

bbnet.wiki
  name : walkaway handbook
  foreward : gemini://sunshinegardens.org/~xj9/wiki/walkaway-handbook.gmi

bbweb.redirects
  redirect
    /wiki/<page>/index.html
    /~clubhouse/{page}.gmi
  redirect
    /wiki/<page>/
    /~clubhouse/{page}.gmi

M bbweb.py => bbweb.py +39 -17
@@ 11,6 11,8 @@ import time

from configparser import ConfigParser

import formats.indental

from av98 import GeminiClient
from markupsafe import escape
from flask import (


@@ 27,6 29,7 @@ from flask import (
app = Flask(__name__)

__version__ = '0.1.0-alpha.3'
BBWEB_HOME = 'gemini://sunshinegardens.org'
BBWEB_DOMAIN = 'sunshinegardens.org'
app.secret_key = os.environ.get('BBWEB_SECRET_KEY', 'CHANGE ME').encode()



@@ 34,6 37,13 @@ config_path = os.environ.get('BBWEB_CONFIG', 'bbweb.ini')
config = ConfigParser()
config.read(config_path)


def themes():
    for item in os.listdir('./static'):
        if 'base16-' in item:
            yield item.replace('base16-', '').replace('.css', '')


def escape_html(s):
    s = s.replace("<", "&lt;")
    s = s.replace(">", "&gt;")


@@ 139,6 149,8 @@ def stream_render(gmi_file, **kwargs):
    yield '<!doctype html>\n<html>\n'
    yield '<meta charset="utf-8">\n'
    yield '<meta name="viewport" content="width=device-width, initial-scale=1">\n'
    ## a thought
    yield '<!-- we must always have old memories and young hopes... -->'
    ln = 0
    for line in gmi_to_html(gmi_file): 
        if ln == 0 and 'h1' in line:


@@ 161,11 173,12 @@ def stream_render(gmi_file, **kwargs):
            yield '}\n'
            yield '</style>\n'
            yield render_stylesheet(path='minireset.min.css', cache=True)
            yield render_stylesheet(path='base16-woodland.css', cache=True)
            yield render_stylesheet(path='spirit.css')
            yield render_stylesheet(path='nav.css')
            # ui
            yield '<header>\n  <form method="GET" action="/navigate-to">\n  '
            yield '<header>\n  <form method="GET" action="/_bbweb/navigate-to">\n  '
            ## BBWEB_DOMAIN should be a select dropdown populated with domains
            ## from bbweb.peers
            yield '  <p>gemini://{0}/</p>\n  '.format(BBWEB_DOMAIN)
            yield '  <input type="text" name="path" value="{value}">\n'.format(
                value=url.replace(BBWEB_DOMAIN, '').replace('gemini://', '')[1:]


@@ 177,12 190,19 @@ def stream_render(gmi_file, **kwargs):
    yield '</main>\n'
    # footer
    yield '<footer>\n'
    ## a thought
    yield '<div>\n'
    yield '  <small>'
    yield 'we must always have old memories and young hopes...'
    yield '</small>\n'
    yield '</div>\n'
    ## theme picker
    yield '<form method="POST" action="/_bbweb/theme">'
    yield '  <label for="theme">theme</label>\n'
    yield '  <select name="theme">\n'
    for item in themes():
            yield '  '
            if theme in item:
                yield '<option label="{0}" value="{0}" selected>\n'.format(item)
            else:
                yield '<option label="{0}" value="{0}">\n'.format(item)
    yield '  </select>\n'
    yield '<button type="submit">set</button>'
    yield '</form>'
    ## version
    yield '<div class="version">\n'
    yield '  <a href="{link}" target="_blank">bbweb</a>'.format(


@@ 191,14 211,6 @@ def stream_render(gmi_file, **kwargs):
    yield '<span>/{version}</span>\n'.format(version=__version__)
    yield '</div>\n'
    yield '</footer>\n'
    # theme picker
    #yield '<footer>\n'
    #yield '<select>\n'
    #for item in os.listdir('./static'):
    #    if 'base16-' in item:
    #        yield '  <option label="{0}" value="{0}">\n'.format(item)
    #yield '</select>\n'
    #yield '</footer>\n'
    yield '</html>'




@@ 241,6 253,8 @@ def hello_world(url=''):
    make sure clients can't browse the fs
    make sure the path makes sense (ends in / unless it has an extension). if
    there is a fix, send a redirect.

    allow fetching arbitrary pages listen in "bbweb.peers"
    """
    if url and not re_valid_path.match(url):
        return redirect('/{path}/'.format(path=escape(url)))


@@ 264,7 278,7 @@ def hello_world(url=''):
            abort(500)


@app.route('/navigate-to')
@app.route('/_bbweb/navigate-to')
def navigate_to():
    """
    make sure these are sanitized


@@ 272,6 286,14 @@ def navigate_to():
    return redirect('/{0}'.format(request.args.get('path', '')))


@app.route('/_bbweb/theme', methods=['POST'])
def set_theme():
    theme = escape(request.form.get('theme', 'woodland'))
    if theme in list(themes()):
        session['theme'] = theme
    return redirect(request.referrer)


@app.route('/favicon.ico')
def favicon():
    abort(400)

A static/base16-bespin.css => static/base16-bespin.css +20 -0
@@ 0,0 1,20 @@
/* Bespin by Jan T. Sott */

:root {
  --base00: #28211c;
  --base01: #36312e;
  --base02: #5e5d5c;
  --base03: #666666;
  --base04: #797977;
  --base05: #8a8986;
  --base06: #9d9b97;
  --base07: #baae9e;
  --base08: #cf6a4c;
  --base09: #cf7d34;
  --base0A: #f9ee98;
  --base0B: #54be0d;
  --base0C: #afc4db;
  --base0D: #5ea6ea;
  --base0E: #9b859d;
  --base0F: #937121;
}

A static/base16-cupcake.css => static/base16-cupcake.css +20 -0
@@ 0,0 1,20 @@
/* Cupcake by Chris Kempson (http://chriskempson.com) */

:root {
  --base00: #fbf1f2;
  --base01: #f2f1f4;
  --base02: #d8d5dd;
  --base03: #bfb9c6;
  --base04: #a59daf;
  --base05: #8b8198;
  --base06: #72677E;
  --base07: #585062;
  --base08: #D57E85;
  --base09: #EBB790;
  --base0A: #DCB16C;
  --base0B: #A3B367;
  --base0C: #69A9A7;
  --base0D: #7297B9;
  --base0E: #BB99B4;
  --base0F: #BAA58C;
}

A static/base16-flat.css => static/base16-flat.css +20 -0
@@ 0,0 1,20 @@
/* Flat by Chris Kempson (http://chriskempson.com) */

:root {
  --base00: #2C3E50;
  --base01: #34495E;
  --base02: #7F8C8D;
  --base03: #95A5A6;
  --base04: #BDC3C7;
  --base05: #e0e0e0;
  --base06: #f5f5f5;
  --base07: #ECF0F1;
  --base08: #E74C3C;
  --base09: #E67E22;
  --base0A: #F1C40F;
  --base0B: #2ECC71;
  --base0C: #1ABC9C;
  --base0D: #3498DB;
  --base0E: #9B59B6;
  --base0F: #be643c;
}

A static/base16-grayscale-dark.css => static/base16-grayscale-dark.css +20 -0
@@ 0,0 1,20 @@
/* Grayscale Dark by Alexandre Gavioli (https://github.com/Alexx2/) */

:root {
  --base00: #101010;
  --base01: #252525;
  --base02: #464646;
  --base03: #525252;
  --base04: #ababab;
  --base05: #b9b9b9;
  --base06: #e3e3e3;
  --base07: #f7f7f7;
  --base08: #7c7c7c;
  --base09: #999999;
  --base0A: #a0a0a0;
  --base0B: #8e8e8e;
  --base0C: #868686;
  --base0D: #686868;
  --base0E: #747474;
  --base0F: #5e5e5e;
}

A static/base16-gruvbox-dark-hard.css => static/base16-gruvbox-dark-hard.css +20 -0
@@ 0,0 1,20 @@
/* Gruvbox dark, hard by Dawid Kurek (dawikur@gmail.com), morhetz (https://github.com/morhetz/gruvbox) */

:root {
  --base00: #1d2021;
  --base01: #3c3836;
  --base02: #504945;
  --base03: #665c54;
  --base04: #bdae93;
  --base05: #d5c4a1;
  --base06: #ebdbb2;
  --base07: #fbf1c7;
  --base08: #fb4934;
  --base09: #fe8019;
  --base0A: #fabd2f;
  --base0B: #b8bb26;
  --base0C: #8ec07c;
  --base0D: #83a598;
  --base0E: #d3869b;
  --base0F: #d65d0e;
}

A static/base16-macintosh.css => static/base16-macintosh.css +20 -0
@@ 0,0 1,20 @@
/* Macintosh by Rebecca Bettencourt (http://www.kreativekorp.com) */

:root {
  --base00: #000000;
  --base01: #404040;
  --base02: #404040;
  --base03: #808080;
  --base04: #808080;
  --base05: #c0c0c0;
  --base06: #c0c0c0;
  --base07: #ffffff;
  --base08: #dd0907;
  --base09: #ff6403;
  --base0A: #fbf305;
  --base0B: #1fb714;
  --base0C: #02abea;
  --base0D: #0000d3;
  --base0E: #4700a5;
  --base0F: #90713a;
}

A static/base16-spacemacs.css => static/base16-spacemacs.css +20 -0
@@ 0,0 1,20 @@
/* Spacemacs by Nasser Alshammari (https://github.com/nashamri/spacemacs-theme) */

:root {
  --base00: #1f2022;
  --base01: #282828;
  --base02: #444155;
  --base03: #585858;
  --base04: #b8b8b8;
  --base05: #a3a3a3;
  --base06: #e8e8e8;
  --base07: #f8f8f8;
  --base08: #f2241f;
  --base09: #ffa500;
  --base0A: #b1951d;
  --base0B: #67b11d;
  --base0C: #2d9574;
  --base0D: #4f97d7;
  --base0E: #a31db1;
  --base0F: #b03060;
}

A static/base16-summerfruit-dark.css => static/base16-summerfruit-dark.css +20 -0
@@ 0,0 1,20 @@
/* Summerfruit Dark by Christopher Corley (http://christop.club/) */

:root {
  --base00: #151515;
  --base01: #202020;
  --base02: #303030;
  --base03: #505050;
  --base04: #B0B0B0;
  --base05: #D0D0D0;
  --base06: #E0E0E0;
  --base07: #FFFFFF;
  --base08: #FF0086;
  --base09: #FD8900;
  --base0A: #ABA800;
  --base0B: #00C918;
  --base0C: #1FAAAA;
  --base0D: #3777E6;
  --base0E: #AD00A1;
  --base0F: #CC6633;
}