improve markdown rendering, add error handlers, simplify index route logic

This commit is contained in:
mst 2024-12-16 16:49:42 +03:00
parent 4557b166bb
commit 71cbd9e54b
2 changed files with 74 additions and 60 deletions

71
app.py
View file

@ -110,47 +110,50 @@ def inject_stuff():
return dict(metadata=func.generateMetadata(), len=len, str=str, const=const, cfg=cfg, logged_in=logged_in, version_id=const.version_id, version=const.version, appName=const.appName, questionCount=questionCount)
# -- template filters --
# {text} | render_markdown
@app.template_filter('render_markdown')
def render_markdown(text):
# app.logger.debug("[CatAsk] app.template_filter render_markdown(text) triggered")
return func.renderMarkdown(text)
if text.startswith("![") and not (text.startswith(':') and text.endswith(':')):
return text
else:
# app.logger.debug("[CatAsk] app.template_filter render_markdown(text) triggered")
return func.renderMarkdown(text)
# render_markdown({text}, fromWho=False|True)
@app.template_global('render_markdown')
def render_markdown(text, fromWho=False):
if (text.startswith("![") or "![" in text) and not (text.startswith(':') and text.endswith(':')):
# ensuring that only inline images get escaped, not emojis
escaped = text.replace("![", "!\[")
return func.renderMarkdown(escaped)
else:
# don't want people inserting buttons and other stuff into name field
allowed_tags = ["p", "img"] if fromWho else None
return func.renderMarkdown(text, allowed_tags)
# -- error handlers --
@app.errorhandler(404)
def notFound(e):
return render_template('errors/404.html'), 404
@app.errorhandler(500)
def internalServerError(e):
return render_template('errors/500.html'), 500
@app.errorhandler(502)
def badGateway(e):
return render_template('errors/502.html'), 502
# -- client (frontend) routes --
@app.route('/', methods=['GET'])
def index():
conn = func.connectToDb()
cursor = conn.cursor(dictionary=True)
app.logger.debug("[CatAsk/Home] SELECT'ing pinned questions")
cursor.execute("SELECT * FROM questions WHERE answered=%s AND pinned=%s ORDER BY creation_date DESC", (True, True))
pinned_questions = cursor.fetchall()
app.logger.debug("[CatAsk/Home] SELECT'ing non-pinned questions")
cursor.execute("SELECT * FROM questions WHERE answered=%s AND pinned=%s ORDER BY creation_date DESC", (True, False))
non_pinned_questions = cursor.fetchall()
questions = pinned_questions + non_pinned_questions
app.logger.debug("[CatAsk/Home] SELECT'ing answers")
cursor.execute("SELECT * FROM answers ORDER BY creation_date DESC")
answers = cursor.fetchall()
metadata = func.generateMetadata()
combined = []
for question in questions:
question_answers = [answer for answer in answers if answer['question_id'] == question['id']]
combined.append({
'question': question,
'answers': question_answers
})
cursor.close()
conn.close()
# func.getAllQuestions() returns combined and metadata
func_val = func.getAllQuestions()
combined = func_val[0]
metadata = func_val[1]
return render_template('index.html', combined=combined, urllib=urllib, trimContent=func.trimContent, metadata=metadata, getRandomWord=func.getRandomWord, formatRelativeTime=func.formatRelativeTime)

View file

@ -506,33 +506,44 @@ def processEmojis(meta_json_path):
return processed_emojis
def renderMarkdown(text):
def renderMarkdown(text, allowed_tags=None):
plugins = [
'strikethrough',
button,
emoji
]
allowed_tags = [
'p',
'em',
'b',
'strong',
'i',
'br',
's',
'del',
'a',
'button',
'ol',
'li',
'hr',
'img'
]
# allowed_attrs = {
# 'a': 'href',
# 'button': 'class',
# # 'img': ['src', 'width', 'height', 'alt', 'class', 'loading', 'title']
# }
if not allowed_tags:
allowed_tags = [
'p',
'em',
'b',
'strong',
'i',
'br',
's',
'del',
'a',
'button',
'ol',
'li',
'hr',
'img',
'code',
'pre'
]
allowed_attrs = {
'a': 'href',
'button': 'class',
'img': {
'class': lambda value: value == "emoji",
'src': True, # Allow specific attributes on emoji images
'alt': True,
'title': True,
'width': True,
'height': True,
'loading': True
}
}
# hard_wrap=True means that newlines will be
# converted into <br> tags
#
@ -545,10 +556,10 @@ def renderMarkdown(text):
plugins=plugins,
hard_wrap=True
)
cleaner = Cleaner(tags=allowed_tags)
clean_text = cleaner.clean(text)
html = md(clean_text)
return Markup(html)
html = md(text)
cleaner = Cleaner(tags=allowed_tags, attributes=allowed_attrs)
clean_html = cleaner.clean(html)
return Markup(clean_html)
def generateMetadata(question=None, answer=None):
metadata = {