1
0
mirror of https://github.com/tiyn/beaker-blog.git synced 2025-10-17 05:11:16 +02:00

Compare commits

6 Commits

Author SHA1 Message Date
9fd714eef3 added robots 2024-04-22 06:14:32 +02:00
a927a18e39 tts: added error handling 2024-04-22 02:29:14 +02:00
6e844a3cb1 added tts functionality 2024-04-22 02:06:12 +02:00
9ea9ab3c53 improved css for footer placement 2024-04-21 04:00:41 +02:00
73d9faea42 added feed to the footer 2024-04-21 02:58:33 +02:00
586549a7f9 added changable timezone for rss feed 2024-04-21 02:14:11 +02:00
10 changed files with 100 additions and 19 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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")

View File

@@ -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"

View File

@@ -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

View File

@@ -5,3 +5,4 @@ WTForms
Flask_WTF
Font-Awesome-Flask
BeautifulSoup4
gTTS

View File

@@ -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
View File

2
src/templates/robots.txt Normal file
View File

@@ -0,0 +1,2 @@
User-agent: *
Disallow: /static/

View File

@@ -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>