diff --git a/CHANGELOG.md b/CHANGELOG.md index 9df746c..202c38b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,19 @@ # iCalendar Timeseries Server Changelog + +## Version 0.4.1 + +### Changes + + +- Fix todo sorting by due date. +- Update README regarding `todo` time series. + + + + + ## Version 0.4.0 diff --git a/README.md b/README.md index 60a5fe6..b3af7e8 100644 --- a/README.md +++ b/README.md @@ -168,6 +168,12 @@ In addition, PromQL label filters can be used. event{calendar="public",foo=~".*"} ``` +Alongside with events, todos are exported in a second time series: + +``` +todo{status!="COMPLETED"} +``` + ## Why Prometheus API - It's JSON. A JSON generator is builtin in Python, so no further dependency. diff --git a/icalendar_timeseries_server/api.py b/icalendar_timeseries_server/api.py index fbfd60d..694a467 100644 --- a/icalendar_timeseries_server/api.py +++ b/icalendar_timeseries_server/api.py @@ -38,9 +38,8 @@ def prometheus_api(): elif q.name == 'todo': events.extend(get_calendar_todos(name)) events = list(filter(q, events)) - [print(e.name, e.due, e.priority) for e in events] # Sort by due date and priority - events.sort(key=lambda e: (e.due, e.priority)) + events.sort(key=lambda e: (e.due is None, e.due, e.priority)) response = { 'status': 'success', 'data': { diff --git a/icalendar_timeseries_server/todo.py b/icalendar_timeseries_server/todo.py index 64ad7ad..ff5e403 100644 --- a/icalendar_timeseries_server/todo.py +++ b/icalendar_timeseries_server/todo.py @@ -2,7 +2,7 @@ from typing import Any, Dict, List import icalendar import jinja2 -from datetime import datetime, timedelta +from datetime import datetime, date, timedelta from icalendar_timeseries_server.config import get_config, get_jenv from icalendar_timeseries_server.query import Metric @@ -18,7 +18,6 @@ _ATTRIBUTES: List[str] = [ 'status', 'summary', 'url', - 'due', 'attach' ] @@ -28,6 +27,15 @@ class Todo(Metric): def __init__(self, cname: str, todo: icalendar.cal.Todo, start: datetime, end: datetime): self.calendar: str = cname self.start = start + due = todo.get('due', None) + if due: + if isinstance(due.dt, datetime): + self.due = due.dt + elif isinstance(due.dt, date): + self.due = datetime.combine(due.dt, datetime.min.time()) + self.due = self.due.replace(tzinfo=get_config().tz) + else: + self.due = None # self.attributes: Dict[str, str] = dict() attributes: Dict[str, str] = dict() tmp: Dict[str, Any] = { @@ -35,6 +43,8 @@ class Todo(Metric): 'start': start, 'end': end } + if self.due: + tmp['due'] = str(self.due) for attr in _ATTRIBUTES: tmp[attr] = todo.get(attr, '') substitution_keys = set(_ATTRIBUTES) @@ -49,11 +59,6 @@ class Todo(Metric): newvalue: str = jtemplate.render(**tmp) attributes[newkey] = newvalue self.uid: str = f'{cname}-{start.strftime("%Y%m%dT%H%M%S%Z")}' - due = todo.get('due', None) - if due: - self.due = due.dt - else: - self.due = datetime.now(get_config().tz) + timedelta(days=36500) self.priority = todo.get('priority', '0') super().__init__('todo', attributes)