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

feat: add hash to HTML filename in case of conflict

This commit is contained in:
Étienne Fildadut 2025-10-11 17:08:22 +02:00
parent 960e06252e
commit 0fd5ec6458
2 changed files with 27 additions and 16 deletions

View file

@ -68,7 +68,6 @@ You need Python 3.12 or newer. Then pip it up, as the kids say.
- [ ] Write documentation
- [ ] Use inotify for real-time article mark-as-read action
- [ ] Share the fun somewhere
- [ ] Actually think about the issues created by the duplicate warning
- [ ] Get article attachments
- [ ] Test with FreshRSS

View file

@ -87,7 +87,8 @@ class Article(ABC):
# no default value, computed by compute_fields
published_formatted: str # article publication time (text)
updated_formatted: str # article publication time (text)
html_path: str # html path, relative to the html_root directory
# no default value, computed on save_html
html_path: str = None # html path, relative to the html_root directory (None will force it to be recomputed on next save_html)
# with default value
unread: bool = True # if the article is unread
title: str = "" # article title
@ -104,7 +105,7 @@ class Article(ABC):
comments_url: str = "" # article comments URL
language: str = "" # article language
image_url: str = "" # article main image
def _get_html_path(self):
config = self.config
@ -123,22 +124,17 @@ class Article(ABC):
config,
config.article_filename_template.render(self._get_template_dict()),
)
html_path = category_directory / html_name
# Add hash if filename already exists
if html_path.exists():
id_hash = sha256(str(self.id).encode("utf-8")).hexdigest()[:8]
html_path = html_path.parent / sanitize_filename(
config, html_path.name, insert_before_suffix=f".{id_hash}"
)
return html_path.relative_to(config.html_root)
def compute_fields(self):
config = self.config
self.updated_formatted = format_datetime(config, self.updated)
self.published_formatted = format_datetime(config, self.published)
self.json_path = (
config.json_root
/ f"{sha256(str(self.id).encode('utf-8')).hexdigest()}.json"
)
self.html_path = str(
self.get_html_path().relative_to(config.html_root)
) # TODO: do this dynamically on write, handle overwrite conflict at the same time
def get_template_dict(self) -> dict:
def _get_template_dict(self) -> dict:
template_fields = (
"id",
"unread",
@ -163,6 +159,16 @@ class Article(ABC):
d["category"] = self.category.asdict()
return d
def compute_fields(self):
config = self.config
self.updated_formatted = format_datetime(config, self.updated)
self.published_formatted = format_datetime(config, self.published)
self.json_path = (
config.json_root
/ f"{sha256(str(self.id).encode('utf-8')).hexdigest()}.json"
)
self.html_path = None
def write_json(self):
"""Write the JSON file associated with this article. Error if it already exists."""
stored_fields = (
@ -208,8 +214,14 @@ class Article(ABC):
return html_path.exists()
def write_html(self):
"""Write the HTML file associated with this article. Error if it already exists.
Note: this may recompute html_path, which is saved into the JSON - so make sure to save the JSON file _after_ the HTML file."""
# Write HTML file for a JSON object
config = self.config
if self.html_path is None:
self.html_path = str(self._get_html_path())
html_path = config.html_root / self.html_path
if html_path.exists():
raise Exception(