From 0a5464c523618c66ef2736683db38731282d8d35 Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Fri, 31 Jul 2026 08:52:55 +0200 Subject: feat: remember target in state.json for bare-dir resume An archive dir that has been backed up once now records its target in state.json, so later runs can be just --archive-dir. --target is still required the first time, and still wins when given. Co-Authored-By: Claude Opus 5 --- tg_backup.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'tg_backup.py') diff --git a/tg_backup.py b/tg_backup.py index e038b92..6c77878 100644 --- a/tg_backup.py +++ b/tg_backup.py @@ -188,7 +188,10 @@ async def run_backup(target, archive_dir): "chat is in the session's entity cache.") state = load_state(archive_dir) + # Remember the target so later runs can resume with just --archive-dir. + state['target'] = target last_id = state['last_id'] + save_state(archive_dir, state) print(f"Resuming from message ID: {last_id}") # reverse=True ensures oldest-to-newest processing. @@ -236,10 +239,14 @@ def main(): args = parser.parse_args() if args.list_chats: asyncio.run(list_chats(args.archive_dir)) - elif args.target: - asyncio.run(run_backup(args.target, args.archive_dir)) + return + # An archive dir already backed up once knows its own target. + target = args.target or load_state(args.archive_dir).get('target') + if target: + asyncio.run(run_backup(target, args.archive_dir)) else: - parser.error("--target is required (or use --list-chats)") + parser.error(f"--target is required the first time ({args.archive_dir}/state.json " + "has no saved target), or use --list-chats") def _self_check(): """Run with --self-check. Guards the path-traversal and state-write logic.""" @@ -280,6 +287,11 @@ def _self_check(): assert not list(archive.glob('*.tmp')), "temp state file left behind" assert load_state(Path(tempfile.mkdtemp())) == {'last_id': 0} + # A saved target survives, and a fresh dir has none to fall back on. + save_state(archive, {'last_id': 9, 'target': '-1001234567890'}) + assert load_state(archive).get('target') == '-1001234567890' + assert load_state(Path(tempfile.mkdtemp())).get('target') is None + print("self-check OK") if __name__ == "__main__": -- cgit v1.2.3