install_system_cron.py 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. #!/usr/bin/env python3
  2. """Install or remove a system cron entry for RobotDaily."""
  3. from __future__ import annotations
  4. import argparse
  5. import subprocess
  6. from pathlib import Path
  7. from utils import SKILL_DIR, log
  8. MARKER = "# robotdaily-arxiv-digest"
  9. def read_crontab() -> str:
  10. result = subprocess.run(["crontab", "-l"], capture_output=True, text=True, check=False)
  11. if result.returncode != 0:
  12. return ""
  13. return result.stdout
  14. def write_crontab(content: str) -> None:
  15. result = subprocess.run(["crontab", "-"], input=content, text=True, check=False)
  16. if result.returncode != 0:
  17. raise SystemExit("Failed to write crontab")
  18. def build_line(python_bin: str) -> str:
  19. skill_dir = SKILL_DIR
  20. log_dir = skill_dir / "logs"
  21. log_file = log_dir / "robotdaily.log"
  22. return (
  23. f"30 10 * * * mkdir -p {log_dir} && cd {skill_dir} && "
  24. f"{python_bin} scripts/run_daily.py --publish-discord >> {log_file} 2>&1 {MARKER}"
  25. )
  26. def main() -> None:
  27. parser = argparse.ArgumentParser(description="Install RobotDaily daily cron")
  28. parser.add_argument("--python-bin", default="python3")
  29. parser.add_argument("--remove", action="store_true")
  30. args = parser.parse_args()
  31. existing_lines = [line for line in read_crontab().splitlines() if MARKER not in line]
  32. if args.remove:
  33. write_crontab("\n".join(existing_lines) + ("\n" if existing_lines else ""))
  34. log("Removed RobotDaily cron entry")
  35. return
  36. existing_lines.append(build_line(args.python_bin))
  37. write_crontab("\n".join(existing_lines) + "\n")
  38. log("Installed RobotDaily cron entry for 10:30 Asia/Shanghai")
  39. if __name__ == "__main__":
  40. main()