refactor!: unify slash handling
It is hard to remember to add `/` at the end of the URL when configuring a new etherpad URL. Also, web server proxies tend to do weird stuff when you assume that you have a slash on the end of each URL. So, I took a look at how to avoid doing that. It turns out that both urljoin / os.path.join are kinda bad for handling URL building. Also, APPLICATION_ROOT didn't seem that necessary since Flask knows what to do with a `/` at the start of a URL, so I dropped it. I think this doesn't break anything!
This commit is contained in:
parent
8b4d0905e2
commit
42e408859b
57
octomode.py
57
octomode.py
@ -1,6 +1,6 @@
|
|||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
from flask import Flask, request, render_template, redirect, url_for
|
from flask import Flask, request, render_template, redirect
|
||||||
from urllib.request import urlopen
|
from urllib.request import urlopen
|
||||||
from urllib.parse import urlencode
|
from urllib.parse import urlencode
|
||||||
|
|
||||||
@ -15,10 +15,9 @@ import pypandoc
|
|||||||
import markdown
|
import markdown
|
||||||
|
|
||||||
class Config(object):
|
class Config(object):
|
||||||
APPLICATION_ROOT = '/'
|
|
||||||
PORTNUMBER = int(os.environ.get('OCTOMODE_PORTNUMBER', 5001))
|
PORTNUMBER = int(os.environ.get('OCTOMODE_PORTNUMBER', 5001))
|
||||||
PAD_URL = os.environ.get('OCTOMODE_PAD_URL', 'https://pad.vvvvvvaria.org/' )
|
PAD_URL = os.environ.get('OCTOMODE_PAD_URL', 'https://pad.vvvvvvaria.org' )
|
||||||
PAD_API_URL = os.environ.get('OCTOMODE_PAD_API_URL', 'https://pad.vvvvvvaria.org/api/1.2.15/')
|
PAD_API_URL = os.environ.get('OCTOMODE_PAD_API_URL', 'https://pad.vvvvvvaria.org/api/1.2.15')
|
||||||
PAD_API_KEY = os.environ.get('OCTOMODE_PAD_API_KEY', '')
|
PAD_API_KEY = os.environ.get('OCTOMODE_PAD_API_KEY', '')
|
||||||
|
|
||||||
APP = Flask(__name__)
|
APP = Flask(__name__)
|
||||||
@ -42,14 +41,14 @@ def get_pad_content(pad_name, ext=""):
|
|||||||
'apikey' : APP.config['PAD_API_KEY']
|
'apikey' : APP.config['PAD_API_KEY']
|
||||||
}
|
}
|
||||||
api_call = 'getText'
|
api_call = 'getText'
|
||||||
response = json.load(urlopen(f"{ APP.config['PAD_API_URL'] }{ api_call }", data=urlencode(arguments).encode()))
|
response = json.load(urlopen(f"{ APP.config['PAD_API_URL'] }/{ api_call }", data=urlencode(arguments).encode()))
|
||||||
|
|
||||||
# create pad in case it does not yet exist
|
# create pad in case it does not yet exist
|
||||||
if response['code'] == 1 and 'padID does not exist' == response['message']:
|
if response['code'] == 1 and 'padID does not exist' == response['message']:
|
||||||
api_call = 'createPad'
|
api_call = 'createPad'
|
||||||
urlopen(f"{ APP.config['PAD_API_URL'] }{ api_call }", data=urlencode(arguments).encode())
|
urlopen(f"{ APP.config['PAD_API_URL'] }/{ api_call }", data=urlencode(arguments).encode())
|
||||||
api_call = 'getText'
|
api_call = 'getText'
|
||||||
response = json.load(urlopen(f"{ APP.config['PAD_API_URL'] }{ api_call }", data=urlencode(arguments).encode()))
|
response = json.load(urlopen(f"{ APP.config['PAD_API_URL'] }/{ api_call }", data=urlencode(arguments).encode()))
|
||||||
|
|
||||||
content = response['data']['text']
|
content = response['data']['text']
|
||||||
return content
|
return content
|
||||||
@ -59,7 +58,7 @@ def all_pads():
|
|||||||
'apikey' : APP.config['PAD_API_KEY'],
|
'apikey' : APP.config['PAD_API_KEY'],
|
||||||
}
|
}
|
||||||
api_call = 'listAllPads'
|
api_call = 'listAllPads'
|
||||||
response = json.load(urlopen(f"{ APP.config['PAD_API_URL'] }{ api_call }", data=urlencode(arguments).encode()))
|
response = json.load(urlopen(f"{ APP.config['PAD_API_URL'] }/{ api_call }", data=urlencode(arguments).encode()))
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
@ -83,7 +82,7 @@ def create_pad_on_first_run(name, ext):
|
|||||||
'text' : default_template
|
'text' : default_template
|
||||||
}
|
}
|
||||||
api_call = 'createPad'
|
api_call = 'createPad'
|
||||||
json.load(urlopen(f"{ APP.config['PAD_API_URL'] }{ api_call }", data=urlencode(arguments).encode()))
|
json.load(urlopen(f"{ APP.config['PAD_API_URL'] }/{ api_call }", data=urlencode(arguments).encode()))
|
||||||
|
|
||||||
def md_to_html(md_pad_content):
|
def md_to_html(md_pad_content):
|
||||||
# Convert Markdown to HTML
|
# Convert Markdown to HTML
|
||||||
@ -120,35 +119,33 @@ def index():
|
|||||||
exts = ['.md', '.css']
|
exts = ['.md', '.css']
|
||||||
for ext in exts:
|
for ext in exts:
|
||||||
create_pad_on_first_run(name, ext)
|
create_pad_on_first_run(name, ext)
|
||||||
return redirect(f'{ APP.config["APPLICATION_ROOT"] }{ name }/pad/')
|
return redirect(f"/{ name }/pad")
|
||||||
else:
|
else:
|
||||||
return render_template('start.html', application_root=APP.config["APPLICATION_ROOT"])
|
return render_template('start.html')
|
||||||
|
|
||||||
@APP.route('/<name>/')
|
@APP.route('/<name>')
|
||||||
def main(name):
|
def main(name):
|
||||||
return redirect(f'{ APP.config["APPLICATION_ROOT"] }{ name }/pad/')
|
return redirect(f"/{ name }/pad")
|
||||||
|
|
||||||
@APP.route('/<name>/pad/')
|
@APP.route('/<name>/pad')
|
||||||
def pad(name):
|
def pad(name):
|
||||||
pad_name = f'{ name }.md'
|
url = f"{ APP.config['PAD_URL'] }/{ name }.md"
|
||||||
url = os.path.join(APP.config['PAD_URL'], pad_name)
|
return render_template('iframe.html', url=url, name=name.strip())
|
||||||
return render_template('iframe.html', url=url, name=name.strip(), application_root=APP.config["APPLICATION_ROOT"])
|
|
||||||
|
|
||||||
@APP.route('/<name>/stylesheet/')
|
@APP.route('/<name>/stylesheet')
|
||||||
def stylesheet(name):
|
def stylesheet(name):
|
||||||
pad_name = f'{ name }.css'
|
url = f"{ APP.config['PAD_URL'] }/{ name }.css"
|
||||||
url = os.path.join(APP.config['PAD_URL'], pad_name)
|
return render_template('iframe.html', url=url, name=name.strip())
|
||||||
return render_template('iframe.html', url=url, name=name.strip(), application_root=APP.config["APPLICATION_ROOT"])
|
|
||||||
|
|
||||||
@APP.route('/<name>/html/')
|
@APP.route('/<name>/html')
|
||||||
def html(name):
|
def html(name):
|
||||||
url = os.path.join(APP.config["APPLICATION_ROOT"], name, 'preview.html')
|
url = f"/{ name }/preview.html"
|
||||||
return render_template('iframe.html', url=url, name=name.strip(), application_root=APP.config["APPLICATION_ROOT"])
|
return render_template('iframe.html', url=url, name=name.strip())
|
||||||
|
|
||||||
@APP.route('/<name>/pdf/')
|
@APP.route('/<name>/pdf')
|
||||||
def pdf(name):
|
def pdf(name):
|
||||||
url = os.path.join(APP.config["APPLICATION_ROOT"], name, 'pagedjs.html')
|
url = f"/{name}/pagedjs.html"
|
||||||
return render_template('pdf.html', url=url, name=name.strip(), application_root=APP.config["APPLICATION_ROOT"])
|
return render_template('pdf.html', url=url, name=name.strip())
|
||||||
|
|
||||||
# //////////////////
|
# //////////////////
|
||||||
# RENDERED RESOURCES
|
# RENDERED RESOURCES
|
||||||
@ -175,7 +172,7 @@ def preview(name):
|
|||||||
lang = "en"
|
lang = "en"
|
||||||
title = "No title"
|
title = "No title"
|
||||||
|
|
||||||
return render_template('preview.html', name=name.strip(), pad_content=html, lang=lang, title=title, application_root=APP.config["APPLICATION_ROOT"])
|
return render_template('preview.html', name=name.strip(), pad_content=html, lang=lang, title=title)
|
||||||
|
|
||||||
@APP.route('/<name>/pagedjs.html')
|
@APP.route('/<name>/pagedjs.html')
|
||||||
def pagedjs(name):
|
def pagedjs(name):
|
||||||
@ -186,10 +183,10 @@ def pagedjs(name):
|
|||||||
lang = metadata['language'][0]
|
lang = metadata['language'][0]
|
||||||
title = metadata['title'][0]
|
title = metadata['title'][0]
|
||||||
|
|
||||||
return render_template('pagedjs.html', name=name.strip(), pad_content=html, lang=lang, title=title, application_root=APP.config["APPLICATION_ROOT"])
|
return render_template('pagedjs.html', name=name.strip(), pad_content=html, lang=lang, title=title)
|
||||||
|
|
||||||
# //////////////////
|
# //////////////////
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
APP.debug=True
|
APP.debug=True
|
||||||
APP.run(host="0.0.0.0", port=f'{ APP.config["PORTNUMBER"] }', threaded=True)
|
APP.run(host="0.0.0.0", port=APP.config["PORTNUMBER"], threaded=True)
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<title>{{ name }} in octomode</title>
|
<title>{{ name }} in octomode</title>
|
||||||
<link rel="stylesheet" type="text/css" href="{{ application_root }}static/main.css">
|
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='main.css') }}">
|
||||||
{% block head %}
|
{% block head %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
</head>
|
</head>
|
||||||
@ -18,17 +18,21 @@ window.addEventListener('load', function () {
|
|||||||
|
|
||||||
// Insert the nav buttons, after the page is loaded
|
// Insert the nav buttons, after the page is loaded
|
||||||
const nav = document.createElement('div');
|
const nav = document.createElement('div');
|
||||||
nav.id = 'nav';
|
nav.id = 'nav';
|
||||||
const name = '{{ name }}';
|
|
||||||
const application_root = '{{ application_root }}';
|
|
||||||
|
|
||||||
nav.innerHTML = `
|
nav.innerHTML = `
|
||||||
<h1>${ name } <a href="${ application_root }"><em class="octomode">in octomode</em></a></h1>
|
<h1>{{ name }} <a href="/"><em class="octomode">in octomode</em></a></h1>
|
||||||
<div id="buttons">
|
<div id="buttons">
|
||||||
<a href="${ application_root }${ name }/pad/"><button>pad</button></a>: <input type="text" name="pad" value="https://pad.vvvvvvaria.org/${ name }.md">
|
|
||||||
<a href="${ application_root }${ name }/stylesheet/"><button>stylesheet</button></a>: <input type="text" name="pad" value="https://pad.vvvvvvaria.org/${ name }.css">
|
<a href="/{{ name }}/pad"><button>pad</button></a>:
|
||||||
<a href="${ application_root }${ name }/html/"><button>html</button></a>
|
<input type="text" name="pad" value="https://pad.vvvvvvaria.org/{{ name }}.md">
|
||||||
<a href="${ application_root }${ name }/pdf/"><button>pdf</button></a>
|
|
||||||
|
<a href="/{{ name }}/stylesheet"><button>stylesheet</button></a>:
|
||||||
|
<input type="text" name="pad" value="https://pad.vvvvvvaria.org/{{ name }}.css">
|
||||||
|
|
||||||
|
<a href="/{{ name }}/html"><button>html</button></a>
|
||||||
|
|
||||||
|
<a href="/{{ name }}/pdf"><button>pdf</button></a>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
|
||||||
document.body.insertBefore(nav, document.body.firstChild);
|
document.body.insertBefore(nav, document.body.firstChild);
|
||||||
|
@ -3,9 +3,9 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<script src="{{ application_root }}static/paged.polyfill.js" type="text/javascript"></script>
|
<script src="{{ url_for('static', filename='paged.polyfill.js') }}" type="text/javascript"></script>
|
||||||
<link href="{{ application_root }}static/pagedjs.css" rel="stylesheet" type="text/css" media="screen">
|
<link href="{{ url_for('static', filename='pagedjs.css') }}" rel="stylesheet" type="text/css" media="screen">
|
||||||
<link href="{{ application_root }}{{ name }}/stylesheet.css" rel="stylesheet" type="text/css" media="print">
|
<link href="/{{ name }}/stylesheet.css" rel="stylesheet" type="text/css" media="print">
|
||||||
<title>{{ title }}</title>
|
<title>{{ title }}</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<iframe id="pdf" name="pdf" src="{{ url }}"></iframe>
|
<iframe id="pdf" name="pdf" src="{{ url }}"></iframe>
|
||||||
@ -16,7 +16,7 @@ window.addEventListener('load', function () {
|
|||||||
// Load the main.css again, to load the stylesheet for the nav
|
// Load the main.css again, to load the stylesheet for the nav
|
||||||
var cssLink = document.createElement('link');
|
var cssLink = document.createElement('link');
|
||||||
cssLink.rel = 'stylesheet';
|
cssLink.rel = 'stylesheet';
|
||||||
cssLink.href = '{{ application_root }}/static/main.css';
|
cssLink.href = '{{ url_for("static", filename="main.css") }}';
|
||||||
var head = document.getElementsByTagName('head')[0];
|
var head = document.getElementsByTagName('head')[0];
|
||||||
head.insertBefore(cssLink, head.firstChild);
|
head.insertBefore(cssLink, head.firstChild);
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<link href="{{ application_root }}/{{ name }}/stylesheet.css" rel="stylesheet" type="text/css" media="screen">
|
<link href="{{ name }}/stylesheet.css" rel="stylesheet" type="text/css" media="screen">
|
||||||
<title>{{ title }}</title>
|
<title>{{ title }}</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
@ -3,10 +3,10 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<title>octomode</title>
|
<title>octomode</title>
|
||||||
<link rel="stylesheet" type="text/css" href="{{ application_root }}static/main.css">
|
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='main.css') }}">
|
||||||
</head>
|
</head>
|
||||||
<body class="start-page">
|
<body class="start-page">
|
||||||
<form action="{{ application_root }}" method="POST">
|
<form action="/" method="POST">
|
||||||
<h1><input type="submit" value="open"> <input type="text" name="name"> <em class="octomode">in octomode</em></h1>
|
<h1><input type="submit" value="open"> <input type="text" name="name"> <em class="octomode">in octomode</em></h1>
|
||||||
</form>
|
</form>
|
||||||
</body>
|
</body>
|
||||||
|
Loading…
Reference in New Issue
Block a user