1
0
Fork 0
mirror of https://codeberg.org/Reuh/feather.git synced 2025-10-28 02:29:32 +00:00

feat: use jinja templates for HTML & filenames

This commit is contained in:
Étienne Fildadut 2025-10-09 15:30:19 +02:00
parent 75d9367e4f
commit d29b97ebf5
4 changed files with 121 additions and 29 deletions

38
main.py
View file

@ -8,6 +8,7 @@ from datetime import datetime
from zoneinfo import ZoneInfo
from pathlib import Path
from hashlib import sha256
from jinja2 import Template
#%% Configuration
@ -36,13 +37,15 @@ class Config:
# Get config fields
self.html_root: Path = Path(get_config("directories", "reader"))
self.json_root: Path = Path(get_config("directories", "data"))
self.max_filename_length: int = int(get_config("directories", "max_filename_length"))
self.server_url: str = str(get_config("server", "url", False))
self.server_user: str = str(get_config("server", "user", False))
self.server_password: str = str(get_config("server", "password", False))
self.items_per_query: int = int(get_config("server", "items_per_request"))
self.timezone: ZoneInfo = ZoneInfo(get_config("time", "timezone"))
self.time_format: str = str(get_config("time", "format"))
self.item_template: Template = Template(get_config("html", "template"), autoescape=True)
self.item_filename_template: Template = Template(get_config("html", "filename_template"), autoescape=False)
self.max_filename_length: int = int(get_config("html", "max_filename_length"))
# Computed config fields
self.update_lock = self.json_root / "update.lock"
@ -109,14 +112,17 @@ def mark_deleted_as_read(config, client_session):
def escape_filename(filename):
return filename.replace("/", "-")
def get_html_path(config, item_json):
def truncate_filename(config, filename):
max_filename_length = config.max_filename_length
suffix = Path(filename).suffix
max_basename_length = max_filename_length - len(suffix)
return filename[:max_basename_length] + '' + suffix if len(filename) > max_filename_length else filename
def get_html_path(config, item_json):
folder_directory = config.html_root / escape_filename(item_json["folder"])
folder_directory.mkdir(exist_ok=True)
html_name = escape_filename(f"{item_json["published_formatted"]}\t[{item_json["origin_title"]}]\t{item_json["title"]}.html")
html_name = html_name[:max_filename_length] + '….html' if len(html_name) > max_filename_length else html_name
html_name = truncate_filename(config, escape_filename(config.item_filename_template.render(item_json)))
html_path = folder_directory / html_name
return html_path
@ -196,29 +202,7 @@ def generate_html_for_item(config, item_json):
print(f"WARNING: a file already exist for {html_path}. Either the feed has duplicate entries, or something has gone terribly wrong.")
else:
with html_path.open("w") as f:
f.write(f"""
<!doctype html>
<html lang="en-US">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>{item_json["title"]}</title>
</head>
<body style="background-color:black; color:white;">
<style>a{{color:palevioletred; text-decoration:none;}}</style>
<article style="max-width:60rem; margin:auto;">
<p style="display:flex; flex-direction:row; justify-content:space-between;">
<span>{item_json["published_formatted"]}</span>
<span><a href="{item_json["origin_url"]}">{item_json["origin_title"]}</a></span>
</p>
<h1><a href="{item_json["canonical_url"]}">{item_json["title"]}</a></h1>
<h3>{item_json["author"]}</h3>
<div>{item_json["summary"]}</div>
<div>{item_json["content"]}</div>
</article>
</body>
</html>
""")
f.write(config.item_template.render(item_json))
def remove_html_for_item(config, item_json):
# Delete a HTML file for a JSON object