doingapp 0.7.0__tar.gz → 0.7.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: doingapp
3
- Version: 0.7.0
3
+ Version: 0.7.1
4
4
  Summary: A fast CLI task tracker — track what you're doing from the terminal.
5
5
  Author-email: Parker Grimes <parker@altellus.com>
6
6
  License-Expression: MIT
@@ -1,5 +1,5 @@
1
1
  import os
2
- import time as _time
2
+ from zoneinfo import ZoneInfo, ZoneInfoNotFoundError
3
3
 
4
4
  import httpx
5
5
 
@@ -8,16 +8,35 @@ from doing_cli.auth import load_token
8
8
  BASE_URL = os.environ.get("DOING_API_URL", "https://doingapp.co")
9
9
 
10
10
 
11
- def _local_tz() -> str:
11
+ def _is_iana_tz(name: str) -> bool:
12
12
  try:
13
- # Works on most Unix systems
14
- return os.path.realpath("/etc/localtime").split("zoneinfo/")[1]
13
+ ZoneInfo(name)
14
+ except (ZoneInfoNotFoundError, ValueError):
15
+ return False
16
+ return True
17
+
18
+
19
+ def _local_tz() -> str | None:
20
+ """IANA name of the local timezone, or None if it can't be determined.
21
+
22
+ TZ wins over /etc/localtime, as it does for the OS itself; containers
23
+ commonly set TZ while /etc/localtime still points at UTC. Abbreviations
24
+ like "MST" are never sent: the server would treat them as fixed offsets
25
+ with no DST. When this returns None the server uses the account timezone.
26
+ """
27
+ candidates = []
28
+ if tz := os.environ.get("TZ", "").lstrip(":"):
29
+ candidates.append(tz)
30
+ try:
31
+ candidates.append(os.path.realpath("/etc/localtime").split("zoneinfo/")[1])
15
32
  except (IndexError, OSError):
16
33
  pass
17
- tz = os.environ.get("TZ")
18
- if tz:
19
- return tz
20
- return _time.tzname[0]
34
+ return next((name for name in candidates if _is_iana_tz(name)), None)
35
+
36
+
37
+ def _tz_params() -> dict:
38
+ tz = _local_tz()
39
+ return {"tz": tz} if tz else {}
21
40
 
22
41
 
23
42
  def _client() -> httpx.Client:
@@ -61,7 +80,7 @@ def create_task(title: str, notes: str | None = None, context_id: int | None = N
61
80
  if recurrence is not None:
62
81
  payload["recurrence"] = recurrence
63
82
  with _client() as c:
64
- r = c.post("/tasks", json=payload, params={"tz": _local_tz()})
83
+ r = c.post("/tasks", json=payload, params=_tz_params())
65
84
  r.raise_for_status()
66
85
  return r.json()
67
86
 
@@ -75,7 +94,7 @@ def get_task(task_id: int) -> dict:
75
94
 
76
95
  def list_tasks(status: str | None = None, date: str | None = None,
77
96
  context_id: int | None = None) -> list[dict]:
78
- params: dict = {"tz": _local_tz()}
97
+ params: dict = _tz_params()
79
98
  if status is not None:
80
99
  params["status"] = status
81
100
  if date is not None:
@@ -90,7 +109,7 @@ def list_tasks(status: str | None = None, date: str | None = None,
90
109
 
91
110
  def mark_done(task_id: int) -> dict:
92
111
  with _client() as c:
93
- r = c.post(f"/tasks/{task_id}/done", params={"tz": _local_tz()})
112
+ r = c.post(f"/tasks/{task_id}/done", params=_tz_params())
94
113
  r.raise_for_status()
95
114
  return r.json()
96
115
 
@@ -138,7 +157,7 @@ def update_task(task_id: int, title: str | None = None, notes: str | None = None
138
157
  elif recurrence is not None:
139
158
  payload["recurrence"] = recurrence
140
159
  with _client() as c:
141
- r = c.patch(f"/tasks/{task_id}", json=payload, params={"tz": _local_tz()})
160
+ r = c.patch(f"/tasks/{task_id}", json=payload, params=_tz_params())
142
161
  r.raise_for_status()
143
162
  return r.json()
144
163
 
@@ -146,7 +165,7 @@ def update_task(task_id: int, title: str | None = None, notes: str | None = None
146
165
  def snooze_task(task_id: int, minutes: int | None = None, preset: str | None = None) -> dict:
147
166
  payload: dict = {"minutes": minutes} if minutes is not None else {"preset": preset}
148
167
  with _client() as c:
149
- r = c.post(f"/tasks/{task_id}/snooze", json=payload, params={"tz": _local_tz()})
168
+ r = c.post(f"/tasks/{task_id}/snooze", json=payload, params=_tz_params())
150
169
  r.raise_for_status()
151
170
  return r.json()
152
171
 
@@ -158,7 +177,7 @@ def delete_task(task_id: int) -> None:
158
177
 
159
178
 
160
179
  def get_stats(context_id: int | None = None) -> dict:
161
- params: dict = {"tz": _local_tz()}
180
+ params: dict = _tz_params()
162
181
  if context_id is not None:
163
182
  params["context_id"] = context_id
164
183
  with _client() as c:
@@ -169,7 +188,7 @@ def get_stats(context_id: int | None = None) -> dict:
169
188
 
170
189
  def get_done_history(limit: int = 7, before: str | None = None,
171
190
  context_id: int | None = None) -> dict:
172
- params: dict = {"tz": _local_tz(), "limit": limit}
191
+ params: dict = {**_tz_params(), "limit": limit}
173
192
  if before is not None:
174
193
  params["before"] = before
175
194
  if context_id is not None:
@@ -181,7 +200,7 @@ def get_done_history(limit: int = 7, before: str | None = None,
181
200
 
182
201
 
183
202
  def get_today(context_id: int | None = None) -> dict:
184
- params: dict = {"tz": _local_tz()}
203
+ params: dict = _tz_params()
185
204
  if context_id is not None:
186
205
  params["context_id"] = context_id
187
206
  with _client() as c:
@@ -225,7 +244,7 @@ def update_context(context_id: int, name: str, icon: str | None = None) -> dict:
225
244
 
226
245
 
227
246
  def snooze_context(context_id: int) -> dict:
228
- params: dict = {"tz": _local_tz()}
247
+ params: dict = _tz_params()
229
248
  with _client() as c:
230
249
  r = c.post(f"/contexts/{context_id}/snooze", params=params)
231
250
  r.raise_for_status()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: doingapp
3
- Version: 0.7.0
3
+ Version: 0.7.1
4
4
  Summary: A fast CLI task tracker — track what you're doing from the terminal.
5
5
  Author-email: Parker Grimes <parker@altellus.com>
6
6
  License-Expression: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "doingapp"
7
- version = "0.7.0"
7
+ version = "0.7.1"
8
8
  description = "A fast CLI task tracker — track what you're doing from the terminal."
9
9
  readme = "README.md"
10
10
  license = "MIT"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes