mirror of
https://github.com/tiyn/beaker-blog.git
synced 2025-10-17 05:11:16 +02:00
Compare commits
6 Commits
41ba108e3f
...
master
Author | SHA1 | Date | |
---|---|---|---|
9fd714eef3 | |||
a927a18e39 | |||
6e844a3cb1 | |||
9ea9ab3c53 | |||
73d9faea42 | |||
586549a7f9 |
18
Dockerfile
18
Dockerfile
@@ -2,11 +2,9 @@ FROM python:3
|
||||
|
||||
MAINTAINER tiyn tiyn@mail-mk.eu
|
||||
|
||||
COPY src /blog
|
||||
|
||||
WORKDIR /blog
|
||||
|
||||
RUN pip3 install -r requirements.txt
|
||||
ENV LANG en_US.UTF-8
|
||||
ENV LANGUAGE en_US:en
|
||||
ENV LC_ALL en_US.UTF-8
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y locales && \
|
||||
@@ -14,9 +12,13 @@ RUN apt-get update && \
|
||||
sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && \
|
||||
dpkg-reconfigure --frontend=noninteractive locales
|
||||
|
||||
ENV LANG en_US.UTF-8
|
||||
ENV LANGUAGE en_US:en
|
||||
ENV LC_ALL en_US.UTF-8
|
||||
RUN apt-get install -y espeak
|
||||
|
||||
COPY src /blog
|
||||
|
||||
WORKDIR /blog
|
||||
|
||||
RUN pip3 install -r requirements.txt
|
||||
|
||||
VOLUME /blog/templates/entry
|
||||
|
||||
|
@@ -22,6 +22,7 @@ via plain text files.
|
||||
- [x] Links to standalone article
|
||||
- [x] Standalone article page
|
||||
- [x] Links to scrolling blog page
|
||||
- [x] TTS Functionality
|
||||
- [x] RSS feed
|
||||
- [x] Navigation
|
||||
- [x] Header
|
||||
|
@@ -121,6 +121,10 @@ def entry(path):
|
||||
def feed_re():
|
||||
return redirect(url_for("feed"))
|
||||
|
||||
@app.route("/robots.txt")
|
||||
def robots():
|
||||
return render_template("robots.txt")
|
||||
|
||||
|
||||
@app.route("/feed")
|
||||
def feed():
|
||||
@@ -137,4 +141,5 @@ def feed():
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
con_gen.prepare_tts()
|
||||
app.run(host="0.0.0.0")
|
||||
|
@@ -21,3 +21,6 @@ MAIL = "dummy@mail.com"
|
||||
|
||||
# Directory to store entries in
|
||||
ENTRY_DIR = "templates/entry"
|
||||
|
||||
# Set the timezone of your blog
|
||||
TIMEZONE = "+0000"
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import glob
|
||||
import locale
|
||||
import os
|
||||
import pathlib
|
||||
@@ -7,6 +8,7 @@ from os import path
|
||||
|
||||
import markdown
|
||||
from bs4 import BeautifulSoup
|
||||
from gtts import gTTS, gTTSError
|
||||
|
||||
import config
|
||||
import search
|
||||
@@ -15,6 +17,7 @@ WEBSITE = config.WEBSITE
|
||||
ENTRY_DIR = config.ENTRY_DIR
|
||||
LANGUAGE = config.LANGUAGE
|
||||
LOCAL = "de_DE.UTF-8" if LANGUAGE == "de-de" else "en_US.UTF-8"
|
||||
TIMEZONE = config.TIMEZONE
|
||||
|
||||
locale.setlocale(locale.LC_TIME, LOCAL)
|
||||
|
||||
@@ -143,6 +146,11 @@ def gen_stand_string(path_ex):
|
||||
content_string += "<a href=\"" + "/index.html#" + \
|
||||
filename_no_end + "\">" + curr_date + "</a>"
|
||||
content_string += "<br><br>\n"
|
||||
if os.path.isfile("static/tmp/" + filename_no_end + ".mp3"):
|
||||
content_string += "<audio controls>\n"
|
||||
content_string += '<source src="/static/tmp/' + filename_no_end + '.mp3" type="audio/mp3">\n'
|
||||
content_string += "</audio>\n"
|
||||
content_string += "<br><br>\n"
|
||||
if filename.endswith(".html"):
|
||||
for line in text:
|
||||
content_string += line
|
||||
@@ -184,7 +192,6 @@ def get_rss_string():
|
||||
Returns:
|
||||
string: rss-string of everything that is in the ENTRY_DIR.
|
||||
"""
|
||||
locale.setlocale(locale.LC_TIME, "en_US.UTF-8")
|
||||
path_ex = ENTRY_DIR
|
||||
content_string = ""
|
||||
if path.exists(path_ex):
|
||||
@@ -202,9 +209,11 @@ def get_rss_string():
|
||||
content_string += "<title>" + title + "</title>\n"
|
||||
content_string += "<guid>" + WEBSITE + \
|
||||
"/index.html#" + filename + "</guid>\n"
|
||||
locale.setlocale(locale.LC_TIME, "en_US.UTF-8")
|
||||
content_string += "<pubDate>" + \
|
||||
datetime.fromtimestamp(os.path.getmtime(file)).strftime(
|
||||
"%a, %d %b %Y %H:%M:%S") + " +0100</pubDate>\n"
|
||||
"%a, %d %b %Y %H:%M:%S") + " " + TIMEZONE + "</pubDate>\n"
|
||||
locale.setlocale(locale.LC_TIME, LOCAL)
|
||||
content_string += "<description>\n<![CDATA[<html>\n<head>\n</head>\n<body>\n"
|
||||
html_string = ""
|
||||
for line in text:
|
||||
@@ -212,7 +221,6 @@ def get_rss_string():
|
||||
content_string += absolutize_html(html_string)
|
||||
content_string += "\n</body></html>\n]]>\n</description>\n"
|
||||
content_string += "</item>\n"
|
||||
locale.setlocale(locale.LC_TIME, LOCAL)
|
||||
return content_string
|
||||
|
||||
|
||||
@@ -269,3 +277,55 @@ def create_preview(path, is_markdown):
|
||||
preview = "\n<p>" + first_p.text + "</p>\n"
|
||||
preview += "...<br>"
|
||||
return preview
|
||||
|
||||
|
||||
def get_text_only(filename):
|
||||
"""
|
||||
Convert a file to text only to use in tts
|
||||
|
||||
Parameters:
|
||||
path (string): path to the article
|
||||
|
||||
Returns:
|
||||
string: unformatted string containing the contents of the file
|
||||
"""
|
||||
# filename = os.path.join(ENTRY_DIR, path)
|
||||
clean_text = ""
|
||||
if path.exists(filename):
|
||||
title = open(filename).readline().rstrip("\n")
|
||||
text = open(filename).readlines()[1:]
|
||||
filename_no_end = filename.split(".", 1)[0]
|
||||
filename_no_end = filename_no_end.split("/")[-1]
|
||||
content_string = ""
|
||||
if filename.endswith(".html"):
|
||||
for line in text:
|
||||
content_string += line
|
||||
if filename.endswith(".md"):
|
||||
content_string += gen_md_content(filename, 1)
|
||||
content_string = absolutize_html(content_string)
|
||||
soup = BeautifulSoup(content_string, "html.parser")
|
||||
tag_to_remove = soup.find("figure")
|
||||
if tag_to_remove:
|
||||
tag_to_remove.decompose()
|
||||
clean_text = soup.get_text(separator=" ")
|
||||
clean_text = title + "\n\n" + clean_text
|
||||
return clean_text
|
||||
|
||||
|
||||
def prepare_tts():
|
||||
files = glob.glob('static/tmp/*')
|
||||
for f in files:
|
||||
os.remove(f)
|
||||
files = glob.glob('templates/entry/*')
|
||||
clean_text = ""
|
||||
for f in files:
|
||||
clean_text = get_text_only(f)
|
||||
_, tail = os.path.split(f)
|
||||
new_filename = "static/tmp/" + os.path.splitext(tail)[0] + ".mp3"
|
||||
try:
|
||||
tts = gTTS(clean_text, lang=LANGUAGE.split("-")[0])
|
||||
tts.save(new_filename)
|
||||
except gTTSError as e:
|
||||
print("Too many request to the google servers. Try it again later.")
|
||||
os.remove(new_filename)
|
||||
return e
|
||||
|
@@ -5,3 +5,4 @@ WTForms
|
||||
Flask_WTF
|
||||
Font-Awesome-Flask
|
||||
BeautifulSoup4
|
||||
gTTS
|
||||
|
@@ -31,6 +31,7 @@ html {
|
||||
footer {
|
||||
height: 100px;
|
||||
padding-top: 20px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
footer .center {
|
||||
@@ -38,11 +39,12 @@ footer .center {
|
||||
}
|
||||
|
||||
.container {
|
||||
min-height: 100%;
|
||||
padding-bottom: 50px;
|
||||
padding-left: 10%;
|
||||
padding-right: 10%;
|
||||
padding-top: 5%;
|
||||
padding-top: 5vh;
|
||||
/* position: relative; */
|
||||
min-height: calc(100vh - 50px - 5vh - 100px - 100px);
|
||||
}
|
||||
|
||||
.container .flash {
|
||||
@@ -163,11 +165,10 @@ form {
|
||||
}
|
||||
|
||||
.standalone {
|
||||
max-height: 100%;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.entry {
|
||||
max-height: 100%;
|
||||
/* border-radius: 0 10px 30px 0; */
|
||||
margin-bottom: 20px;
|
||||
padding-left: 20px;
|
||||
@@ -252,7 +253,7 @@ form.search input[type=text] {
|
||||
form.search button[type=submit] {
|
||||
float: left;
|
||||
width: 5%;
|
||||
padding: 12px;
|
||||
padding: 10px;
|
||||
font-size: 17px;
|
||||
border: 1px solid grey;
|
||||
border-left: none; /* Prevent double borders */
|
||||
@@ -268,6 +269,12 @@ form.search::after {
|
||||
.standalone img {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.entry img {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
audio {
|
||||
width: 50%;
|
||||
height: 5vh;
|
||||
}
|
||||
|
0
src/static/tmp/.gitkeep
Normal file
0
src/static/tmp/.gitkeep
Normal file
2
src/templates/robots.txt
Normal file
2
src/templates/robots.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
User-agent: *
|
||||
Disallow: /static/
|
@@ -35,9 +35,9 @@
|
||||
<!-- Content -->
|
||||
<footer>
|
||||
<div class="center">
|
||||
<a href="{{ url_for('imprint') }}">
|
||||
{% if language=="de-de" %}Impressum und Kontakt{% else %}Imprint and Contact{% endif %}
|
||||
</a><br>
|
||||
<a href="{{ url_for('imprint') }}">{% if language=="de-de" %}Impressum und Kontakt{% else %}Imprint and Contact{%
|
||||
endif %}</a>.<br>
|
||||
<a href="{{ url_for('feed') }}">{% if language=="de-de" %}RSS-Feed{% else %}RSS feed{% endif %}</a>.<br>
|
||||
Made with <a href="https://github.com/tiyn/beaker-blog">Beaker Blog</a>.
|
||||
</div>
|
||||
</footer>
|
||||
|
Reference in New Issue
Block a user