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

feat: add daemon mode

This commit is contained in:
Étienne Fildadut 2025-10-09 18:32:36 +02:00
parent 4cf6da5f0a
commit 4d5b9a78d9
3 changed files with 37 additions and 4 deletions

27
main.py
View file

@ -5,6 +5,7 @@ import google_reader
import tomllib
import sys
import argparse
import asyncio
from datetime import datetime
from zoneinfo import ZoneInfo
from pathlib import Path
@ -54,6 +55,8 @@ class Config:
self.item_filename_template: Template = Template(str(get_config("html", "filename_template")), autoescape=False)
self.max_filename_length: int = int(get_config("html", "max_filename_length"))
self.filename_translation = str.maketrans(get_config("html", "filename_replacement"))
self.daemon_sync_up_every: int = int(get_config("daemon", "sync_up_every"))
self.daemon_sync_down_every: int = int(get_config("daemon", "sync_down_every"))
# Computed config fields
self.update_lock = self.json_root / "update.lock"
@ -260,6 +263,20 @@ def synchronize_remote_changes(config, client_session):
synchronize_with_server(config, client_session)
remove_empty_html_directories(config)
async def daemon_sync_up_loop(config, client_session):
while True:
synchronize_local_changes(config, client_session)
await asyncio.sleep(config.daemon_sync_up_every)
async def daemon_sync_down_loop(config, client_session):
while True:
synchronize_remote_changes(config, client_session)
await asyncio.sleep(config.daemon_sync_down_every)
async def daemon(config, client_session):
print(f"Started in daemon mode; changes will be downloaded from the server every {config.daemon_sync_down_every}s and uploaded every {config.daemon_sync_up_every}s")
async with asyncio.TaskGroup() as tg:
tg.create_task(daemon_sync_up_loop(config, client_session))
tg.create_task(daemon_sync_down_loop(config, client_session))
def regenerate_files(config):
for json_path in config.json_root.glob("*.json"):
item_json = json.load(json_path.open("r"))
@ -279,8 +296,8 @@ def main():
description="file-based RSS reader"
)
parser.add_argument(
"action", choices=("sync", "sync-up", "sync-down", "regenerate"),
help="sync: perform a full synchronization with the server; sync-up: only synchronize local changes to the server (e.g. items read locally); sync-down: only synchronize remote change from the server (e.g. new items or items read from another device); regenerate: regenerate all HTML files from the local data"
"action", choices=("sync", "sync-up", "sync-down", "daemon", "regenerate"),
help="sync: perform a full synchronization with the server; sync-up: only synchronize local changes to the server (e.g. items read locally); sync-down: only synchronize remote change from the server (e.g. new items or items read from another device); daemon: start in daemon mode (will keep performing synchronizations periodically until process is stopped); regenerate: regenerate all HTML files from the local data"
)
args = parser.parse_args()
@ -294,6 +311,12 @@ def main():
elif args.action == "sync-down":
client_session = ClientSession(config)
synchronize_remote_changes(config, client_session)
elif args.action == "daemon":
client_session = ClientSession(config)
try:
asyncio.run(daemon(config, client_session))
except KeyboardInterrupt:
pass
elif args.action == "regenerate":
regenerate_files(config)