orionis 0.730.0__py3-none-any.whl → 0.731.0__py3-none-any.whl

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.
@@ -106,7 +106,11 @@ class MakeCommand(BaseCommand):
106
106
  stub = file.read()
107
107
 
108
108
  # Generate the class name by capitalizing each word and appending 'Command'
109
- class_name = ''.join(word.capitalize() for word in name.split('_')) + "Command"
109
+ class_name = ''.join(word.capitalize() for word in name.split('_'))
110
+ if not class_name.endswith("Command"):
111
+ class_name = class_name.rstrip("_") + "Command"
112
+
113
+
110
114
  # Replace placeholders in the stub with the actual class name and signature
111
115
  stub = stub.replace("{{class_name}}", class_name)
112
116
  stub = stub.replace("{{signature}}", signature)
@@ -114,6 +118,12 @@ class MakeCommand(BaseCommand):
114
118
  # Ensure the commands directory exists
115
119
  commands_dir = app.path('console') / "commands"
116
120
  commands_dir.mkdir(parents=True, exist_ok=True)
121
+
122
+ # Ensure the name ends with 'command' (case-insensitive)
123
+ if not name.lower().endswith("command"):
124
+ name = name.rstrip("_") + "_command"
125
+
126
+ # Define the full path for the new command file
117
127
  file_path = commands_dir / f"{name}.py"
118
128
 
119
129
  # Check if the file already exists to prevent overwriting
@@ -0,0 +1,131 @@
1
+ import re
2
+ from pathlib import Path
3
+ from typing import List
4
+ from orionis.console.args.argument import CLIArgument
5
+ from orionis.console.base.command import BaseCommand
6
+ from orionis.console.exceptions import CLIOrionisRuntimeError
7
+ from orionis.foundation.contracts.application import IApplication
8
+
9
+ class MakeSchedulerListenerCommand(BaseCommand):
10
+ """
11
+ Command to create a new custom scheduler listener for scheduled task events.
12
+
13
+ Attributes
14
+ ----------
15
+ timestamps : bool
16
+ Indicates whether timestamps will be shown in the command output.
17
+ signature : str
18
+ Command signature.
19
+ description : str
20
+ Command description.
21
+
22
+ Methods
23
+ -------
24
+ options() -> List[CLIArgument]
25
+ Returns the CLI arguments required for this command.
26
+ handle(app: IApplication) -> dict
27
+ Handles the creation of the scheduler listener file.
28
+ """
29
+
30
+ # Indicates whether timestamps will be shown in the command output
31
+ timestamps: bool = False
32
+
33
+ # Command signature and description
34
+ signature: str = "make:scheduler-listener"
35
+
36
+ # Command description
37
+ description: str = (
38
+ "Creates a new custom scheduler listener to handle events for a scheduled task."
39
+ )
40
+
41
+ async def options(self) -> List[CLIArgument]:
42
+ """
43
+ Returns the CLI arguments required for this command.
44
+
45
+ Returns
46
+ -------
47
+ List[CLIArgument]
48
+ A list containing the required CLIArgument for the listener name.
49
+ """
50
+
51
+ # Define the required CLI argument for the listener name
52
+ return [
53
+ CLIArgument(
54
+ flags=["name"],
55
+ type=str,
56
+ required=True,
57
+ help="The filename where the new command will be created."
58
+ )
59
+ ]
60
+
61
+ def handle(self, app: IApplication) -> dict:
62
+ """
63
+ Handles the creation of the scheduler listener file.
64
+
65
+ This method validates the listener name, loads the stub template,
66
+ generates the listener class, ensures the listeners directory exists,
67
+ and writes the new listener file. If the file already exists, it
68
+ prevents overwriting and displays an error.
69
+
70
+ Parameters
71
+ ----------
72
+ app : IApplication
73
+ The application instance used to resolve paths.
74
+
75
+ Returns
76
+ -------
77
+ dict
78
+ An empty dictionary. All output is handled via CLI messaging.
79
+ """
80
+
81
+ try:
82
+
83
+ # Retrieve the 'name' argument (required)
84
+ listener_name: str = self.argument("name")
85
+
86
+ # Validate that the listener_name argument is provided
87
+ if not listener_name:
88
+ self.error("The 'name' argument is required.")
89
+
90
+ # Validate that the listener name starts with a lowercase letter and contains only lowercase letters, numbers, or underscores
91
+ if not re.match(r'^[a-z][a-z0-9_]*$', listener_name):
92
+ self.error("The 'name' argument must start with a lowercase letter and contain only lowercase letters, numbers, and underscores (_).")
93
+
94
+ # Load the listener stub template from the stubs directory
95
+ stub_path = Path(__file__).parent.parent / "stubs" / "listener.stub"
96
+ with open(stub_path, "r", encoding="utf-8") as file:
97
+ stub_content = file.read()
98
+
99
+ # Generate the class name by capitalizing each word and appending 'Listener'
100
+ class_name = ''.join(word.capitalize() for word in listener_name.split('_'))
101
+ if not class_name.endswith("Listener"):
102
+ class_name = class_name.rstrip("_") + "Listener"
103
+
104
+ # Replace placeholders in the stub with the actual class name
105
+ stub_content = stub_content.replace("{{class_name}}", class_name)
106
+
107
+ # Ensure the listeners directory exists
108
+ listeners_dir = app.path('console') / "listeners"
109
+ listeners_dir.mkdir(parents=True, exist_ok=True)
110
+
111
+ # Ensure the listener_name ends with 'listener' (case-insensitive)
112
+ if not listener_name.lower().endswith("listener"):
113
+ listener_name = listener_name.rstrip("_") + "_listener"
114
+
115
+ file_path = listeners_dir / f"{listener_name}.py"
116
+
117
+ # Check if the file already exists to prevent overwriting
118
+ if file_path.exists():
119
+ relative_path = file_path.relative_to(app.path('root'))
120
+ self.error(f"The file [{relative_path}] already exists. Please choose a different name.")
121
+ else:
122
+ # Write the generated listener code to the new file
123
+ with open(file_path, "w", encoding="utf-8") as file:
124
+ file.write(stub_content)
125
+ relative_path = file_path.relative_to(app.path('root'))
126
+ self.info(f"Listener [{relative_path}] was created successfully.")
127
+
128
+ except Exception as exc:
129
+
130
+ # Catch any unexpected exceptions and raise a CLI-specific runtime error
131
+ raise CLIOrionisRuntimeError(f"An unexpected error occurred: {exc}") from exc
@@ -288,6 +288,7 @@ class Reactor(IReactor):
288
288
  from orionis.console.commands.scheduler_work import ScheduleWorkCommand
289
289
  from orionis.console.commands.test import TestCommand
290
290
  from orionis.console.commands.version import VersionCommand
291
+ from orionis.console.commands.make_scheduler_listener import MakeSchedulerListenerCommand
291
292
 
292
293
  # List of core command classes to load (extend this list as more core commands are added)
293
294
  core_commands = [
@@ -298,7 +299,8 @@ class Reactor(IReactor):
298
299
  ScheduleListCommand,
299
300
  ScheduleWorkCommand,
300
301
  TestCommand,
301
- VersionCommand
302
+ VersionCommand,
303
+ MakeSchedulerListenerCommand
302
304
  ]
303
305
 
304
306
  # Iterate through the core command classes and register them
@@ -10,7 +10,7 @@ class {{class_name}}(BaseCommand):
10
10
  # Command description
11
11
  description: str = "[Command description]"
12
12
 
13
- def options(cls) -> List[CLIArgument]:
13
+ def options(self) -> List[CLIArgument]:
14
14
  """
15
15
  Define the command's arguments and options.
16
16
  Returns a list of CLIArgument instances.
@@ -6,7 +6,7 @@
6
6
  NAME = "orionis"
7
7
 
8
8
  # Current version of the framework
9
- VERSION = "0.730.0"
9
+ VERSION = "0.731.0"
10
10
 
11
11
  # Full name of the author or maintainer of the project
12
12
  AUTHOR = "Raul Mauricio Uñate Castro"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: orionis
3
- Version: 0.730.0
3
+ Version: 0.731.0
4
4
  Summary: Orionis Framework – Elegant, Fast, and Powerful.
5
5
  Home-page: https://github.com/orionis-framework/framework
6
6
  Author: Raul Mauricio Uñate Castro
@@ -12,7 +12,8 @@ orionis/console/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
12
12
  orionis/console/commands/__publisher__.py,sha256=TS2WGZoWx7YX8CP7ixKB5lHc_1r-bBDNB8OkkWR9lzc,21647
13
13
  orionis/console/commands/cache_clear.py,sha256=UlFEZI8Q4BONsZybE6IgKrjLhW5N-JJLNEPMVFRw6LA,2926
14
14
  orionis/console/commands/help.py,sha256=GF5N6uabqBaGVVgiBRmlB0TQkUlDK71bvIgJQIPJxak,3760
15
- orionis/console/commands/make_command.py,sha256=WHE2J78fuY9RHScCOn9R_2KjkiayYJHFlm-Mp-k8X-o,5956
15
+ orionis/console/commands/make_command.py,sha256=eL33zKDRmKaTsuqdYjyMzKsDb1D-R4iWcqMNbLyko5A,6308
16
+ orionis/console/commands/make_scheduler_listener.py,sha256=LT4pbUsCqrrYDfuantW65GAjlWZrJlqY0frJtHiH42M,5239
16
17
  orionis/console/commands/scheduler_list.py,sha256=7E0C926e7YVU3YxqQ8Ot2as7Yco0jviFaxM8WrOYfsg,5316
17
18
  orionis/console/commands/scheduler_work.py,sha256=dDW9XTjGb-5ABuhPYjfd1rfO7xLDhgYu5nd6nToiYFE,5597
18
19
  orionis/console/commands/test.py,sha256=G3pveONRbeWTcVwaHat3wTAhxMm4g_BwhJhIejq6V0Y,3518
@@ -32,7 +33,7 @@ orionis/console/contracts/reactor.py,sha256=iT6ShoCutAWEeJzOf_PK7CGXi9TgrOD5tewH
32
33
  orionis/console/contracts/schedule.py,sha256=NaVOUpuE08X5rm9-oXyNs6r3LbOg7B_rIz-k4r7y4Qk,13703
33
34
  orionis/console/contracts/schedule_event_listener.py,sha256=h06qsBxuEMD3KLSyu0JXdUDHlQW19BX9lA09Qrh2QXg,3818
34
35
  orionis/console/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
- orionis/console/core/reactor.py,sha256=z3Yp4fvZoXv5YcDJc8sS8AfV9wHC80IgkTO31EijZUg,44184
36
+ orionis/console/core/reactor.py,sha256=I_3Ix0lzbS1gZ8pyfkHYA8DUQB0lzxyvBk_g9cthrmE,44326
36
37
  orionis/console/debug/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
37
38
  orionis/console/debug/dumper.py,sha256=vbmP_GlrzBj0KDjiQl4iDudPRe6V0W5r5UA8i3h9_c4,6555
38
39
  orionis/console/dynamic/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -61,7 +62,7 @@ orionis/console/output/console.py,sha256=xRZXSZiVqlyc1L16MBUV1M3TUHQwrWSFYUtisiv
61
62
  orionis/console/output/executor.py,sha256=uQjFPOlyZLFj9pcyYPugCqxwJog0AJgK1OcmQH2ELbw,7314
62
63
  orionis/console/request/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
63
64
  orionis/console/request/cli_request.py,sha256=sH7Q2MpMIasiPiEPBeGhExnbfpSic98vQdAKvG9cgew,9071
64
- orionis/console/stubs/command.stub,sha256=hvtIUd5JHOOsoHnrwF2yMkzFs2sZeeBgM8RZMPrNgjM,691
65
+ orionis/console/stubs/command.stub,sha256=d5qSvgDkA54BD5I5tbpp3zc_oRGKgFwxW0BLsszG1bE,692
65
66
  orionis/console/stubs/listener.stub,sha256=R6QNFU2I2OiUJAvSye2Zrboith5v4S8GlePUIQNNFjc,4264
66
67
  orionis/console/tasks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
67
68
  orionis/console/tasks/schedule.py,sha256=QExrIRcxr7s31xY1-DLUsrc7GmeuAhFjpCo4OicnChg,93309
@@ -206,7 +207,7 @@ orionis/foundation/providers/scheduler_provider.py,sha256=IrPQJwvQVLRm5Qnz0Cxon4
206
207
  orionis/foundation/providers/testing_provider.py,sha256=eI1p2lUlxl25b5Z487O4nmqLE31CTDb4c3Q21xFadkE,1615
207
208
  orionis/foundation/providers/workers_provider.py,sha256=GdHENYV_yGyqmHJHn0DCyWmWId5xWjD48e6Zq2PGCWY,1674
208
209
  orionis/metadata/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
209
- orionis/metadata/framework.py,sha256=144rPMiaSWVBgDzcZ9H-EIukPrsUG1X23SMS4BFaR-E,4720
210
+ orionis/metadata/framework.py,sha256=R7byA9N4aFOQgGCWBzwwHyXnKxctpdVPNoZo0c18AU8,4720
210
211
  orionis/metadata/package.py,sha256=s1JeGJPwdVh4jO3IOfmpwMuJ_oX6Vf9NL7jgPEQNf5Y,16050
211
212
  orionis/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
212
213
  orionis/services/asynchrony/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -401,8 +402,8 @@ orionis/test/validators/workers.py,sha256=HcZ3cnrk6u7cvM1xZpn_lsglHAq69_jx9RcTSv
401
402
  orionis/test/view/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
402
403
  orionis/test/view/render.py,sha256=arysoswhkV2vUd2aVMZRPpmH317jaWbgjDpQ_AWQ5AE,5663
403
404
  orionis/test/view/report.stub,sha256=QLqqCdRoENr3ECiritRB3DO_MOjRQvgBh5jxZ3Hs1r0,28189
404
- orionis-0.730.0.dist-info/licenses/LICENCE,sha256=JhC-z_9mbpUrCfPjcl3DhDA8trNDMzb57cvRSam1avc,1463
405
- orionis-0.730.0.dist-info/METADATA,sha256=4AI8C0GfVSxyoeL4xbmObgz6Q9_gbTxqY5WBPub7H34,4962
406
- orionis-0.730.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
407
- orionis-0.730.0.dist-info/top_level.txt,sha256=lyXi6jArpqJ-0zzNqd_uwsH-z9TCEBVBL-pC3Ekv7hU,8
408
- orionis-0.730.0.dist-info/RECORD,,
405
+ orionis-0.731.0.dist-info/licenses/LICENCE,sha256=JhC-z_9mbpUrCfPjcl3DhDA8trNDMzb57cvRSam1avc,1463
406
+ orionis-0.731.0.dist-info/METADATA,sha256=_7l305UGl4mv2vm-X8S3KNsjkBmiTdrNKCeIKptgZ88,4962
407
+ orionis-0.731.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
408
+ orionis-0.731.0.dist-info/top_level.txt,sha256=lyXi6jArpqJ-0zzNqd_uwsH-z9TCEBVBL-pC3Ekv7hU,8
409
+ orionis-0.731.0.dist-info/RECORD,,