mirror of
https://github.com/tiyn/beaker-blog.git
synced 2025-04-19 15:27:47 +02:00
Compare commits
No commits in common. "41ba108e3f113075bae9354352e4a71be39be4d8" and "910e6bcc0a018768912e33a575ab8ce95c6c09ec" have entirely different histories.
41ba108e3f
...
910e6bcc0a
39
src/app.py
39
src/app.py
@ -1,4 +1,4 @@
|
|||||||
from flask import (Flask, abort, make_response, redirect, render_template, request, url_for)
|
from flask import Flask, abort, make_response, render_template, request
|
||||||
from flask_font_awesome import FontAwesome
|
from flask_font_awesome import FontAwesome
|
||||||
|
|
||||||
import config
|
import config
|
||||||
@ -28,12 +28,8 @@ def page_not_found(e):
|
|||||||
language=LANGUAGE), 404
|
language=LANGUAGE), 404
|
||||||
|
|
||||||
|
|
||||||
@app.route("/index.html")
|
|
||||||
def index_re():
|
|
||||||
return redirect(url_for("index"))
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/")
|
@app.route("/")
|
||||||
|
@app.route("/index.html")
|
||||||
def index():
|
def index():
|
||||||
content = con_gen.gen_index_string()
|
content = con_gen.gen_index_string()
|
||||||
return render_template("index.html",
|
return render_template("index.html",
|
||||||
@ -44,12 +40,8 @@ def index():
|
|||||||
language=LANGUAGE)
|
language=LANGUAGE)
|
||||||
|
|
||||||
|
|
||||||
@app.route("/search.html", methods=["GET", "POST"])
|
|
||||||
def search_re():
|
|
||||||
return redirect(url_for("search"))
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/search", methods=["GET", "POST"])
|
@app.route("/search", methods=["GET", "POST"])
|
||||||
|
@app.route("/search.html", methods=["GET", "POST"])
|
||||||
def search():
|
def search():
|
||||||
form = SearchForm()
|
form = SearchForm()
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
@ -71,12 +63,8 @@ def search():
|
|||||||
language=LANGUAGE), 200
|
language=LANGUAGE), 200
|
||||||
|
|
||||||
|
|
||||||
@app.route("/imprint.html")
|
|
||||||
def imprint_re():
|
|
||||||
return redirect(url_for("imprint"))
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/imprint")
|
@app.route("/imprint")
|
||||||
|
@app.route("/imprint.html")
|
||||||
def imprint():
|
def imprint():
|
||||||
return render_template("imprint.html",
|
return render_template("imprint.html",
|
||||||
title=TITLE,
|
title=TITLE,
|
||||||
@ -86,12 +74,8 @@ def imprint():
|
|||||||
language=LANGUAGE)
|
language=LANGUAGE)
|
||||||
|
|
||||||
|
|
||||||
@app.route("/archive.html")
|
|
||||||
def archive_re():
|
|
||||||
return redirect(url_for("archive"))
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/archive")
|
@app.route("/archive")
|
||||||
|
@app.route("/archive.html")
|
||||||
def archive():
|
def archive():
|
||||||
content = con_gen.gen_arch_string()
|
content = con_gen.gen_arch_string()
|
||||||
return render_template("archive.html",
|
return render_template("archive.html",
|
||||||
@ -117,21 +101,14 @@ def entry(path):
|
|||||||
|
|
||||||
@app.route("/feed.xml")
|
@app.route("/feed.xml")
|
||||||
@app.route("/rss.xml")
|
@app.route("/rss.xml")
|
||||||
@app.route("/rss")
|
|
||||||
def feed_re():
|
|
||||||
return redirect(url_for("feed"))
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/feed")
|
|
||||||
def feed():
|
def feed():
|
||||||
content = con_gen.get_rss_string()
|
content = con_gen.get_rss_string()
|
||||||
feed_xml = render_template("feed.xml",
|
rss_xml = render_template("rss.xml",
|
||||||
content_string=content,
|
content_string=content,
|
||||||
title=TITLE,
|
title=TITLE,
|
||||||
description=DESCRIPTION,
|
description=DESCRIPTION,
|
||||||
website=WEBSITE,
|
website=WEBSITE)
|
||||||
language=LANGUAGE)
|
response = make_response(rss_xml)
|
||||||
response = make_response(feed_xml)
|
|
||||||
response.headers["Content-Type"] = "application/rss+xml"
|
response.headers["Content-Type"] = "application/rss+xml"
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
@ -1,17 +1,14 @@
|
|||||||
import locale
|
import locale
|
||||||
import os
|
import os
|
||||||
import pathlib
|
import pathlib
|
||||||
import urllib.parse
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from os import path
|
from os import path
|
||||||
|
|
||||||
import markdown
|
import markdown
|
||||||
from bs4 import BeautifulSoup
|
|
||||||
|
|
||||||
import config
|
import config
|
||||||
import search
|
import search
|
||||||
|
|
||||||
WEBSITE = config.WEBSITE
|
|
||||||
ENTRY_DIR = config.ENTRY_DIR
|
ENTRY_DIR = config.ENTRY_DIR
|
||||||
LANGUAGE = config.LANGUAGE
|
LANGUAGE = config.LANGUAGE
|
||||||
LOCAL = "de_DE.UTF-8" if LANGUAGE == "de-de" else "en_US.UTF-8"
|
LOCAL = "de_DE.UTF-8" if LANGUAGE == "de-de" else "en_US.UTF-8"
|
||||||
@ -93,32 +90,9 @@ def gen_index_string():
|
|||||||
if file.endswith(".md"):
|
if file.endswith(".md"):
|
||||||
content_string += gen_md_content(file, 2)
|
content_string += gen_md_content(file, 2)
|
||||||
content_string += "</div>"
|
content_string += "</div>"
|
||||||
content_string = absolutize_html(content_string)
|
|
||||||
return content_string
|
return content_string
|
||||||
|
|
||||||
|
|
||||||
def absolutize_html(string):
|
|
||||||
"""
|
|
||||||
Creates a html string from another string that only uses absolute links that use the full domain.
|
|
||||||
|
|
||||||
Parameters:
|
|
||||||
string: html-formatted string.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
string: html-formatted string with absolute linksn
|
|
||||||
"""
|
|
||||||
soup = BeautifulSoup(string, "html.parser")
|
|
||||||
for a_tag in soup.find_all("a"):
|
|
||||||
href = str(a_tag.get("href"))
|
|
||||||
if href.startswith("/") or href.startswith("."):
|
|
||||||
a_tag["href"] = urllib.parse.urljoin(WEBSITE, href)
|
|
||||||
for img_tag in soup.find_all("img"):
|
|
||||||
src = str(img_tag.get("src"))
|
|
||||||
if src.startswith("/") or src.startswith("."):
|
|
||||||
img_tag["src"] = urllib.parse.urljoin(WEBSITE, src)
|
|
||||||
return str(soup)
|
|
||||||
|
|
||||||
|
|
||||||
def gen_stand_string(path_ex):
|
def gen_stand_string(path_ex):
|
||||||
"""
|
"""
|
||||||
Creates a html-string for a file.
|
Creates a html-string for a file.
|
||||||
@ -148,7 +122,6 @@ def gen_stand_string(path_ex):
|
|||||||
content_string += line
|
content_string += line
|
||||||
if filename.endswith(".md"):
|
if filename.endswith(".md"):
|
||||||
content_string += gen_md_content(filename, 1)
|
content_string += gen_md_content(filename, 1)
|
||||||
content_string = absolutize_html(content_string)
|
|
||||||
return content_string
|
return content_string
|
||||||
|
|
||||||
|
|
||||||
@ -165,8 +138,10 @@ def gen_md_content(path_ex, depth):
|
|||||||
"""
|
"""
|
||||||
content_string = ""
|
content_string = ""
|
||||||
if path.exists(path_ex):
|
if path.exists(path_ex):
|
||||||
|
filename = path_ex.split(".", 1)
|
||||||
|
fileend = filename[len(filename) - 1]
|
||||||
header = "#"
|
header = "#"
|
||||||
for _ in range(depth):
|
for i in range(depth):
|
||||||
header += "#"
|
header += "#"
|
||||||
header += " "
|
header += " "
|
||||||
markdown_lines = open(path_ex, "r").readlines()[1:]
|
markdown_lines = open(path_ex, "r").readlines()[1:]
|
||||||
@ -184,7 +159,6 @@ def get_rss_string():
|
|||||||
Returns:
|
Returns:
|
||||||
string: rss-string of everything that is in the ENTRY_DIR.
|
string: rss-string of everything that is in the ENTRY_DIR.
|
||||||
"""
|
"""
|
||||||
locale.setlocale(locale.LC_TIME, "en_US.UTF-8")
|
|
||||||
path_ex = ENTRY_DIR
|
path_ex = ENTRY_DIR
|
||||||
content_string = ""
|
content_string = ""
|
||||||
if path.exists(path_ex):
|
if path.exists(path_ex):
|
||||||
@ -200,19 +174,16 @@ def get_rss_string():
|
|||||||
filename = filename.split(".", 1)[0]
|
filename = filename.split(".", 1)[0]
|
||||||
content_string += "<item>\n"
|
content_string += "<item>\n"
|
||||||
content_string += "<title>" + title + "</title>\n"
|
content_string += "<title>" + title + "</title>\n"
|
||||||
content_string += "<guid>" + WEBSITE + \
|
content_string += "<guid>" + config.WEBSITE + \
|
||||||
"/index.html#" + filename + "</guid>\n"
|
"/index.html#" + filename + "</guid>\n"
|
||||||
content_string += "<pubDate>" + \
|
content_string += "<pubDate>" + \
|
||||||
datetime.fromtimestamp(os.path.getmtime(file)).strftime(
|
datetime.fromtimestamp(os.path.getmtime(file)).strftime(
|
||||||
"%a, %d %b %Y %H:%M:%S") + " +0100</pubDate>\n"
|
"%Y-%m-%d") + "</pubDate>\n"
|
||||||
content_string += "<description>\n<![CDATA[<html>\n<head>\n</head>\n<body>\n"
|
content_string += "<description>"
|
||||||
html_string = ""
|
|
||||||
for line in text:
|
for line in text:
|
||||||
html_string += line
|
content_string += line
|
||||||
content_string += absolutize_html(html_string)
|
content_string += "</description>\n"
|
||||||
content_string += "\n</body></html>\n]]>\n</description>\n"
|
|
||||||
content_string += "</item>\n"
|
content_string += "</item>\n"
|
||||||
locale.setlocale(locale.LC_TIME, LOCAL)
|
|
||||||
return content_string
|
return content_string
|
||||||
|
|
||||||
|
|
||||||
@ -260,12 +231,20 @@ def create_preview(path, is_markdown):
|
|||||||
string: html-formated preview
|
string: html-formated preview
|
||||||
"""
|
"""
|
||||||
file = open(path, "r", encoding="utf-8")
|
file = open(path, "r", encoding="utf-8")
|
||||||
lines = file.read()
|
first_lines = file.readlines()
|
||||||
if is_markdown:
|
|
||||||
lines += markdown.markdown(lines)
|
|
||||||
preview = ""
|
preview = ""
|
||||||
first_p = BeautifulSoup(lines).find('p')
|
preview_length = 3
|
||||||
if first_p is not None:
|
for i, line in enumerate(first_lines):
|
||||||
preview = "\n<p>" + first_p.text + "</p>\n"
|
if i == 0:
|
||||||
preview += "...<br>"
|
continue
|
||||||
|
if i > preview_length:
|
||||||
|
break
|
||||||
|
if not line.isspace():
|
||||||
|
if is_markdown:
|
||||||
|
preview += markdown.markdown(line)
|
||||||
|
else:
|
||||||
|
preview += line
|
||||||
|
else:
|
||||||
|
preview_length += 1
|
||||||
|
preview += "<br>...<br>"
|
||||||
return preview
|
return preview
|
||||||
|
@ -4,4 +4,3 @@ Whoosh
|
|||||||
WTForms
|
WTForms
|
||||||
Flask_WTF
|
Flask_WTF
|
||||||
Font-Awesome-Flask
|
Font-Awesome-Flask
|
||||||
BeautifulSoup4
|
|
||||||
|
@ -14,6 +14,7 @@ ENTRY_DIR = config.ENTRY_DIR
|
|||||||
|
|
||||||
def createSearchableData(root):
|
def createSearchableData(root):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
Schema definition: title(name of file), path(as ID), content(indexed but not stored), textdata (stored text content)
|
Schema definition: title(name of file), path(as ID), content(indexed but not stored), textdata (stored text content)
|
||||||
source:
|
source:
|
||||||
https://appliedmachinelearning.blog/2018/07/31/developing-a-fast-indexing-and-full-text-search-engine-with-whoosh-a-pure-pythhon-library/
|
https://appliedmachinelearning.blog/2018/07/31/developing-a-fast-indexing-and-full-text-search-engine-with-whoosh-a-pure-pythhon-library/
|
||||||
|
@ -76,6 +76,7 @@ span {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width:800px) {
|
@media screen and (max-width:800px) {
|
||||||
|
|
||||||
.main-menu {
|
.main-menu {
|
||||||
background: var(--menubg0);
|
background: var(--menubg0);
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ body {
|
|||||||
body,
|
body,
|
||||||
html {
|
html {
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
|
height: 100%;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
@ -79,7 +80,6 @@ footer .center {
|
|||||||
.main-menu-dropdown img {
|
.main-menu-dropdown img {
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.main-menu-dropdown span,
|
.main-menu-dropdown span,
|
||||||
.main-menu-dropdown a {
|
.main-menu-dropdown a {
|
||||||
float: left;
|
float: left;
|
||||||
@ -147,7 +147,6 @@ footer .center {
|
|||||||
transition: var(--transtime);
|
transition: var(--transtime);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.main-menu a {
|
.main-menu a {
|
||||||
display: block;
|
display: block;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
@ -162,13 +161,8 @@ form {
|
|||||||
margin-bottom: 40px;
|
margin-bottom: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.standalone {
|
|
||||||
max-height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.entry {
|
.entry {
|
||||||
max-height: 100%;
|
border-radius: 0 10px 30px 0;
|
||||||
/* border-radius: 0 10px 30px 0; */
|
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
padding-left: 20px;
|
padding-left: 20px;
|
||||||
}
|
}
|
||||||
@ -231,7 +225,7 @@ ol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
code {
|
code {
|
||||||
/* border-radius: 25px; */
|
border-radius: 25px;
|
||||||
padding-left: 20px;
|
padding-left: 20px;
|
||||||
padding-right: 20px;
|
padding-right: 20px;
|
||||||
page-break-inside: avoid;
|
page-break-inside: avoid;
|
||||||
@ -264,10 +258,3 @@ form.search::after {
|
|||||||
clear: both;
|
clear: both;
|
||||||
display: table;
|
display: table;
|
||||||
}
|
}
|
||||||
|
|
||||||
.standalone img {
|
|
||||||
width: 50%;
|
|
||||||
}
|
|
||||||
.entry img {
|
|
||||||
width: 50%;
|
|
||||||
}
|
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
<title>{{ title }}</title>
|
<title>{{ title }}</title>
|
||||||
<description>{{ description }}</description>
|
<description>{{ description }}</description>
|
||||||
<language>{{ language }}</language>
|
<language>{{ language }}</language>
|
||||||
<link>{{ website }}</link>
|
<link>{{ website }}/feed.xml</link>
|
||||||
<atom:link href="{{ website }}{{ url_for('feed') }}" rel="self" type="application/rss+xml"/>
|
<atom:link href="/feed.xml" rel="self" type="application/rss+xml" />
|
||||||
|
|
||||||
{% autoescape off %}
|
{% autoescape off %}
|
||||||
{{ content_string }}
|
{{ content_string }}
|
@ -1,12 +1,11 @@
|
|||||||
<!DOCTYPE html>
|
<html>
|
||||||
<html lang={% if language=="de-de" %}de{% else %}en{% endif %}>
|
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<title>{{ title }}</title>
|
<title>{{ title }}</title>
|
||||||
<link href="{{ url_for('static', filename='css/' + style + '.css') }}" rel="stylesheet" type="text/css">
|
<link href="{{ url_for('static', filename='css/' + style + '.css') }}" rel="stylesheet" type="text/css">
|
||||||
<link rel="icon" type="image/x-icon" href="{{ url_for('static', filename='graphics/logo.png')}}">
|
<link rel="icon" type="image/x-icon" href="{{ url_for('static', filename='graphics/logo.png') }}">
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width">
|
<meta name="viewport" content="width=device-width" initial-scale=1.0>
|
||||||
{{ font_awesome.load_js() }}
|
{{ font_awesome.load_js() }}
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
@ -14,9 +13,7 @@
|
|||||||
<!-- Menu -->
|
<!-- Menu -->
|
||||||
<div class="main-menu-dropdown">
|
<div class="main-menu-dropdown">
|
||||||
<a href="{{ url_for('index') }}">
|
<a href="{{ url_for('index') }}">
|
||||||
<img class="logo" src="{{ url_for('static', filename='graphics/logo.png') }}" alt="Logo von
|
<img class="logo" src="{{ url_for('static', filename='graphics/logo.png') }}">
|
||||||
Mittelerde mit Marten. Zu sehen sind 3 'M's mit Serifen, wobei die beiden Äußeren etwas
|
|
||||||
kleiner sind">
|
|
||||||
{{ stitle }}
|
{{ stitle }}
|
||||||
</a>
|
</a>
|
||||||
<input type="checkbox" id="main-menu-check">
|
<input type="checkbox" id="main-menu-check">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user