scriptplan 0.9.0__tar.gz → 0.9.2__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.
Files changed (101) hide show
  1. {scriptplan-0.9.0/scriptplan.egg-info → scriptplan-0.9.2}/PKG-INFO +102 -10
  2. scriptplan-0.9.2/README.md +208 -0
  3. {scriptplan-0.9.0 → scriptplan-0.9.2}/pyproject.toml +31 -7
  4. scriptplan-0.9.2/scriptplan/__init__.py +26 -0
  5. scriptplan-0.9.2/scriptplan/_cython/__init__.py +45 -0
  6. scriptplan-0.9.2/scriptplan/_cython/scoreboard_cy.c +11547 -0
  7. scriptplan-0.9.2/scriptplan/_cython/scoreboard_cy.pyx +174 -0
  8. scriptplan-0.9.2/scriptplan/_cython/time_utils_cy.c +11618 -0
  9. scriptplan-0.9.2/scriptplan/_cython/time_utils_cy.pyx +149 -0
  10. scriptplan-0.9.2/scriptplan/_cython/working_hours_cy.c +11742 -0
  11. scriptplan-0.9.2/scriptplan/_cython/working_hours_cy.pyx +150 -0
  12. scriptplan-0.9.2/scriptplan/cli/__init__.py +7 -0
  13. {scriptplan-0.9.0 → scriptplan-0.9.2}/scriptplan/cli/main.py +133 -135
  14. scriptplan-0.9.2/scriptplan/cli/plan.py +659 -0
  15. {scriptplan-0.9.0 → scriptplan-0.9.2}/scriptplan/core/account.py +48 -40
  16. {scriptplan-0.9.0 → scriptplan-0.9.2}/scriptplan/core/allocation.py +37 -25
  17. {scriptplan-0.9.0 → scriptplan-0.9.2}/scriptplan/core/booking.py +19 -14
  18. scriptplan-0.9.2/scriptplan/core/exceptions.py +319 -0
  19. {scriptplan-0.9.0 → scriptplan-0.9.2}/scriptplan/core/journal.py +74 -53
  20. scriptplan-0.9.2/scriptplan/core/leave.py +17 -0
  21. {scriptplan-0.9.0 → scriptplan-0.9.2}/scriptplan/core/limits.py +64 -49
  22. {scriptplan-0.9.0 → scriptplan-0.9.2}/scriptplan/core/project.py +425 -401
  23. {scriptplan-0.9.0 → scriptplan-0.9.2}/scriptplan/core/property.py +366 -333
  24. {scriptplan-0.9.0 → scriptplan-0.9.2}/scriptplan/core/resource.py +35 -32
  25. {scriptplan-0.9.0 → scriptplan-0.9.2}/scriptplan/core/resource_scenario.py +123 -115
  26. scriptplan-0.9.2/scriptplan/core/scenario.py +11 -0
  27. scriptplan-0.9.2/scriptplan/core/scenario_data.py +66 -0
  28. {scriptplan-0.9.0 → scriptplan-0.9.2}/scriptplan/core/shift.py +28 -19
  29. scriptplan-0.9.2/scriptplan/core/task.py +80 -0
  30. {scriptplan-0.9.0 → scriptplan-0.9.2}/scriptplan/core/task_scenario.py +343 -268
  31. {scriptplan-0.9.0 → scriptplan-0.9.2}/scriptplan/core/timesheet.py +141 -121
  32. {scriptplan-0.9.0 → scriptplan-0.9.2}/scriptplan/core/working_hours.py +50 -26
  33. {scriptplan-0.9.0 → scriptplan-0.9.2}/scriptplan/parser/macro_processor.py +39 -38
  34. scriptplan-0.9.2/scriptplan/parser/tjp_parser.py +1845 -0
  35. {scriptplan-0.9.0 → scriptplan-0.9.2}/scriptplan/report/__init__.py +29 -29
  36. {scriptplan-0.9.0 → scriptplan-0.9.2}/scriptplan/report/report.py +72 -161
  37. {scriptplan-0.9.0 → scriptplan-0.9.2}/scriptplan/report/report_base.py +98 -118
  38. {scriptplan-0.9.0 → scriptplan-0.9.2}/scriptplan/report/report_context.py +32 -32
  39. {scriptplan-0.9.0 → scriptplan-0.9.2}/scriptplan/report/resource_report.py +47 -61
  40. {scriptplan-0.9.0 → scriptplan-0.9.2}/scriptplan/report/table_report.py +188 -224
  41. {scriptplan-0.9.0 → scriptplan-0.9.2}/scriptplan/report/task_report.py +57 -67
  42. {scriptplan-0.9.0 → scriptplan-0.9.2}/scriptplan/report/text_report.py +49 -52
  43. {scriptplan-0.9.0 → scriptplan-0.9.2}/scriptplan/scheduler/batch_processor.py +44 -49
  44. scriptplan-0.9.2/scriptplan/scheduler/scoreboard.py +179 -0
  45. {scriptplan-0.9.0 → scriptplan-0.9.2}/scriptplan/utils/data_cache.py +22 -18
  46. {scriptplan-0.9.0 → scriptplan-0.9.2}/scriptplan/utils/logger.py +39 -36
  47. {scriptplan-0.9.0 → scriptplan-0.9.2}/scriptplan/utils/message_handler.py +229 -155
  48. {scriptplan-0.9.0 → scriptplan-0.9.2}/scriptplan/utils/time.py +79 -66
  49. {scriptplan-0.9.0 → scriptplan-0.9.2/scriptplan.egg-info}/PKG-INFO +102 -10
  50. {scriptplan-0.9.0 → scriptplan-0.9.2}/scriptplan.egg-info/SOURCES.txt +10 -3
  51. {scriptplan-0.9.0 → scriptplan-0.9.2}/scriptplan.egg-info/entry_points.txt +1 -0
  52. {scriptplan-0.9.0 → scriptplan-0.9.2}/scriptplan.egg-info/requires.txt +6 -0
  53. scriptplan-0.9.2/setup.py +66 -0
  54. {scriptplan-0.9.0 → scriptplan-0.9.2}/tests/test_account.py +2 -1
  55. {scriptplan-0.9.0 → scriptplan-0.9.2}/tests/test_attribute_base.py +3 -3
  56. {scriptplan-0.9.0 → scriptplan-0.9.2}/tests/test_batch_processor.py +2 -3
  57. {scriptplan-0.9.0 → scriptplan-0.9.2}/tests/test_cli.py +3 -9
  58. {scriptplan-0.9.0 → scriptplan-0.9.2}/tests/test_core_allocation.py +5 -3
  59. {scriptplan-0.9.0 → scriptplan-0.9.2}/tests/test_core_booking.py +8 -6
  60. {scriptplan-0.9.0 → scriptplan-0.9.2}/tests/test_core_project.py +4 -2
  61. {scriptplan-0.9.0 → scriptplan-0.9.2}/tests/test_core_resource.py +5 -3
  62. {scriptplan-0.9.0 → scriptplan-0.9.2}/tests/test_core_scenario.py +6 -4
  63. {scriptplan-0.9.0 → scriptplan-0.9.2}/tests/test_core_task.py +7 -5
  64. {scriptplan-0.9.0 → scriptplan-0.9.2}/tests/test_journal.py +2 -1
  65. {scriptplan-0.9.0 → scriptplan-0.9.2}/tests/test_logger.py +3 -2
  66. {scriptplan-0.9.0 → scriptplan-0.9.2}/tests/test_macro_processor.py +1 -0
  67. {scriptplan-0.9.0 → scriptplan-0.9.2}/tests/test_message_handler.py +11 -6
  68. {scriptplan-0.9.0 → scriptplan-0.9.2}/tests/test_parser.py +4 -2
  69. {scriptplan-0.9.0 → scriptplan-0.9.2}/tests/test_property_list.py +2 -1
  70. {scriptplan-0.9.0 → scriptplan-0.9.2}/tests/test_property_set.py +7 -6
  71. {scriptplan-0.9.0 → scriptplan-0.9.2}/tests/test_property_tree_node.py +7 -6
  72. {scriptplan-0.9.0 → scriptplan-0.9.2}/tests/test_report.py +77 -57
  73. {scriptplan-0.9.0 → scriptplan-0.9.2}/tests/test_scheduling.py +4 -3
  74. {scriptplan-0.9.0 → scriptplan-0.9.2}/tests/test_scheduling_validation.py +28 -20
  75. {scriptplan-0.9.0 → scriptplan-0.9.2}/tests/test_scoreboard.py +11 -9
  76. {scriptplan-0.9.0 → scriptplan-0.9.2}/tests/test_shift.py +1 -0
  77. {scriptplan-0.9.0 → scriptplan-0.9.2}/tests/test_timesheet.py +2 -1
  78. {scriptplan-0.9.0 → scriptplan-0.9.2}/tests/test_utils_time.py +7 -5
  79. scriptplan-0.9.0/README.md +0 -123
  80. scriptplan-0.9.0/scriptplan/__init__.py +0 -22
  81. scriptplan-0.9.0/scriptplan/cli/__init__.py +0 -7
  82. scriptplan-0.9.0/scriptplan/core/leave.py +0 -14
  83. scriptplan-0.9.0/scriptplan/core/scenario.py +0 -5
  84. scriptplan-0.9.0/scriptplan/core/scenario_data.py +0 -39
  85. scriptplan-0.9.0/scriptplan/core/task.py +0 -77
  86. scriptplan-0.9.0/scriptplan/parser/tjp_parser.py +0 -1904
  87. scriptplan-0.9.0/scriptplan/report/html_generator.py +0 -477
  88. scriptplan-0.9.0/scriptplan/scheduler/scoreboard.py +0 -120
  89. scriptplan-0.9.0/tests/test_html_generator.py +0 -268
  90. scriptplan-0.9.0/tests/test_html_report_integration.py +0 -199
  91. {scriptplan-0.9.0 → scriptplan-0.9.2}/LICENSE +0 -0
  92. {scriptplan-0.9.0 → scriptplan-0.9.2}/MANIFEST.in +0 -0
  93. {scriptplan-0.9.0 → scriptplan-0.9.2}/scriptplan/core/__init__.py +0 -0
  94. {scriptplan-0.9.0 → scriptplan-0.9.2}/scriptplan/parser/__init__.py +0 -0
  95. {scriptplan-0.9.0 → scriptplan-0.9.2}/scriptplan/parser/tjp.lark +0 -0
  96. {scriptplan-0.9.0 → scriptplan-0.9.2}/scriptplan/py.typed +0 -0
  97. {scriptplan-0.9.0 → scriptplan-0.9.2}/scriptplan/scheduler/__init__.py +0 -0
  98. {scriptplan-0.9.0 → scriptplan-0.9.2}/scriptplan/utils/__init__.py +0 -0
  99. {scriptplan-0.9.0 → scriptplan-0.9.2}/scriptplan.egg-info/dependency_links.txt +0 -0
  100. {scriptplan-0.9.0 → scriptplan-0.9.2}/scriptplan.egg-info/top_level.txt +0 -0
  101. {scriptplan-0.9.0 → scriptplan-0.9.2}/setup.cfg +0 -0
@@ -1,14 +1,14 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: scriptplan
3
- Version: 0.9.0
3
+ Version: 0.9.2
4
4
  Summary: A precise project scheduling engine with minute-level accuracy for resource allocation and dependency management.
5
5
  Author-email: Farshid Ashouri <farsheed.ashouri@gmail.com>
6
6
  Maintainer-email: Farshid Ashouri <farsheed.ashouri@gmail.com>
7
7
  License-Expression: Apache-2.0
8
- Project-URL: Homepage, https://github.com/farshidash/scriptplan
9
- Project-URL: Documentation, https://github.com/farshidash/scriptplan#readme
10
- Project-URL: Bug Tracker, https://github.com/farshidash/scriptplan/issues
11
- Project-URL: Source, https://github.com/farshidash/scriptplan
8
+ Project-URL: Homepage, https://github.com/rodmena-limited/scriptplan
9
+ Project-URL: Documentation, https://github.com/rodmena-limited/scriptplan#readme
10
+ Project-URL: Bug Tracker, https://github.com/rodmena-limited/scriptplan/issues
11
+ Project-URL: Source, https://github.com/rodmena-limited/scriptplan
12
12
  Keywords: scheduling,project-management,resource-allocation,gantt,critical-path
13
13
  Classifier: Development Status :: 4 - Beta
14
14
  Classifier: Intended Audience :: Developers
@@ -19,6 +19,7 @@ Classifier: Programming Language :: Python :: 3.10
19
19
  Classifier: Programming Language :: Python :: 3.11
20
20
  Classifier: Programming Language :: Python :: 3.12
21
21
  Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Programming Language :: Python :: 3.14
22
23
  Classifier: Operating System :: OS Independent
23
24
  Classifier: Topic :: Office/Business :: Scheduling
24
25
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
@@ -28,16 +29,32 @@ Description-Content-Type: text/markdown
28
29
  License-File: LICENSE
29
30
  Requires-Dist: lark>=1.0.0
30
31
  Requires-Dist: python-dateutil>=2.8.0
32
+ Requires-Dist: click>=8.0.0
31
33
  Provides-Extra: dev
32
34
  Requires-Dist: pytest>=7.0.0; extra == "dev"
33
35
  Requires-Dist: pytest-xdist>=3.0.0; extra == "dev"
34
36
  Requires-Dist: pandas>=1.5.0; extra == "dev"
37
+ Requires-Dist: types-python-dateutil>=2.8.0; extra == "dev"
38
+ Requires-Dist: types-pytz>=2022.1.0; extra == "dev"
35
39
  Requires-Dist: build; extra == "dev"
36
40
  Requires-Dist: twine; extra == "dev"
41
+ Requires-Dist: ruff>=0.1.0; extra == "dev"
42
+ Requires-Dist: mypy>=1.0.0; extra == "dev"
43
+ Requires-Dist: cython>=3.0.0; extra == "dev"
37
44
  Dynamic: license-file
38
45
 
46
+ <p align="center">
47
+ <img src="https://raw.githubusercontent.com/rodmena-limited/scriptplan/main/icons/logo.svg" alt="ScriptPlan" width="400"/>
48
+ </p>
49
+
39
50
  # ScriptPlan
40
51
 
52
+ ![Logic Certified](https://img.shields.io/badge/Logic-Certified_Airport--Grade-success?style=for-the-badge&logo=github)
53
+ ![Tests Passed](https://img.shields.io/badge/Stress_Tests-24%2F24_Passed-success?style=for-the-badge)
54
+ ![Temporal Physics](https://img.shields.io/badge/Temporal_Physics-Verified-blue?style=for-the-badge)
55
+ ![Scheduling](https://img.shields.io/badge/Scheduling-ALAP_%7C_JIT_%7C_Priority-blueviolet?style=for-the-badge)
56
+ ![Constraints](https://img.shields.io/badge/Constraints-Hard_Limits_%7C_Quotas-orange?style=for-the-badge)
57
+
41
58
  A precise project scheduling engine with minute-level accuracy for resource allocation and dependency management. The syntax is compatible with TaskJuggler (.tjp files).
42
59
 
43
60
  ## Installation
@@ -46,15 +63,59 @@ A precise project scheduling engine with minute-level accuracy for resource allo
46
63
  pip install scriptplan
47
64
  ```
48
65
 
49
- ## Usage
66
+ ## Quick Start
50
67
 
51
- ### Command Line
68
+ ### Report Generation (Unix-style)
52
69
 
53
70
  ```bash
54
- scriptplan project.tjp
55
- scriptplan --output-dir ./reports project.tjp
71
+ # Generate JSON report to stdout
72
+ plan report project.tjp
73
+
74
+ # Generate CSV report
75
+ plan report --csv project.tjp
76
+
77
+ # Save to file
78
+ plan report project.tjp > output.json
79
+ plan report --csv project.tjp > output.csv
80
+
81
+ # Read from stdin
82
+ cat project.tjp | plan report
83
+ plan report - < project.tjp
84
+
85
+ # Pipe to other tools
86
+ plan report project.tjp | jq '.data[0]'
87
+ plan report --csv project.tjp | csvkit
88
+
89
+ # Process multiple files
90
+ for f in projects/*.tjp; do
91
+ plan report "$f" | jq -r '.report_id'
92
+ done
56
93
  ```
57
94
 
95
+ **Output Format** (JSON):
96
+ ```json
97
+ {
98
+ "data": [
99
+ {
100
+ "id": "project.task1",
101
+ "start": "2024-01-01-09:00",
102
+ "end": "2024-01-05-17:00"
103
+ }
104
+ ],
105
+ "columns": ["id", "start", "end"],
106
+ "report_id": "ea3f901dd6426dfa58288d945819c75485fd9ff1875db59def350f219e2d62ca"
107
+ }
108
+ ```
109
+
110
+ **Features**:
111
+ - Output to stdout (Unix philosophy)
112
+ - Messages to stderr
113
+ - SHA256 report_id (content-based hash)
114
+ - Lowercase column names
115
+ - No HTML metadata
116
+ - No file pollution (uses temp directories)
117
+ - Safe for concurrent execution (100+ instances)
118
+
58
119
  ### Python API
59
120
 
60
121
  ```python
@@ -71,6 +132,20 @@ for task in project.tasks:
71
132
  print(f"{task.id}: {start} -> {end}")
72
133
  ```
73
134
 
135
+ ## System Certified
136
+
137
+ **Certification Level**: Airport-Grade / Mission Critical
138
+
139
+ **Capabilities Verified**:
140
+
141
+ - **Temporal Physics**: Floating point precision, Timezones, DST awareness, Date Line crossing.
142
+
143
+ - **Resource Constraints**: Daily/Weekly limits, Hierarchical quotas, Shift intersections.
144
+
145
+ - **Advanced Scheduling**: ALAP (Backward pass), Priority preemption, Smart Resource Selection (Failover).
146
+
147
+ - **Workflow Logic**: Atomicity (Contiguous), Perishability (Max Gap), Zero-Buffer Synchronization.
148
+
74
149
  ## Features
75
150
 
76
151
  - Minute-level scheduling precision
@@ -158,4 +233,21 @@ delivery.assemble_b: 2025-07-16-08:00 -> 2025-07-17-16:00
158
233
 
159
234
  ## License
160
235
 
161
- Apache 2.0
236
+ Apache-2.0
237
+
238
+ ## Acknowledgments
239
+
240
+ ScriptPlan references [TaskJuggler](https://taskjuggler.org/) solely for **file format compatibility**. We have not used, modified, or copied any TaskJuggler source code. ScriptPlan is an independent, clean-room implementation.
241
+
242
+ - The `.tjp` file format is documented publicly and widely used in the project management community
243
+ - All scheduling algorithms, parser, and report generation in ScriptPlan are original implementations
244
+ - TaskJuggler is mentioned only to indicate that ScriptPlan can read the same project file format
245
+
246
+ If you're looking for the original TaskJuggler with its full feature set including interactive HTML reports and GUI tools, please visit [taskjuggler.org](https://taskjuggler.org/).
247
+
248
+ ## Why ScriptPlan?
249
+
250
+ This scheduler is part of Highway Workflow Engine's worker capacity management system. I decided to open-source it for the community to benefit from its precise scheduling capabilities. Thanks to TaskJuggler's established syntax, users can easily adopt ScriptPlan without learning a new format.
251
+
252
+ Yours,
253
+ Farshid.
@@ -0,0 +1,208 @@
1
+ <p align="center">
2
+ <img src="https://raw.githubusercontent.com/rodmena-limited/scriptplan/main/icons/logo.svg" alt="ScriptPlan" width="400"/>
3
+ </p>
4
+
5
+ # ScriptPlan
6
+
7
+ ![Logic Certified](https://img.shields.io/badge/Logic-Certified_Airport--Grade-success?style=for-the-badge&logo=github)
8
+ ![Tests Passed](https://img.shields.io/badge/Stress_Tests-24%2F24_Passed-success?style=for-the-badge)
9
+ ![Temporal Physics](https://img.shields.io/badge/Temporal_Physics-Verified-blue?style=for-the-badge)
10
+ ![Scheduling](https://img.shields.io/badge/Scheduling-ALAP_%7C_JIT_%7C_Priority-blueviolet?style=for-the-badge)
11
+ ![Constraints](https://img.shields.io/badge/Constraints-Hard_Limits_%7C_Quotas-orange?style=for-the-badge)
12
+
13
+ A precise project scheduling engine with minute-level accuracy for resource allocation and dependency management. The syntax is compatible with TaskJuggler (.tjp files).
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ pip install scriptplan
19
+ ```
20
+
21
+ ## Quick Start
22
+
23
+ ### Report Generation (Unix-style)
24
+
25
+ ```bash
26
+ # Generate JSON report to stdout
27
+ plan report project.tjp
28
+
29
+ # Generate CSV report
30
+ plan report --csv project.tjp
31
+
32
+ # Save to file
33
+ plan report project.tjp > output.json
34
+ plan report --csv project.tjp > output.csv
35
+
36
+ # Read from stdin
37
+ cat project.tjp | plan report
38
+ plan report - < project.tjp
39
+
40
+ # Pipe to other tools
41
+ plan report project.tjp | jq '.data[0]'
42
+ plan report --csv project.tjp | csvkit
43
+
44
+ # Process multiple files
45
+ for f in projects/*.tjp; do
46
+ plan report "$f" | jq -r '.report_id'
47
+ done
48
+ ```
49
+
50
+ **Output Format** (JSON):
51
+ ```json
52
+ {
53
+ "data": [
54
+ {
55
+ "id": "project.task1",
56
+ "start": "2024-01-01-09:00",
57
+ "end": "2024-01-05-17:00"
58
+ }
59
+ ],
60
+ "columns": ["id", "start", "end"],
61
+ "report_id": "ea3f901dd6426dfa58288d945819c75485fd9ff1875db59def350f219e2d62ca"
62
+ }
63
+ ```
64
+
65
+ **Features**:
66
+ - Output to stdout (Unix philosophy)
67
+ - Messages to stderr
68
+ - SHA256 report_id (content-based hash)
69
+ - Lowercase column names
70
+ - No HTML metadata
71
+ - No file pollution (uses temp directories)
72
+ - Safe for concurrent execution (100+ instances)
73
+
74
+ ### Python API
75
+
76
+ ```python
77
+ from scriptplan.parser.tjp_parser import ProjectFileParser
78
+
79
+ parser = ProjectFileParser()
80
+ project = parser.parse(open('project.tjp').read())
81
+
82
+ # Access scheduled tasks
83
+ for task in project.tasks:
84
+ if task.leaf():
85
+ start = task.get('start', 0)
86
+ end = task.get('end', 0)
87
+ print(f"{task.id}: {start} -> {end}")
88
+ ```
89
+
90
+ ## System Certified
91
+
92
+ **Certification Level**: Airport-Grade / Mission Critical
93
+
94
+ **Capabilities Verified**:
95
+
96
+ - **Temporal Physics**: Floating point precision, Timezones, DST awareness, Date Line crossing.
97
+
98
+ - **Resource Constraints**: Daily/Weekly limits, Hierarchical quotas, Shift intersections.
99
+
100
+ - **Advanced Scheduling**: ALAP (Backward pass), Priority preemption, Smart Resource Selection (Failover).
101
+
102
+ - **Workflow Logic**: Atomicity (Contiguous), Perishability (Max Gap), Zero-Buffer Synchronization.
103
+
104
+ ## Features
105
+
106
+ - Minute-level scheduling precision
107
+ - ASAP and ALAP scheduling modes
108
+ - Resource allocation with contention handling
109
+ - Working hours and shift definitions
110
+ - Dependency chains with gap constraints
111
+ - Leap year and timezone handling
112
+
113
+ ## Accuracy
114
+
115
+ ScriptPlan uses integer arithmetic for all time calculations, avoiding floating-point drift. The scheduler correctly handles:
116
+
117
+ - Non-standard shift boundaries (e.g., 08:13 - 11:59, 13:07 - 17:47)
118
+ - Prime-number effort durations with prime-number gaps
119
+ - Resource contention across multi-day tasks
120
+ - Calendar gaps (weekends, holidays) vs working time gaps
121
+
122
+ Example: A chain of 500 tasks, each with 73-minute effort and 29-minute gaps, scheduled across leap year boundaries with non-standard shifts, produces exact minute-aligned results.
123
+
124
+ ## Example Project
125
+
126
+ ```
127
+ project "Manufacturing" 2025-07-01 +1m {
128
+ timezone "Etc/UTC"
129
+ timeformat "%Y-%m-%d %H:%M"
130
+ scheduling alap
131
+ }
132
+
133
+ shift factory_hours "Factory Hours" {
134
+ workinghours mon - fri 08:00 - 16:00
135
+ }
136
+
137
+ resource machine "Press" {
138
+ workinghours factory_hours
139
+ }
140
+
141
+ task delivery "Product Launch" {
142
+ end 2025-07-18-16:00
143
+
144
+ task pack "Packaging" {
145
+ effort 8h
146
+ allocate machine
147
+ }
148
+
149
+ task assemble_b "Body Assembly" {
150
+ effort 16h
151
+ allocate machine
152
+ depends !!pack { onstart }
153
+ }
154
+
155
+ task assemble_a "Engine Assembly" {
156
+ effort 16h
157
+ allocate machine
158
+ }
159
+ }
160
+
161
+ task connection_setup "Logic" {
162
+ task set_deps "Apply" {
163
+ depends !delivery.assemble_a, !delivery.assemble_b
164
+ precedes !delivery.pack
165
+ }
166
+ }
167
+
168
+ taskreport output "output" {
169
+ formats csv
170
+ columns id, start, end
171
+ timeformat "%Y-%m-%d-%H:%M"
172
+ }
173
+ ```
174
+
175
+ This project schedules backward from the delivery deadline (ALAP mode). The scheduler:
176
+
177
+ 1. Anchors packaging to end at 16:00 on July 18
178
+ 2. Schedules both assembly tasks to complete before packaging starts
179
+ 3. Resolves resource contention (single machine) by sequencing assemblies back-to-back
180
+ 4. Respects weekend boundaries (Mon-Fri working hours)
181
+
182
+ Result:
183
+ ```
184
+ delivery.pack: 2025-07-18-08:00 -> 2025-07-18-16:00
185
+ delivery.assemble_a: 2025-07-14-08:00 -> 2025-07-15-16:00
186
+ delivery.assemble_b: 2025-07-16-08:00 -> 2025-07-17-16:00
187
+ ```
188
+
189
+ ## License
190
+
191
+ Apache-2.0
192
+
193
+ ## Acknowledgments
194
+
195
+ ScriptPlan references [TaskJuggler](https://taskjuggler.org/) solely for **file format compatibility**. We have not used, modified, or copied any TaskJuggler source code. ScriptPlan is an independent, clean-room implementation.
196
+
197
+ - The `.tjp` file format is documented publicly and widely used in the project management community
198
+ - All scheduling algorithms, parser, and report generation in ScriptPlan are original implementations
199
+ - TaskJuggler is mentioned only to indicate that ScriptPlan can read the same project file format
200
+
201
+ If you're looking for the original TaskJuggler with its full feature set including interactive HTML reports and GUI tools, please visit [taskjuggler.org](https://taskjuggler.org/).
202
+
203
+ ## Why ScriptPlan?
204
+
205
+ This scheduler is part of Highway Workflow Engine's worker capacity management system. I decided to open-source it for the community to benefit from its precise scheduling capabilities. Thanks to TaskJuggler's established syntax, users can easily adopt ScriptPlan without learning a new format.
206
+
207
+ Yours,
208
+ Farshid.
@@ -1,10 +1,10 @@
1
1
  [build-system]
2
- requires = ["setuptools>=61.0", "wheel"]
2
+ requires = ["setuptools>=61.0", "wheel", "cython>=3.0.0"]
3
3
  build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "scriptplan"
7
- version = "0.9.0"
7
+ version = "0.9.2"
8
8
  description = "A precise project scheduling engine with minute-level accuracy for resource allocation and dependency management."
9
9
  authors = [
10
10
  { name = "Farshid Ashouri", email = "farsheed.ashouri@gmail.com" },
@@ -26,6 +26,7 @@ classifiers = [
26
26
  "Programming Language :: Python :: 3.11",
27
27
  "Programming Language :: Python :: 3.12",
28
28
  "Programming Language :: Python :: 3.13",
29
+ "Programming Language :: Python :: 3.14",
29
30
  "Operating System :: OS Independent",
30
31
  "Topic :: Office/Business :: Scheduling",
31
32
  "Topic :: Software Development :: Libraries :: Python Modules",
@@ -35,6 +36,7 @@ keywords = ["scheduling", "project-management", "resource-allocation", "gantt",
35
36
  dependencies = [
36
37
  "lark>=1.0.0",
37
38
  "python-dateutil>=2.8.0",
39
+ "click>=8.0.0",
38
40
  ]
39
41
 
40
42
  [project.optional-dependencies]
@@ -42,18 +44,24 @@ dev = [
42
44
  "pytest>=7.0.0",
43
45
  "pytest-xdist>=3.0.0",
44
46
  "pandas>=1.5.0",
47
+ "types-python-dateutil>=2.8.0",
48
+ "types-pytz>=2022.1.0",
45
49
  "build",
46
50
  "twine",
51
+ "ruff>=0.1.0",
52
+ "mypy>=1.0.0",
53
+ "cython>=3.0.0",
47
54
  ]
48
55
 
49
56
  [project.scripts]
50
57
  scriptplan = "scriptplan.cli.main:main"
58
+ plan = "scriptplan.cli.plan:main"
51
59
 
52
60
  [project.urls]
53
- "Homepage" = "https://github.com/farshidash/scriptplan"
54
- "Documentation" = "https://github.com/farshidash/scriptplan#readme"
55
- "Bug Tracker" = "https://github.com/farshidash/scriptplan/issues"
56
- "Source" = "https://github.com/farshidash/scriptplan"
61
+ "Homepage" = "https://github.com/rodmena-limited/scriptplan"
62
+ "Documentation" = "https://github.com/rodmena-limited/scriptplan#readme"
63
+ "Bug Tracker" = "https://github.com/rodmena-limited/scriptplan/issues"
64
+ "Source" = "https://github.com/rodmena-limited/scriptplan"
57
65
 
58
66
  [tool.setuptools]
59
67
  include-package-data = true
@@ -63,7 +71,7 @@ where = ["."]
63
71
  include = ["scriptplan*"]
64
72
 
65
73
  [tool.setuptools.package-data]
66
- scriptplan = ["py.typed", "parser/*.lark"]
74
+ scriptplan = ["py.typed", "parser/*.lark", "_cython/*.pyx"]
67
75
 
68
76
  [tool.pytest.ini_options]
69
77
  testpaths = ["tests"]
@@ -75,3 +83,19 @@ filterwarnings = [
75
83
  "ignore::DeprecationWarning",
76
84
  "ignore::PendingDeprecationWarning",
77
85
  ]
86
+
87
+ [tool.ruff]
88
+ line-length = 120
89
+ target-version = "py39"
90
+
91
+ [tool.ruff.lint]
92
+ select = ["E", "F", "W", "I", "UP", "B", "C4", "SIM", "RUF"]
93
+ # N rules ignored: codebase uses camelCase for TaskJuggler API compatibility
94
+ ignore = ["E501"] # Line length handled separately
95
+
96
+ [tool.mypy]
97
+ python_version = "3.9"
98
+ strict = true
99
+ warn_return_any = true
100
+ warn_unused_configs = true
101
+ ignore_missing_imports = true
@@ -0,0 +1,26 @@
1
+ """
2
+ ScriptPlan - A Python implementation inspired by TaskJuggler.
3
+
4
+ This package provides project scheduling and resource management capabilities
5
+ compatible with the TaskJuggler Project Definition Language (.tjp files).
6
+
7
+ ScriptPlan owes its existence to TaskJuggler (https://taskjuggler.org/),
8
+ the pioneering open-source project management tool created by Chris Schlaeger.
9
+ The TJP file format and scheduling concepts originate from TaskJuggler.
10
+ """
11
+
12
+ __version__ = "0.9.2"
13
+ __author__ = "ScriptPlan Team"
14
+
15
+ from scriptplan.core.project import Project
16
+ from scriptplan.core.resource import Resource
17
+ from scriptplan.core.scenario import Scenario
18
+ from scriptplan.core.task import Task
19
+
20
+ __all__ = [
21
+ "Project",
22
+ "Resource",
23
+ "Scenario",
24
+ "Task",
25
+ "__version__",
26
+ ]
@@ -0,0 +1,45 @@
1
+ """
2
+ Cython-optimized modules for ScriptPlan.
3
+
4
+ This package contains Cython implementations of performance-critical code.
5
+ Pure Python fallbacks are used if Cython extensions are not compiled.
6
+ """
7
+
8
+ # Track which optimized modules are available
9
+ CYTHON_AVAILABLE = {
10
+ "scoreboard": False,
11
+ "time_utils": False,
12
+ "working_hours": False,
13
+ }
14
+
15
+ # Try to import Cython modules
16
+ try:
17
+ from scriptplan._cython import scoreboard_cy # noqa: F401
18
+
19
+ CYTHON_AVAILABLE["scoreboard"] = True
20
+ except ImportError:
21
+ pass
22
+
23
+ try:
24
+ from scriptplan._cython import time_utils_cy # noqa: F401
25
+
26
+ CYTHON_AVAILABLE["time_utils"] = True
27
+ except ImportError:
28
+ pass
29
+
30
+ try:
31
+ from scriptplan._cython import working_hours_cy # noqa: F401
32
+
33
+ CYTHON_AVAILABLE["working_hours"] = True
34
+ except ImportError:
35
+ pass
36
+
37
+
38
+ def is_optimized(module: str) -> bool:
39
+ """Check if a Cython-optimized module is available."""
40
+ return CYTHON_AVAILABLE.get(module, False)
41
+
42
+
43
+ def get_available_optimizations() -> list[str]:
44
+ """Get list of available Cython optimizations."""
45
+ return [k for k, v in CYTHON_AVAILABLE.items() if v]