altadesk-task-analytics 1.0.0__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.
@@ -0,0 +1,17 @@
1
+ Metadata-Version: 2.4
2
+ Name: altadesk-task-analytics
3
+ Version: 1.0.0
4
+ Summary: A task analytics library for AltaDesk cloud task management system
5
+ Author: X23219505
6
+ Author-email: x23219505@student.ncirl.ie
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: Operating System :: OS Independent
9
+ Requires-Python: >=3.8
10
+ Dynamic: author
11
+ Dynamic: author-email
12
+ Dynamic: classifier
13
+ Dynamic: description
14
+ Dynamic: requires-python
15
+ Dynamic: summary
16
+
17
+ A custom Python library that provides task prioritisation, deadline tracking and analytics calculations for the AltaDesk cloud-based task management system.
@@ -0,0 +1,14 @@
1
+ # AltaDesk Task Analytics
2
+
3
+ A custom Python library for task prioritisation, deadline tracking and analytics.
4
+
5
+ ## Installation
6
+
7
+ pip install altadesk-task-analytics
8
+
9
+ ## Usage
10
+
11
+ from altadesk_task_analytics import TaskAnalytics
12
+
13
+ analytics = TaskAnalytics(tasks)
14
+ report = analytics.generate_report()
@@ -0,0 +1,4 @@
1
+ from .task_analytics import TaskAnalytics
2
+
3
+ __version__ = "1.0.0"
4
+ __author__ = "X23219505"
@@ -0,0 +1,134 @@
1
+ from datetime import datetime, timezone, date
2
+ from typing import List, Dict, Any, Optional
3
+ import logging
4
+
5
+ logger = logging.getLogger(__name__)
6
+
7
+ # Priority weights used for score calculation
8
+ PRIORITY_WEIGHT = {"high": 3, "medium": 2, "low": 1}
9
+ URGENCY_THRESHOLD_DAYS = 3
10
+
11
+
12
+ class TaskAnalytics:
13
+
14
+ def __init__(self, tasks: List[Dict[str, Any]]):
15
+ if not isinstance(tasks, list):
16
+ raise TypeError("tasks must be a list of dicts")
17
+ self._tasks = tasks
18
+ self._today = date.today()
19
+
20
+ def get_priority_score(self, task_id: str) -> Optional[float]:
21
+ # Combines priority weight with urgency multiplier
22
+ task = self._find_task(task_id)
23
+ if task is None:
24
+ return None
25
+ base = PRIORITY_WEIGHT.get(task.get("priority", "low"), 1)
26
+ urgency = self._urgency_multiplier(task.get("deadline", ""))
27
+ return round(base * urgency, 2)
28
+
29
+ def get_sorted_tasks(self) -> List[Dict[str, Any]]:
30
+ # Returns tasks sorted by highest priority score first
31
+ def sort_key(task):
32
+ base = PRIORITY_WEIGHT.get(task.get("priority", "low"), 1)
33
+ urgency = self._urgency_multiplier(task.get("deadline", ""))
34
+ return base * urgency
35
+ return sorted(self._tasks, key=sort_key, reverse=True)
36
+
37
+ def get_overdue_tasks(self) -> List[Dict[str, Any]]:
38
+ # Returns tasks past their deadline that are not done
39
+ overdue = []
40
+ for task in self._tasks:
41
+ if task.get("status") == "done":
42
+ continue
43
+ days = self._days_remaining(task.get("deadline", ""))
44
+ if days is not None and days < 0:
45
+ overdue.append(task)
46
+ return overdue
47
+
48
+ def get_upcoming_tasks(self, within_days: int = 7) -> List[Dict[str, Any]]:
49
+ # Returns tasks due within the specified number of days
50
+ upcoming = []
51
+ for task in self._tasks:
52
+ if task.get("status") == "done":
53
+ continue
54
+ days = self._days_remaining(task.get("deadline", ""))
55
+ if days is not None and 0 <= days <= within_days:
56
+ upcoming.append({**task, "_days_remaining": days})
57
+ upcoming.sort(key=lambda t: t["_days_remaining"])
58
+ return upcoming
59
+
60
+ def generate_report(self) -> Dict[str, Any]:
61
+ # Generates a full analytics summary for the dashboard
62
+ total = len(self._tasks)
63
+
64
+ by_status = {"todo": 0, "in_progress": 0, "done": 0}
65
+ for task in self._tasks:
66
+ status = task.get("status", "todo")
67
+ by_status[status] = by_status.get(status, 0) + 1
68
+
69
+ by_priority = {"high": 0, "medium": 0, "low": 0}
70
+ for task in self._tasks:
71
+ p = task.get("priority", "low")
72
+ by_priority[p] = by_priority.get(p, 0) + 1
73
+
74
+ overdue = self.get_overdue_tasks()
75
+ done_count = by_status.get("done", 0)
76
+ completion_rate = round((done_count / total * 100), 1) if total else 0.0
77
+
78
+ scores = [self.get_priority_score(t["task_id"]) for t in self._tasks
79
+ if self.get_priority_score(t["task_id"]) is not None]
80
+ avg_score = round(sum(scores) / len(scores), 2) if scores else 0.0
81
+
82
+ return {
83
+ "total": total,
84
+ "by_status": by_status,
85
+ "by_priority": by_priority,
86
+ "overdue_count": len(overdue),
87
+ "completion_rate": completion_rate,
88
+ "avg_priority_score": avg_score,
89
+ "upcoming_7days": self.get_upcoming_tasks(within_days=7),
90
+ "generated_at": datetime.now(timezone.utc).isoformat(),
91
+ }
92
+
93
+ @staticmethod
94
+ def is_urgent(task: Dict[str, Any]) -> bool:
95
+ if task.get("status") == "done":
96
+ return False
97
+ days = TaskAnalytics._days_remaining_static(task.get("deadline", ""))
98
+ if days is None:
99
+ return False
100
+ return days <= URGENCY_THRESHOLD_DAYS
101
+
102
+ @classmethod
103
+ def from_raw_scan(cls, scan_response: Dict) -> "TaskAnalytics":
104
+ items = scan_response.get("Items", [])
105
+ return cls(items)
106
+
107
+ def _find_task(self, task_id: str) -> Optional[Dict[str, Any]]:
108
+ for task in self._tasks:
109
+ if task.get("task_id") == task_id:
110
+ return task
111
+ return None
112
+
113
+ def _days_remaining(self, deadline_str: str) -> Optional[int]:
114
+ return TaskAnalytics._days_remaining_static(deadline_str)
115
+
116
+ @staticmethod
117
+ def _days_remaining_static(deadline_str: str) -> Optional[int]:
118
+ if not deadline_str:
119
+ return None
120
+ try:
121
+ deadline_date = date.fromisoformat(deadline_str[:10])
122
+ return (deadline_date - date.today()).days
123
+ except ValueError:
124
+ return None
125
+
126
+ def _urgency_multiplier(self, deadline_str: str) -> float:
127
+ # Multiplier increases as deadline approaches
128
+ days = self._days_remaining(deadline_str)
129
+ if days is None: return 1.0
130
+ if days < 0: return 3.0
131
+ if days <= 3: return 2.5
132
+ if days <= 7: return 2.0
133
+ if days <= 14: return 1.5
134
+ return 1.0
@@ -0,0 +1,17 @@
1
+ Metadata-Version: 2.4
2
+ Name: altadesk-task-analytics
3
+ Version: 1.0.0
4
+ Summary: A task analytics library for AltaDesk cloud task management system
5
+ Author: X23219505
6
+ Author-email: x23219505@student.ncirl.ie
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: Operating System :: OS Independent
9
+ Requires-Python: >=3.8
10
+ Dynamic: author
11
+ Dynamic: author-email
12
+ Dynamic: classifier
13
+ Dynamic: description
14
+ Dynamic: requires-python
15
+ Dynamic: summary
16
+
17
+ A custom Python library that provides task prioritisation, deadline tracking and analytics calculations for the AltaDesk cloud-based task management system.
@@ -0,0 +1,8 @@
1
+ README.md
2
+ setup.py
3
+ altadesk_task_analytics/__init__.py
4
+ altadesk_task_analytics/task_analytics.py
5
+ altadesk_task_analytics.egg-info/PKG-INFO
6
+ altadesk_task_analytics.egg-info/SOURCES.txt
7
+ altadesk_task_analytics.egg-info/dependency_links.txt
8
+ altadesk_task_analytics.egg-info/top_level.txt
@@ -0,0 +1 @@
1
+ altadesk_task_analytics
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,16 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ setup(
4
+ name="altadesk-task-analytics",
5
+ version="1.0.0",
6
+ author="X23219505",
7
+ author_email="x23219505@student.ncirl.ie",
8
+ description="A task analytics library for AltaDesk cloud task management system",
9
+ long_description="A custom Python library that provides task prioritisation, deadline tracking and analytics calculations for the AltaDesk cloud-based task management system.",
10
+ packages=find_packages(),
11
+ python_requires=">=3.8",
12
+ classifiers=[
13
+ "Programming Language :: Python :: 3",
14
+ "Operating System :: OS Independent",
15
+ ],
16
+ )