handle yaml errors
This commit is contained in:
parent
c661d09926
commit
01ae1d7e92
71
octomode.py
71
octomode.py
|
|
@ -25,6 +25,13 @@ APP.config.from_pyfile('settings.py')
|
|||
|
||||
# ---
|
||||
|
||||
# my attempt as showing helpful error messages.
|
||||
class MarkdownRenderError(RuntimeError):
|
||||
def __init__(self, kind, message, original):
|
||||
super().__init__(message)
|
||||
self.kind = kind
|
||||
self.original = original
|
||||
|
||||
def get_pad_content(pad_name, ext=""):
|
||||
if ext:
|
||||
pad_name = f'{ pad_name }{ ext }'
|
||||
|
|
@ -62,6 +69,22 @@ def all_pads():
|
|||
|
||||
return response
|
||||
|
||||
# get all pads that end in .md
|
||||
def all_publications():
|
||||
pads = all_pads()
|
||||
pubs = []
|
||||
print(pads)
|
||||
if(pads and pads['data'] and pads['data']['padIDs']):
|
||||
for pad in pads['data']['padIDs']:
|
||||
# if extension is .md add it to pubs
|
||||
if pad.endswith('.md'):
|
||||
# strip the .md
|
||||
name = pad.removesuffix('.md')
|
||||
pubs.append(name)
|
||||
return pubs
|
||||
else:
|
||||
return []
|
||||
|
||||
def create_pad_on_first_run(name, ext):
|
||||
pads = all_pads()
|
||||
pad = name+ext
|
||||
|
|
@ -87,7 +110,21 @@ def create_pad_on_first_run(name, ext):
|
|||
def md_to_html(md_pad_content):
|
||||
# Convert Markdown to HTML
|
||||
# html = markdown.markdown(md_pad_content, extensions=['meta', 'attr_list']) # attr_list does not work
|
||||
html = pypandoc.convert_text(md_pad_content, 'html', format='md')
|
||||
try:
|
||||
html = pypandoc.convert_text(md_pad_content, 'html', format='md')
|
||||
except RuntimeError as exc:
|
||||
message = str(exc)
|
||||
if "YAML" in message or "YAML metadata" in message:
|
||||
raise MarkdownRenderError(
|
||||
kind="yaml",
|
||||
message="Invalid YAML metadata. Use `key: value` and add a blank line.",
|
||||
original=str(exc)
|
||||
) from exc
|
||||
raise MarkdownRenderError(
|
||||
kind="markdown",
|
||||
message = "Markdown conversion failed. Please check the markdown for errors.",
|
||||
original = str(exc)
|
||||
) from exc
|
||||
|
||||
# Sanitize the Markdown
|
||||
# html = bleach.clean(html)
|
||||
|
|
@ -125,6 +162,17 @@ def get_app_root():
|
|||
def get_meta(metadata, key, default=None):
|
||||
return metadata.get(key, [default])[0]
|
||||
|
||||
def render_markdown_error(name, error):
|
||||
print("ERROR", error)
|
||||
return render_template(
|
||||
'error.html',
|
||||
name=name.strip(),
|
||||
error_text=str(error),
|
||||
error=error,
|
||||
lang="en",
|
||||
title="Markdown error"
|
||||
), 400
|
||||
|
||||
# ---
|
||||
|
||||
@APP.route('/', methods=['GET', 'POST'])
|
||||
|
|
@ -140,7 +188,8 @@ def index():
|
|||
create_pad_on_first_run(name, ext)
|
||||
return redirect(url_for("pad", name=name))
|
||||
else:
|
||||
return render_template('start.html', home_pad_url=APP.config['HOME_PAD_URL'])
|
||||
pubs = all_publications()
|
||||
return render_template('start.html', pubs = pubs, home_pad_url=APP.config['HOME_PAD_URL'])
|
||||
|
||||
@APP.route('/<name>/')
|
||||
def main(name):
|
||||
|
|
@ -190,7 +239,10 @@ def css(name):
|
|||
def preview(name):
|
||||
# TO GENERATE THE PREVIEW WEBPAGE
|
||||
md_pad_content = get_pad_content(name, ext='.md')
|
||||
html = md_to_html(md_pad_content)
|
||||
try:
|
||||
html = md_to_html(md_pad_content)
|
||||
except MarkdownRenderError as exc:
|
||||
return render_markdown_error(name, exc)
|
||||
metadata = get_md_metadata(md_pad_content)
|
||||
lang = get_meta(metadata, 'language', 'en')
|
||||
title = get_meta(metadata, 'title', 'Untitled')
|
||||
|
|
@ -201,21 +253,26 @@ def preview(name):
|
|||
def pagedjs(name):
|
||||
# TO GENERATE THE PAGED.JS WEBPAGE
|
||||
md_pad_content = get_pad_content(name, ext='.md')
|
||||
html = md_to_html(md_pad_content)
|
||||
try:
|
||||
html = md_to_html(md_pad_content)
|
||||
except MarkdownRenderError as exc:
|
||||
return render_markdown_error(name, exc)
|
||||
metadata = get_md_metadata(md_pad_content)
|
||||
lang = get_meta(metadata, 'language', 'en')
|
||||
title = get_meta(metadata, 'title', 'Untitled')
|
||||
cover = get_meta(metadata, 'cover', None)
|
||||
|
||||
impose = False #request.args.get("impose") == "true"
|
||||
|
||||
return render_template('pagedjs.html', name=name.strip(), pad_content=html, lang=lang, title=title, cover=cover, impose=impose)
|
||||
|
||||
@APP.route('/<name>/imposed.html')
|
||||
def imposed(name):
|
||||
# TO GENERATE THE IMPOSED WEBPAGE
|
||||
md_pad_content = get_pad_content(name, ext='.md')
|
||||
html = md_to_html(md_pad_content)
|
||||
try:
|
||||
html = md_to_html(md_pad_content)
|
||||
except MarkdownRenderError as exc:
|
||||
return render_markdown_error(name, exc)
|
||||
metadata = get_md_metadata(md_pad_content)
|
||||
lang = get_meta(metadata, 'language', 'en')
|
||||
title = get_meta(metadata, 'title', 'Untitled')
|
||||
|
|
@ -230,4 +287,6 @@ def imposed(name):
|
|||
if __name__ == '__main__':
|
||||
APP.debug = True
|
||||
APP.env = "development"
|
||||
# APP.debug = False
|
||||
# APP.env = "production"
|
||||
APP.run(host="0.0.0.0", port=APP.config["PORTNUMBER"], threaded=True)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@ from filter_registry import register_filter
|
|||
@register_filter
|
||||
def remove_star_before_img(text):
|
||||
# regex version
|
||||
return re.sub(r'\*\s*!?\[\]\(', '
|
||||
# return re.sub(r'\*\s*!?\[\]\(', '
|
||||
return re.sub(r'\*\s*!?\[\.*]\(', '
|
||||
|
||||
# @register_filter
|
||||
# def remove_star_before_img(text):
|
||||
|
|
|
|||
10
settings.py
10
settings.py
|
|
@ -1,16 +1,18 @@
|
|||
import os
|
||||
from pathlib import Path
|
||||
from dotenv import load_dotenv
|
||||
|
||||
# Load environment variables from the .env file
|
||||
load_dotenv()
|
||||
# Load environment variables from the .env file alongside this module.
|
||||
ENV_PATH = Path(__file__).resolve().parent / ".env"
|
||||
load_dotenv(dotenv_path=ENV_PATH)
|
||||
|
||||
# Bind them to Python variables
|
||||
APPLICATION_ROOT = os.environ.get('OCTOMODE_APPLICATION_ROOT', '/')
|
||||
PORTNUMBER = int(os.environ.get('OCTOMODE_PORTNUMBER', 5001))
|
||||
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_KEY = "97e3bf6a626eaaa3426833db3d936f3a"
|
||||
#os.environ.get('OCTOMODE_PAD_API_KEY', '')
|
||||
HOME_PAD_URL = os.environ.get('OCTOMODE_HOME_PAD_URL', '')
|
||||
PAD_API_KEY = os.environ.get('OCTOMODE_PAD_API_KEY', '')
|
||||
|
||||
# Check if API key is provided
|
||||
if not PAD_API_KEY or PAD_API_KEY == "XXX":
|
||||
|
|
|
|||
|
|
@ -100,10 +100,16 @@ div#nav{
|
|||
}
|
||||
|
||||
|
||||
.cols {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 3fr;
|
||||
margin-top: 3rem;
|
||||
}
|
||||
|
||||
.home_pad_iframe {
|
||||
height: 75vh;
|
||||
margin: 5rem;
|
||||
width: calc(100vw - 13rem);
|
||||
/* margin: 5rem; */
|
||||
/* width: calc(100vw - 13rem); */
|
||||
border: 1px solid black;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
|
|
|||
35
templates/error.html
Normal file
35
templates/error.html
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="{{ lang }}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link href="{{ url_for('css', name=name) }}" rel="stylesheet" type="text/css" media="print">
|
||||
<title>{{ title }} - {{ name }}</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>{{ title }}</h1>
|
||||
<p>The document "{{name}}" has an error.</p>
|
||||
{% if error.kind == "yaml" %}
|
||||
<p>It seems like that there's something wrong with the YAML at the top of your document. <br />
|
||||
It should be structured like this:
|
||||
</p>
|
||||
<pre>
|
||||
---
|
||||
title: My Title
|
||||
lang: en
|
||||
cover: https://example.com/image.jpg
|
||||
---
|
||||
</pre>
|
||||
<p>
|
||||
Make sure that there is a space between the ":" and the value.
|
||||
</p>
|
||||
{% endif %}
|
||||
{% elif error.kind == "markdown" %}
|
||||
There's something wrong with the markdown in your pad. Please check the document or revert some of your recent changes.
|
||||
{% endif %}
|
||||
<details>
|
||||
<summary>Details</summary>
|
||||
{{error.original}}
|
||||
</details>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -5,11 +5,23 @@
|
|||
<title>octomode</title>
|
||||
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='main.css') }}">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<style>
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body class="start-page">
|
||||
<form action="{{ url_for('index') }}" method="POST">
|
||||
<h1><input type="submit" value="open"> <input type="text" name="name"> <em class="octomode">in octomode</em></h1>
|
||||
</form>
|
||||
<div class="cols">
|
||||
<h2>Publications</h2>
|
||||
<p>Below a list of the publications on the server.</p>
|
||||
<ul>
|
||||
{% for pub in pubs %}
|
||||
<a href="{{ url_for('pdf',name=pub)}}">{{pub}}</a>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<iframe class="home_pad_iframe" src="{{ home_pad_url }}"></iframe>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
Loading…
Reference in a new issue