taskcheck 0.3.2__tar.gz → 0.3.2.post2__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.1
2
2
  Name: taskcheck
3
- Version: 0.3.2
3
+ Version: 0.3.2.post2
4
4
  Summary: Automatic scheduler for taskwarrior
5
5
  Requires-Python: >=3.11
6
6
  Description-Content-Type: text/markdown
@@ -144,3 +144,7 @@ additional_attributes_unplanned = ["due", "urgency"] # additional attributes to
144
144
  -i, --install: install taskcheck configuration
145
145
  -r, --report: show tasks planned until a certain time
146
146
  ```
147
+
148
+ ## TODO
149
+
150
+ - [ ] Consider due dates are nearer while planning in the future
@@ -131,3 +131,7 @@ additional_attributes_unplanned = ["due", "urgency"] # additional attributes to
131
131
  -i, --install: install taskcheck configuration
132
132
  -r, --report: show tasks planned until a certain time
133
133
  ```
134
+
135
+ ## TODO
136
+
137
+ - [ ] Consider due dates are nearer while planning in the future
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "taskcheck"
3
- version = "0.3.2"
3
+ version = "0.3.2-2"
4
4
  description = "Automatic scheduler for taskwarrior"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -2,7 +2,6 @@ import tomllib
2
2
  import argparse
3
3
 
4
4
  from taskcheck.parallel import check_tasks_parallel
5
- from taskcheck.sequential import check_tasks_sequentially
6
5
  from taskcheck.common import config_dir
7
6
 
8
7
  arg_parser = argparse.ArgumentParser()
@@ -64,9 +64,7 @@ def compute_estimated_urgency(remaining_hours, urgency_coefficients):
64
64
  key=lambda x: abs(pdth_to_hours(x) - remaining_hours),
65
65
  )
66
66
  coefficient = urgency_coefficients.estimated[closest_match]
67
- # Compute the urgency
68
- estimated_urgency = coefficient * remaining_hours
69
- return estimated_urgency
67
+ return coefficient
70
68
 
71
69
 
72
70
  def check_tasks_parallel(config, verbose=False):
@@ -82,10 +80,7 @@ def check_tasks_parallel(config, verbose=False):
82
80
  )
83
81
 
84
82
  for day_offset in range(days_ahead):
85
- date = today + timedelta(days=day_offset)
86
- allocate_time_for_day(
87
- task_info, day_offset, date, urgency_coefficients, verbose
88
- )
83
+ allocate_time_for_day(task_info, day_offset, urgency_coefficients, verbose)
89
84
 
90
85
  update_tasks_with_scheduling_info(task_info, verbose)
91
86
 
@@ -120,10 +115,11 @@ def initialize_task_info(tasks, time_maps, days_ahead, urgency_coefficients, cal
120
115
  return task_info
121
116
 
122
117
 
123
- def allocate_time_for_day(task_info, day_offset, date, urgency_coefficients, verbose):
118
+ def allocate_time_for_day(task_info, day_offset, urgency_coefficients, verbose):
119
+ date = datetime.today().date() + timedelta(days=day_offset)
124
120
  total_available_hours = compute_total_available_hours(task_info, day_offset)
125
- if verbose:
126
- print(f"Day {date}, total available hours: {total_available_hours:.2f}")
121
+ # if verbose:
122
+ # print(f"Day {date}, total available hours: {total_available_hours:.2f}")
127
123
  if total_available_hours <= 0:
128
124
  return
129
125
 
@@ -134,7 +130,7 @@ def allocate_time_for_day(task_info, day_offset, date, urgency_coefficients, ver
134
130
  recompute_urgencies(tasks_remaining, urgency_coefficients)
135
131
  sorted_task_ids = sorted(
136
132
  tasks_remaining.keys(),
137
- key=lambda x: (tasks_remaining[x]["urgency"], x),
133
+ key=lambda x: tasks_remaining[x]["urgency"],
138
134
  reverse=True,
139
135
  )
140
136
 
@@ -146,6 +142,23 @@ def allocate_time_for_day(task_info, day_offset, date, urgency_coefficients, ver
146
142
  info = tasks_remaining[uuid]
147
143
  if any(d in tasks_remaining for d in info["task"].get("depends", [])):
148
144
  # cannot execute this task until all its dependencies are completed
145
+ if verbose:
146
+ print(
147
+ "Skipping task",
148
+ info["task"]["id"],
149
+ "due to dependency on:",
150
+ [
151
+ tasks_remaining[_d]["task"]["id"]
152
+ for _d in info["task"].get("depends", [])
153
+ if _d in tasks_remaining
154
+ ],
155
+ )
156
+ continue
157
+
158
+ wait = info["task"].get("wait")
159
+ if wait and date <= datetime.strptime(wait, "%Y%m%dT%H%M%SZ").date():
160
+ if verbose:
161
+ print(f"Skipping task {info['task']['id']} due to wait date {wait}")
149
162
  continue
150
163
  allocation = allocate_time_to_task(info, day_offset, day_remaining_hours)
151
164
  if allocation > 0:
@@ -155,7 +168,7 @@ def allocate_time_for_day(task_info, day_offset, date, urgency_coefficients, ver
155
168
  update_task_scheduling(info, allocation, date_str)
156
169
  if verbose:
157
170
  print(
158
- f"Allocated {allocation:.2f} hours to task {info['task']['id']} on {date}"
171
+ f"Allocated {allocation:.2f} hours to task {info['task']['id']} on {date} with urgency {info['urgency']:.2f} and estimated-related urgency {info['estimated_urgency']:.2f}"
159
172
  )
160
173
  if (
161
174
  info["remaining_hours"] <= 0
@@ -166,8 +179,8 @@ def allocate_time_for_day(task_info, day_offset, date, urgency_coefficients, ver
166
179
  break
167
180
  if not allocated:
168
181
  break
169
- if verbose and day_remaining_hours > 0:
170
- print(f"Unused time on {date}: {day_remaining_hours:.2f} hours")
182
+ # if verbose and day_remaining_hours > 0:
183
+ # print(f"Unused time on {date}: {day_remaining_hours:.2f} hours")
171
184
 
172
185
 
173
186
  def compute_total_available_hours(task_info, day_offset):
@@ -207,8 +220,17 @@ def recompute_urgencies(tasks_remaining, urgency_coefficients):
207
220
  if started_by_scheduler and not started_by_user:
208
221
  # If the task was started by the scheduler, apply the active task coefficient
209
222
  info["urgency"] += urgency_coefficients.active
223
+ info["started"] = False
210
224
 
211
225
  if urgency_coefficients.inherit:
226
+ # Build reverse dependencies mapping
227
+ reverse_deps = {} # Map from task_uuid to list of tasks that depend on it
228
+ for task_uuid, info in tasks_remaining.items():
229
+ for dep_uuid in info["task"].get("depends", []):
230
+ if dep_uuid not in reverse_deps:
231
+ reverse_deps[dep_uuid] = []
232
+ reverse_deps[dep_uuid].append(task_uuid)
233
+
212
234
  # Define a recursive function to compute the maximum urgency
213
235
  def get_max_urgency(info, visited):
214
236
  task_uuid = info["task"]["uuid"]
@@ -217,8 +239,8 @@ def recompute_urgencies(tasks_remaining, urgency_coefficients):
217
239
  # Start with the current task's urgency
218
240
  urgency = info["urgency"]
219
241
  visited[task_uuid] = urgency # Mark as visited
220
- # Recursively compute urgencies of dependents
221
- for dep_uuid in info["task"].get("depends", []):
242
+ # Recursively compute urgencies of tasks that depend on this task
243
+ for dep_uuid in reverse_deps.get(task_uuid, []):
222
244
  if dep_uuid in tasks_remaining:
223
245
  dep_info = tasks_remaining[dep_uuid]
224
246
  dep_urgency = get_max_urgency(dep_info, visited)
@@ -226,7 +248,7 @@ def recompute_urgencies(tasks_remaining, urgency_coefficients):
226
248
  visited[task_uuid] = urgency # Update with the maximum urgency found
227
249
  return urgency
228
250
 
229
- # Update urgencies based on dependents
251
+ # Update urgencies based on tasks that depend on them
230
252
  for info in tasks_remaining.values():
231
253
  visited = {} # Reset visited dictionary for each task
232
254
  max_urgency = get_max_urgency(info, visited)
@@ -248,9 +270,10 @@ def allocate_time_to_task(info, day_offset, day_remaining_hours):
248
270
  if allocation <= 0.05:
249
271
  return 0
250
272
 
273
+ if info["remaining_hours"] == info["task"]["estimated"]:
274
+ info["started"] = True
251
275
  info["remaining_hours"] -= allocation
252
276
  info["task_time_map"][day_offset] -= allocation
253
- info["started"] = True
254
277
 
255
278
  return allocation
256
279
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: taskcheck
3
- Version: 0.3.2
3
+ Version: 0.3.2.post2
4
4
  Summary: Automatic scheduler for taskwarrior
5
5
  Requires-Python: >=3.11
6
6
  Description-Content-Type: text/markdown
@@ -144,3 +144,7 @@ additional_attributes_unplanned = ["due", "urgency"] # additional attributes to
144
144
  -i, --install: install taskcheck configuration
145
145
  -r, --report: show tasks planned until a certain time
146
146
  ```
147
+
148
+ ## TODO
149
+
150
+ - [ ] Consider due dates are nearer while planning in the future
File without changes
File without changes