~xj9/bbnet

28585982d97f726825501b672038ba792b0a0860 — xj9 13 days ago 7a86005
use ndtl config, fix parser bug
4 files changed, 66 insertions(+), 54 deletions(-)

R bbweb.ndtl => bbnet.ndtl
M bbweb.py
M formats/indental.py
A static/favicon.ico
R bbweb.ndtl => bbnet.ndtl +5 -2
@@ 1,15 1,18 @@
bbnet.peers
  sunshinegardens.org
    self
    enabled
  gemini.circumlunar.space
    enabled

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

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

M bbweb.py => bbweb.py +60 -51
@@ 9,8 9,6 @@ import os.path
import re
import time

from configparser import ConfigParser

import formats.indental

from av98 import GeminiClient


@@ 33,10 31,9 @@ BBWEB_HOME = 'gemini://sunshinegardens.org'
BBWEB_DOMAIN = 'sunshinegardens.org'
app.secret_key = os.environ.get('BBWEB_SECRET_KEY', 'CHANGE ME').encode()

config_path = os.environ.get('BBWEB_CONFIG', 'bbweb.ini')
config = ConfigParser()
config.read(config_path)

av98_config_path = os.environ.get('AV98_CONFIG_PATH', None)
config_path = os.environ.get('BBWEB_CONFIG', 'bbnet.ndtl')
config = formats.indental.parse_file(config_path)

def themes():
    for item in os.listdir('./static'):


@@ 45,25 42,27 @@ def themes():


def escape_html(s):
    s = s.replace("<", "&lt;")
    s = s.replace(">", "&gt;")
    # s = s.replace("<", "&lt;")
    # s = s.replace(">", "&gt;")
    # this has to be last
    # s = s.replace("&amp;", "&")
    return escape(s)


# regexes
re_header = re.compile(r'^(#+)\s+?(.+)$')
re_link = re.compile(r'^=>\s?(.+?)\s(.+)?$')
re_list_item = re.compile(r'^\*\s?(.+)?$')
re_pre = re.compile(r'^```')
re_quote = re.compile(r'^>(.+)?$')
re_hr = re.compile(r'^-{3,}$')
re_image = re.compile(r'^.+\.(?:jpe?g|gif|png|bmp|svg)$')
re_emoji = re.compile(r'\s:([a-z0-9_]):\s?')

def gmi_to_html(lines):
    """
    line-wise gmi to html conversion with toggles
    """
    # regexes
    re_header = re.compile(r'^(#+)\s+?(.+)$')
    re_link = re.compile(r'^=>\s?(.+?)\s(.+)?$')
    re_list_item = re.compile(r'^\*\s?(.+)?$')
    re_pre = re.compile(r'^```')
    re_quote = re.compile(r'^>(.+)?$')
    re_hr = re.compile(r'^-{3,}$')
    re_image = re.compile(r'^.+\.(?:jpe?g|gif|png|bmp)$')
    # toggles
    pre_toggle = False
    list_toggle = False


@@ 144,21 143,25 @@ def render_stylesheet(**kwargs):


def stream_render(gmi_file, **kwargs):
    site_name = config.get('bbnet.wiki', {}).get('name', 'bbnet')
    url = kwargs['url']
    theme = kwargs['theme']
    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... -->'
    yield '''
    <!doctype html>
    <html>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 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:
            yield '<title>bbnet - {title}</title>\n'.format(
            yield '<title>{site_name} - {title}</title>\n'.format(
                site_name=site_name,
                title=line.strip().replace('<h1>', '').replace('</h1>', '')
            )
        elif ln == 0:
            yield '<title>bbnet</title>\n'
            yield '<title>{site_name}</title>\n'.format(site_name=site_name)
        if ln == 0:
            # head
            theme_path = './static/base16-{theme}.css'.format(theme=theme)


@@ 167,11 170,13 @@ def stream_render(gmi_file, **kwargs):
            with open(theme_path) as fd:
                for style in fd:
                    yield style
            yield 'body {\n'
            yield '  background-color: var(--base00);\n'
            yield '  color: var(--base03);\n'
            yield '}\n'
            yield '</style>\n'
            yield """
            body {
                background-color: var(--base00);
                color: var(--base03);
            }
            </style>
            """
            yield render_stylesheet(path='minireset.min.css', cache=True)
            yield render_stylesheet(path='spirit.css')
            yield render_stylesheet(path='nav.css')


@@ 191,17 196,18 @@ def stream_render(gmi_file, **kwargs):
    # footer
    yield '<footer>\n'
    ## theme picker
    yield '<form method="POST" action="/_bbweb/theme">'
    yield '  <label for="theme">theme</label>\n'
    yield '  <select name="theme">\n'
    yield """
    <form method="POST" action="/_bbweb/theme">
      <label for="theme">theme</label>
      <select name="theme">
    """
    for item in themes():
            yield '  '
            if theme in item:
                yield '<option label="{0}" value="{0}" selected>\n'.format(item)
                yield '  <option label="{0}" value="{0}" selected>\n'.format(item)
            else:
                yield '<option label="{0}" value="{0}">\n'.format(item)
                yield '  <option label="{0}" value="{0}">\n'.format(item)
    yield '  </select>\n'
    yield '<button type="submit">set</button>'
    yield '<button type="submit">set</button>\n'
    yield '</form>'
    ## version
    yield '<div class="version">\n'


@@ 265,7 271,10 @@ def hello_world(url=''):
        )
        if session.get('theme') is None:
            session['theme'] = 'woodland'
        gc = GeminiClient(restricted=True)
        gc = GeminiClient(
            restricted=True,
            config_path=av98_config_path
        )
        try:
            gc.do_go(request_url)
            return stream_response(


@@ 274,8 283,7 @@ def hello_world(url=''):
                theme=escape(session['theme'])
            )
        except Exception as e:
            print(e)
            abort(500)
            abort(e.code)


@app.route('/_bbweb/navigate-to')


@@ 296,7 304,7 @@ def set_theme():

@app.route('/favicon.ico')
def favicon():
    abort(400)
    return send_file('./static/favicon.ico', mimetype='image/x-icon')


def redirect_to(section, target):


@@ 307,16 315,17 @@ def redirect_to(section, target):
    return handler


for section in config.sections():
    try:
        route = config[section]['route'].strip()
        target = config[section]['target'].strip()
        print(section, route, '->', target)
        app.add_url_rule(
            route,
            section,
            redirect_to(section, target)
        )
    except:
        pass
if config.get('bbweb.redirects'):
    for section, rule in config['bbweb.redirects'].items():
        try:
            route = rule[0].strip()
            target = rule[1].strip()
            print(section, route, '->', target)
            app.add_url_rule(
                route,
                section,
                redirect_to(section, target)
            )
        except:
            pass


M formats/indental.py => formats/indental.py +1 -1
@@ 35,7 35,7 @@ def _parse(ndtl_io):
            key, value = line.strip().split(" : ")
            result[current_name][key.strip()] = value.strip()
        elif list_item.match(line) and current_name:
            if in_list is None:
            if len(line[0:3].strip()):
                in_list = line.strip()
                result[current_name][in_list] = []
            else:

A static/favicon.ico => static/favicon.ico +0 -0