62 lines
1.9 KiB
Python
62 lines
1.9 KiB
Python
#!/usr/bin/env python3
|
|
"""Delete all checked/done items from the Vikunja Groceries list.
|
|
Scheduled monthly as a cron job to prevent accumulation of thousands of done items."""
|
|
|
|
import json
|
|
import os
|
|
import sys
|
|
import time
|
|
import urllib.error
|
|
import urllib.request
|
|
|
|
TOKEN = os.environ.get("VIKUNJA_TOKEN", "tk_e05df0fdc7a88073150c732d8fe169a3d190084b")
|
|
BASE = os.environ.get("VIKUNJA_BASE", "http://192.168.68.148:3456/api/v1")
|
|
PROJECT_ID = int(os.environ.get("VIKUNJA_GROCERIES_PROJECT", "5"))
|
|
|
|
def main():
|
|
all_tasks = []
|
|
page = 1
|
|
while True:
|
|
req = urllib.request.Request(
|
|
f"{BASE}/projects/{PROJECT_ID}/tasks?per_page=50&page={page}"
|
|
)
|
|
req.add_header("Authorization", f"Bearer {TOKEN}")
|
|
with urllib.request.urlopen(req, timeout=15) as r:
|
|
batch = json.loads(r.read())
|
|
if not batch:
|
|
break
|
|
all_tasks.extend(batch)
|
|
if len(batch) < 50:
|
|
break
|
|
page += 1
|
|
if page > 200:
|
|
break
|
|
|
|
done = [t for t in all_tasks if t.get("done")]
|
|
if not done:
|
|
print("No checked items to delete. Clean list.")
|
|
return
|
|
|
|
done_ids = [t["id"] for t in done]
|
|
deleted = 0
|
|
errors = []
|
|
for tid in done_ids:
|
|
time.sleep(0.05)
|
|
del_req = urllib.request.Request(f"{BASE}/tasks/{tid}", method="DELETE")
|
|
del_req.add_header("Authorization", f"Bearer {TOKEN}")
|
|
try:
|
|
with urllib.request.urlopen(del_req, timeout=10):
|
|
pass
|
|
deleted += 1
|
|
except urllib.error.HTTPError as e:
|
|
errors.append({"id": tid, "code": e.code})
|
|
|
|
print(f"Cleaned {deleted} checked item(s) from Groceries list.")
|
|
if errors:
|
|
print(f"Errors: {len(errors)}")
|
|
for e in errors[:5]:
|
|
print(f" Task {e['id']}: HTTP {e['code']}")
|
|
sys.exit(1 if errors else 0)
|
|
|
|
if __name__ == "__main__":
|
|
main() |