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

feat: add command to regenerate local files

This commit is contained in:
Étienne Fildadut 2025-10-09 17:51:01 +02:00
parent e5b9fec570
commit c421cf3509

44
main.py
View file

@ -4,6 +4,7 @@ import json
import google_reader
import tomllib
import sys
import argparse
from datetime import datetime
from zoneinfo import ZoneInfo
from pathlib import Path
@ -102,13 +103,13 @@ def mark_deleted_as_read(config, client_session):
marked_as_read = 0
to_mark_as_read = []
for stored_item in config.json_root.glob("*.json"):
item_json = json.load(stored_item.open("r"))
for json_path in config.json_root.glob("*.json"):
item_json = json.load(json_path.open("r"))
html_path = config.html_root / item_json["html_path"]
if not html_path.exists():
to_mark_as_read.append(item_json["id"])
# delete JSON file
stored_item.unlink()
json_path.unlink()
marked_as_read += 1
for i in range(0, len(to_mark_as_read), config.items_per_query):
@ -141,6 +142,11 @@ def get_html_path(config, item_json):
def format_datetime(config, timestamp):
return datetime.fromtimestamp(timestamp, config.timezone).strftime(config.time_format)
def set_computed_fields_json(config, item_json):
item_json["published_formatted"] = format_datetime(config, item_json["published"])
item_json["updated_formatted"] = format_datetime(config, item_json["updated"])
item_json["html_path"] = str(get_html_path(config, item_json).relative_to(config.html_root))
def synchronize_with_server(config, client_session):
# Synchronize items from the server, generating and deleting JSON and HTML files accordingly
config.update_lock.touch()
@ -163,9 +169,7 @@ def synchronize_with_server(config, client_session):
"folder": folder_name,
"title": item_content.title,
"published": item_content.published,
"published_formatted": format_datetime(config, item_content.published),
"updated": item_content.updated,
"updated_formatted": format_datetime(config, item_content.updated),
"author": item_content.author,
"summary": item_content.summary.content,
"content": item_content.content.content,
@ -173,7 +177,7 @@ def synchronize_with_server(config, client_session):
"origin_url": item_content.origin.html_url,
"canonical_url": item_content.canonical[0].href,
}
item_json["html_path"] = str(get_html_path(config, item_json).relative_to(config.html_root))
set_computed_fields_json(config, item_json)
json_path = config.json_root / f"{ sha256(item_json["id"].encode("utf-8")).hexdigest() }.json"
grabbed_item_paths.append(json_path)
@ -240,18 +244,42 @@ def remove_empty_html_directories(config):
if len(dirnames) == 0 and len(filenames) == 0:
dirpath.rmdir()
def process(config, client_session):
def update(config, client_session):
# Do a full feather update
mark_deleted_as_read(config, client_session)
synchronize_with_server(config, client_session)
remove_empty_html_directories(config)
def regenerate_files(config):
for json_path in config.json_root.glob("*.json"):
item_json = json.load(json_path.open("r"))
remove_html_for_item(config, item_json, ignore_deleted=True) # path might change so we preemptively remove the old file
set_computed_fields_json(config, item_json) # recompute formatted datetime & path from the current configuration
# rewrite JSON
with json_path.open("w") as f:
json.dump(item_json, f)
# rewrite HTML
generate_html_for_item(config, item_json, regenerate=True)
#%% Run feather
def main():
parser = argparse.ArgumentParser(
prog="feather",
description="file-based RSS reader"
)
parser.add_argument(
"action", choices=("update", "regenerate"),
help='''use update to perform a full synchronization with the server; regenerate will regenerate all HTML files from the local data'''
)
args = parser.parse_args()
config = Config()
if args.action == "update":
client_session = ClientSession(config)
process(config, client_session)
update(config, client_session)
elif args.action == "regenerate":
regenerate_files(config)
if __name__ == "__main__":
main()