feat: guard against a dead Instagram session, show progress, fix missing pings
- check-session.py: preflight in gdl-cron.sh. No unexpired sessionid in the Chrome profile gdl reads -> abort before any request, ping /76 (red check). - stories-streak.py: postflight. Every fetched stories source empty for 3 consecutive days -> exit 77, for a session Instagram stopped honouring while the cookie is still present. The 2026-10-07 session death went unnoticed for a week because every run still exited 0. - gdl-sync.py: [n/N] source headers, a 60s heartbeat with new-file counts, and per-source timing, so a healthy paced run no longer looks hung. - gdl-sync@.service now runs run-%i.sh instead of gdl-cron.sh: HC_URL is set in the wrappers, so scheduled runs had never pinged Healthchecks. - Tests for both guards (offline) and the progress helpers.
This commit is contained in:
@@ -343,5 +343,43 @@ class PostUrlsFile(unittest.TestCase):
|
||||
])
|
||||
|
||||
|
||||
class ProgressOutput(unittest.TestCase):
|
||||
"""The heartbeat that stops a healthy paced run (12-20s between requests, no per-file
|
||||
output) from looking hung."""
|
||||
|
||||
def test_elapsed_formatting(self):
|
||||
self.assertEqual(gdl._fmt_elapsed(5), "5s")
|
||||
self.assertEqual(gdl._fmt_elapsed(125), "2m05s")
|
||||
self.assertEqual(gdl._fmt_elapsed(7300), "2h01m")
|
||||
|
||||
def test_count_new_counts_media_written_since_and_ignores_sidecars(self):
|
||||
with tempfile.TemporaryDirectory() as d:
|
||||
root = Path(d)
|
||||
(root / "sub").mkdir()
|
||||
old = root / "old.jpg"
|
||||
old.write_text("x")
|
||||
import os
|
||||
os.utime(old, (1, 1)) # long before `since`
|
||||
(root / "sub" / "new.jpg").write_text("x")
|
||||
(root / "sub" / "new.mp4").write_text("x")
|
||||
for sidecar in ("new.txt", "new.json", "half.jpg.part"):
|
||||
(root / "sub" / sidecar).write_text("x")
|
||||
n, newest = gdl._count_new(root, since=1000)
|
||||
self.assertEqual(n, 2)
|
||||
self.assertIn(newest, ("new.jpg", "new.mp4"))
|
||||
|
||||
def test_heartbeat_prints_while_running_and_stops_cleanly(self):
|
||||
with tempfile.TemporaryDirectory() as d:
|
||||
with mock.patch("builtins.print") as pr:
|
||||
with gdl.Heartbeat("fetching", watch=Path(d), every=0.05) as hb:
|
||||
(Path(d) / "a.jpg").write_text("x")
|
||||
import time
|
||||
time.sleep(0.2)
|
||||
lines = [str(c.args[0]) for c in pr.call_args_list]
|
||||
self.assertTrue(any("fetching" in s and "new file(s) so far" in s for s in lines))
|
||||
self.assertFalse(hb._thread.is_alive())
|
||||
self.assertGreater(hb.elapsed, 0.1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main(verbosity=2)
|
||||
|
||||
Reference in New Issue
Block a user