Personal noctalia plugins collection
1#!/usr/bin/env python3
2"""Create a VTODO item via Evolution Data Server."""
3
4import argparse
5import json
6import sys
7from datetime import datetime, timezone
8
9import gi
10gi.require_version("ECal", "2.0")
11gi.require_version("EDataServer", "1.2")
12gi.require_version("ICalGLib", "3.0")
13from gi.repository import ECal, EDataServer, ICalGLib
14
15
16def find_task_source(registry, task_list_uid):
17 source = registry.ref_source(task_list_uid)
18 if source and source.has_extension(EDataServer.SOURCE_EXTENSION_TASK_LIST):
19 return source
20 for src in registry.list_sources(EDataServer.SOURCE_EXTENSION_TASK_LIST):
21 if src.get_display_name() == task_list_uid or src.get_uid() == task_list_uid:
22 return src
23 return None
24
25
26def make_ical_datetime(timestamp):
27 dt = datetime.fromtimestamp(timestamp, tz=timezone.utc).astimezone()
28 ical_time = ICalGLib.Time.new_null_time()
29 ical_time.set_date(dt.year, dt.month, dt.day)
30 ical_time.set_time(dt.hour, dt.minute, dt.second)
31 tz_id = dt.strftime("%Z")
32 builtin_tz = ICalGLib.Timezone.get_builtin_timezone(tz_id)
33 if builtin_tz:
34 ical_time.set_timezone(builtin_tz)
35 else:
36 ical_time.set_timezone(ICalGLib.Timezone.get_utc_timezone())
37 return ical_time
38
39
40def main():
41 parser = argparse.ArgumentParser(description="Create EDS VTODO item")
42 parser.add_argument("--task-list", required=True, help="Task list UID")
43 parser.add_argument("--summary", required=True, help="Task summary")
44 parser.add_argument("--due", type=int, default=0, help="Due date (UNIX timestamp)")
45 parser.add_argument("--priority", type=int, default=0, help="Priority (0-9)")
46 parser.add_argument("--description", default="", help="Task description")
47 args = parser.parse_args()
48
49 try:
50 registry = EDataServer.SourceRegistry.new_sync(None)
51 source = find_task_source(registry, args.task_list)
52 if not source:
53 print(json.dumps({"success": False, "error": f"Task list not found: {args.task_list}"}))
54 sys.exit(1)
55
56 client = ECal.Client.connect_sync(
57 source, ECal.ClientSourceType.TASKS, 1, None
58 )
59
60 comp = ICalGLib.Component.new(ICalGLib.ComponentKind.VTODO_COMPONENT)
61 comp.set_summary(args.summary)
62 comp.set_status(ICalGLib.PropertyStatus.NEEDSACTION)
63
64 if args.due > 0:
65 comp.set_due(make_ical_datetime(args.due))
66
67 if args.priority > 0:
68 prop = ICalGLib.Property.new_priority(args.priority)
69 comp.add_property(prop)
70
71 if args.description:
72 comp.set_description(args.description)
73
74 # Set PERCENT-COMPLETE to 0
75 prop = ICalGLib.Property.new_percentcomplete(0)
76 comp.add_property(prop)
77
78 uid = client.create_object_sync(comp, ECal.OperationFlags.NONE, None)
79 print(json.dumps({"success": True, "uid": uid}))
80
81 except Exception as e:
82 print(json.dumps({"success": False, "error": str(e)}))
83 sys.exit(1)
84
85
86if __name__ == "__main__":
87 main()