modusa 0.1.0__tar.gz → 0.2.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.
- {modusa-0.1.0 → modusa-0.2.1}/PKG-INFO +16 -11
- {modusa-0.1.0 → modusa-0.2.1}/README.md +10 -9
- {modusa-0.1.0 → modusa-0.2.1}/pyproject.toml +6 -2
- modusa-0.2.1/src/modusa/.DS_Store +0 -0
- {modusa-0.1.0 → modusa-0.2.1}/src/modusa/decorators.py +5 -5
- modusa-0.2.1/src/modusa/devtools/generate_template.py +144 -0
- {modusa-0.1.0 → modusa-0.2.1}/src/modusa/devtools/main.py +6 -4
- modusa-0.1.0/src/modusa/devtools/templates/engines.py → modusa-0.2.1/src/modusa/devtools/templates/engine.py +8 -7
- modusa-0.1.0/src/modusa/devtools/templates/generators.py → modusa-0.2.1/src/modusa/devtools/templates/generator.py +8 -10
- modusa-0.2.1/src/modusa/devtools/templates/io.py +24 -0
- modusa-0.1.0/src/modusa/devtools/templates/plugins.py → modusa-0.2.1/src/modusa/devtools/templates/plugin.py +7 -6
- modusa-0.2.1/src/modusa/devtools/templates/signal.py +40 -0
- modusa-0.2.1/src/modusa/devtools/templates/test.py +11 -0
- {modusa-0.1.0/src/modusa → modusa-0.2.1/src/modusa/engines}/.DS_Store +0 -0
- modusa-0.2.1/src/modusa/engines/__init__.py +3 -0
- modusa-0.2.1/src/modusa/generators/__init__.py +5 -0
- modusa-0.2.1/src/modusa/generators/audio_waveforms.py +227 -0
- modusa-0.2.1/src/modusa/generators/base.py +29 -0
- modusa-0.2.1/src/modusa/io/__init__.py +9 -0
- modusa-0.2.1/src/modusa/io/audio_converter.py +76 -0
- modusa-0.2.1/src/modusa/io/audio_loader.py +212 -0
- modusa-0.2.1/src/modusa/io/audio_player.py +72 -0
- modusa-0.2.1/src/modusa/io/base.py +43 -0
- modusa-0.2.1/src/modusa/io/plotter.py +430 -0
- modusa-0.2.1/src/modusa/io/youtube_downloader.py +139 -0
- modusa-0.2.1/src/modusa/main.py +33 -0
- modusa-0.2.1/src/modusa/plugins/__init__.py +1 -0
- modusa-0.2.1/src/modusa/signals/__init__.py +7 -0
- modusa-0.2.1/src/modusa/signals/audio_signal.py +476 -0
- modusa-0.2.1/src/modusa/signals/base.py +34 -0
- modusa-0.2.1/src/modusa/signals/frequency_domain_signal.py +329 -0
- modusa-0.2.1/src/modusa/signals/signal_ops.py +158 -0
- modusa-0.2.1/src/modusa/signals/spectrogram.py +465 -0
- modusa-0.2.1/src/modusa/signals/time_domain_signal.py +309 -0
- {modusa-0.1.0 → modusa-0.2.1}/src/modusa/utils/excp.py +5 -0
- modusa-0.2.1/tests/test_engines/audio_converter.py +11 -0
- modusa-0.2.1/tests/test_engines/youtube_audio_loader.py +11 -0
- modusa-0.2.1/tests/test_engines/youtube_downloader.py +20 -0
- modusa-0.2.1/tests/test_generators/audio_waveform.py +11 -0
- modusa-0.2.1/tests/test_io/audio_player.py +11 -0
- modusa-0.2.1/tests/test_io/plotter.py +11 -0
- modusa-0.2.1/tests/test_plugins/youtube_audio_loader.py +11 -0
- modusa-0.2.1/tests/test_signals/frequency_domain_signal.py +11 -0
- modusa-0.2.1/tests/test_signals/spectrogram.py +11 -0
- modusa-0.2.1/tests/test_signals/time_domain_signal.py +11 -0
- modusa-0.1.0/src/modusa/devtools/generate_template.py +0 -79
- modusa-0.1.0/src/modusa/devtools/templates/signals.py +0 -63
- modusa-0.1.0/src/modusa/engines/__init__.py +0 -4
- modusa-0.1.0/src/modusa/engines/plot_1dsignal.py +0 -130
- modusa-0.1.0/src/modusa/engines/plot_2dmatrix.py +0 -159
- modusa-0.1.0/src/modusa/generators/__init__.py +0 -3
- modusa-0.1.0/src/modusa/generators/base.py +0 -40
- modusa-0.1.0/src/modusa/generators/basic_waveform.py +0 -185
- modusa-0.1.0/src/modusa/main.py +0 -35
- modusa-0.1.0/src/modusa/plugins/__init__.py +0 -7
- modusa-0.1.0/src/modusa/plugins/plot_1dsignal.py +0 -59
- modusa-0.1.0/src/modusa/plugins/plot_2dmatrix.py +0 -76
- modusa-0.1.0/src/modusa/plugins/plot_time_domain_signal.py +0 -59
- modusa-0.1.0/src/modusa/signals/__init__.py +0 -9
- modusa-0.1.0/src/modusa/signals/audio_signal.py +0 -230
- modusa-0.1.0/src/modusa/signals/base.py +0 -294
- modusa-0.1.0/src/modusa/signals/signal1d.py +0 -311
- modusa-0.1.0/src/modusa/signals/signal2d.py +0 -226
- modusa-0.1.0/src/modusa/signals/uniform_time_domain_signal.py +0 -212
- modusa-0.1.0/tests/test_signals/test_signal1d.py +0 -52
- {modusa-0.1.0 → modusa-0.2.1}/LICENSE.md +0 -0
- {modusa-0.1.0 → modusa-0.2.1}/src/modusa/__init__.py +0 -0
- {modusa-0.1.0 → modusa-0.2.1}/src/modusa/config.py +0 -0
- {modusa-0.1.0 → modusa-0.2.1}/src/modusa/devtools/list_authors.py +0 -0
- {modusa-0.1.0 → modusa-0.2.1}/src/modusa/devtools/list_plugins.py +0 -0
- {modusa-0.1.0 → modusa-0.2.1}/src/modusa/engines/base.py +0 -0
- {modusa-0.1.0 → modusa-0.2.1}/src/modusa/plugins/base.py +0 -0
- {modusa-0.1.0 → modusa-0.2.1}/src/modusa/utils/.DS_Store +0 -0
- {modusa-0.1.0 → modusa-0.2.1}/src/modusa/utils/__init__.py +0 -0
- {modusa-0.1.0 → modusa-0.2.1}/src/modusa/utils/config.py +0 -0
- {modusa-0.1.0 → modusa-0.2.1}/src/modusa/utils/logger.py +0 -0
- {modusa-0.1.0 → modusa-0.2.1}/tests/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: modusa
|
|
3
|
-
Version: 0.1
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: A modular signal analysis python library.
|
|
5
5
|
Author-Email: Ankit Anand <ankit0.anand0@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -8,7 +8,6 @@ Requires-Python: >=3.12
|
|
|
8
8
|
Requires-Dist: jupyter>=1.1.1
|
|
9
9
|
Requires-Dist: pytest>=8.4.0
|
|
10
10
|
Requires-Dist: numpy>=2.2.6
|
|
11
|
-
Requires-Dist: librosa>=0.11.0
|
|
12
11
|
Requires-Dist: matplotlib>=3.10.3
|
|
13
12
|
Requires-Dist: pandas>=2.3.0
|
|
14
13
|
Requires-Dist: pydantic>=2.11.5
|
|
@@ -24,24 +23,30 @@ Requires-Dist: snakeviz>=2.2.2
|
|
|
24
23
|
Requires-Dist: line-profiler>=4.2.0
|
|
25
24
|
Requires-Dist: nbsphinx==0.9.7
|
|
26
25
|
Requires-Dist: ghp-import>=2.1.0
|
|
26
|
+
Requires-Dist: yt-dlp>=2025.6.30
|
|
27
|
+
Requires-Dist: sphinx-book-theme>=1.1.4
|
|
28
|
+
Requires-Dist: pydata-sphinx-theme>=0.15.4
|
|
29
|
+
Requires-Dist: sphinx-material>=0.0.36
|
|
30
|
+
Requires-Dist: librosa==0.10.1
|
|
27
31
|
Description-Content-Type: text/markdown
|
|
28
32
|
|
|
29
33
|
# modusa
|
|
30
34
|
|
|
31
|
-
**modusa
|
|
35
|
+
[**modusa**](https://meluron-toolbox.github.io/modusa/) is a modular framework for audio signal analysis and processing, designed to help audio researchers and developers build DSP chains with minimal code.
|
|
32
36
|
|
|
33
37
|
---
|
|
34
38
|
|
|
35
|
-
##
|
|
39
|
+
## Core Components
|
|
36
40
|
|
|
37
41
|
- ⚙️ **modusa Signals**
|
|
38
42
|
- 🧩 **modusa Plugins**
|
|
39
43
|
- 📊 **modusa Genetators**
|
|
40
|
-
-
|
|
44
|
+
- 📥 **modusa I/O**
|
|
45
|
+
- ♻️ **modusa Engines**
|
|
41
46
|
|
|
42
47
|
---
|
|
43
48
|
|
|
44
|
-
##
|
|
49
|
+
## Installation
|
|
45
50
|
|
|
46
51
|
> modusa is under active development. You can install the latest version via:
|
|
47
52
|
|
|
@@ -53,7 +58,7 @@ pdm install
|
|
|
53
58
|
|
|
54
59
|
---
|
|
55
60
|
|
|
56
|
-
##
|
|
61
|
+
## Tests
|
|
57
62
|
|
|
58
63
|
```bash
|
|
59
64
|
pytest tests/
|
|
@@ -61,26 +66,26 @@ pytest tests/
|
|
|
61
66
|
|
|
62
67
|
---
|
|
63
68
|
|
|
64
|
-
##
|
|
69
|
+
## Status
|
|
65
70
|
|
|
66
71
|
modusa is in **early alpha**. Expect rapid iteration, breaking changes, and big ideas.
|
|
67
72
|
If you like the direction, consider ⭐ starring the repo and opening issues or ideas.
|
|
68
73
|
|
|
69
74
|
---
|
|
70
75
|
|
|
71
|
-
##
|
|
76
|
+
## About
|
|
72
77
|
|
|
73
78
|
**modusa** is developed and maintained by [meluron](https://www.github.com/meluron),
|
|
74
79
|
|
|
75
80
|
---
|
|
76
81
|
|
|
77
|
-
##
|
|
82
|
+
## License
|
|
78
83
|
|
|
79
84
|
MIT License. See `LICENSE` for details.
|
|
80
85
|
|
|
81
86
|
---
|
|
82
87
|
|
|
83
|
-
##
|
|
88
|
+
## Contributions
|
|
84
89
|
|
|
85
90
|
Pull requests, ideas, and discussions are welcome!
|
|
86
91
|
No matter which domain you are in, if you work with any signal, we'd love your input.
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
# modusa
|
|
2
2
|
|
|
3
|
-
**modusa
|
|
3
|
+
[**modusa**](https://meluron-toolbox.github.io/modusa/) is a modular framework for audio signal analysis and processing, designed to help audio researchers and developers build DSP chains with minimal code.
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## Core Components
|
|
8
8
|
|
|
9
9
|
- ⚙️ **modusa Signals**
|
|
10
10
|
- 🧩 **modusa Plugins**
|
|
11
11
|
- 📊 **modusa Genetators**
|
|
12
|
-
-
|
|
12
|
+
- 📥 **modusa I/O**
|
|
13
|
+
- ♻️ **modusa Engines**
|
|
13
14
|
|
|
14
15
|
---
|
|
15
16
|
|
|
16
|
-
##
|
|
17
|
+
## Installation
|
|
17
18
|
|
|
18
19
|
> modusa is under active development. You can install the latest version via:
|
|
19
20
|
|
|
@@ -25,7 +26,7 @@ pdm install
|
|
|
25
26
|
|
|
26
27
|
---
|
|
27
28
|
|
|
28
|
-
##
|
|
29
|
+
## Tests
|
|
29
30
|
|
|
30
31
|
```bash
|
|
31
32
|
pytest tests/
|
|
@@ -33,26 +34,26 @@ pytest tests/
|
|
|
33
34
|
|
|
34
35
|
---
|
|
35
36
|
|
|
36
|
-
##
|
|
37
|
+
## Status
|
|
37
38
|
|
|
38
39
|
modusa is in **early alpha**. Expect rapid iteration, breaking changes, and big ideas.
|
|
39
40
|
If you like the direction, consider ⭐ starring the repo and opening issues or ideas.
|
|
40
41
|
|
|
41
42
|
---
|
|
42
43
|
|
|
43
|
-
##
|
|
44
|
+
## About
|
|
44
45
|
|
|
45
46
|
**modusa** is developed and maintained by [meluron](https://www.github.com/meluron),
|
|
46
47
|
|
|
47
48
|
---
|
|
48
49
|
|
|
49
|
-
##
|
|
50
|
+
## License
|
|
50
51
|
|
|
51
52
|
MIT License. See `LICENSE` for details.
|
|
52
53
|
|
|
53
54
|
---
|
|
54
55
|
|
|
55
|
-
##
|
|
56
|
+
## Contributions
|
|
56
57
|
|
|
57
58
|
Pull requests, ideas, and discussions are welcome!
|
|
58
59
|
No matter which domain you are in, if you work with any signal, we'd love your input.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "modusa"
|
|
3
|
-
version = "0.1
|
|
3
|
+
version = "0.2.1"
|
|
4
4
|
description = "A modular signal analysis python library."
|
|
5
5
|
authors = [
|
|
6
6
|
{ name = "Ankit Anand", email = "ankit0.anand0@gmail.com" },
|
|
@@ -9,7 +9,6 @@ dependencies = [
|
|
|
9
9
|
"jupyter>=1.1.1",
|
|
10
10
|
"pytest>=8.4.0",
|
|
11
11
|
"numpy>=2.2.6",
|
|
12
|
-
"librosa>=0.11.0",
|
|
13
12
|
"matplotlib>=3.10.3",
|
|
14
13
|
"pandas>=2.3.0",
|
|
15
14
|
"pydantic>=2.11.5",
|
|
@@ -25,6 +24,11 @@ dependencies = [
|
|
|
25
24
|
"line-profiler>=4.2.0",
|
|
26
25
|
"nbsphinx==0.9.7",
|
|
27
26
|
"ghp-import>=2.1.0",
|
|
27
|
+
"yt-dlp>=2025.6.30",
|
|
28
|
+
"sphinx-book-theme>=1.1.4",
|
|
29
|
+
"pydata-sphinx-theme>=0.15.4",
|
|
30
|
+
"sphinx-material>=0.0.36",
|
|
31
|
+
"librosa==0.10.1",
|
|
28
32
|
]
|
|
29
33
|
requires-python = ">=3.12"
|
|
30
34
|
readme = "README.md"
|
|
Binary file
|
|
@@ -103,7 +103,7 @@ def validate_arg(arg_name: str, value: Any, expected_type: Any) -> None:
|
|
|
103
103
|
union_args = get_args(expected_type)
|
|
104
104
|
for typ in union_args:
|
|
105
105
|
typ_origin = get_origin(typ) or typ
|
|
106
|
-
if
|
|
106
|
+
if isinstance(value, typ_origin):
|
|
107
107
|
return
|
|
108
108
|
|
|
109
109
|
# ❌ If none match
|
|
@@ -116,17 +116,17 @@ def validate_arg(arg_name: str, value: Any, expected_type: Any) -> None:
|
|
|
116
116
|
|
|
117
117
|
# Handle generic types like list[float], tuple[int, str]
|
|
118
118
|
elif origin is not None:
|
|
119
|
-
if
|
|
119
|
+
if not isinstance(value, origin):
|
|
120
120
|
raise excp.ValidationError(
|
|
121
|
-
f"Argument '{arg_name}' must be
|
|
121
|
+
f"Argument '{arg_name}' must be of type {origin.__name__}, got {type(value).__name__}"
|
|
122
122
|
)
|
|
123
123
|
return
|
|
124
124
|
|
|
125
125
|
# ✅ Handle plain types
|
|
126
126
|
elif isinstance(expected_type, type):
|
|
127
|
-
if
|
|
127
|
+
if not isinstance(value, expected_type):
|
|
128
128
|
raise excp.ValidationError(
|
|
129
|
-
f"Argument '{arg_name}' must be
|
|
129
|
+
f"Argument '{arg_name}' must be of type {expected_type.__name__}, got {type(value).__name__}"
|
|
130
130
|
)
|
|
131
131
|
return
|
|
132
132
|
# ❌ Unsupported type structure
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
from datetime import date
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
import questionary
|
|
6
|
+
import sys
|
|
7
|
+
|
|
8
|
+
ROOT_DIR = Path(__file__).parents[3].resolve()
|
|
9
|
+
SRC_CODE_DIR = ROOT_DIR / "src/modusa"
|
|
10
|
+
TESTS_DIR = ROOT_DIR / "tests"
|
|
11
|
+
TEMPLATES_DIR = ROOT_DIR / "src/modusa/devtools/templates"
|
|
12
|
+
|
|
13
|
+
PLUGIN_INFO = {
|
|
14
|
+
"template_fp": TEMPLATES_DIR / "plugin.py",
|
|
15
|
+
"test_template_fp": TEMPLATES_DIR / "test.py",
|
|
16
|
+
"template_dump_dp": SRC_CODE_DIR / "plugins",
|
|
17
|
+
"test_template_dump_dp": TESTS_DIR / "test_plugins"
|
|
18
|
+
}
|
|
19
|
+
IO_INFO = {
|
|
20
|
+
"template_fp": TEMPLATES_DIR / "io.py",
|
|
21
|
+
"test_template_fp": TEMPLATES_DIR / "test.py",
|
|
22
|
+
"template_dump_dp": SRC_CODE_DIR / "io",
|
|
23
|
+
"test_template_dump_dp": TESTS_DIR / "test_io"
|
|
24
|
+
}
|
|
25
|
+
GENERATOR_INFO = {
|
|
26
|
+
"template_fp": TEMPLATES_DIR / "generator.py",
|
|
27
|
+
"test_template_fp": TEMPLATES_DIR / "test.py",
|
|
28
|
+
"template_dump_dp": SRC_CODE_DIR / "generators",
|
|
29
|
+
"test_template_dump_dp": TESTS_DIR / "test_generators"
|
|
30
|
+
}
|
|
31
|
+
SIGNAL_INFO = {
|
|
32
|
+
"template_fp": TEMPLATES_DIR / "signal.py",
|
|
33
|
+
"test_template_fp": TEMPLATES_DIR / "test.py",
|
|
34
|
+
"template_dump_dp": SRC_CODE_DIR / "signals",
|
|
35
|
+
"test_template_dump_dp": TESTS_DIR / "test_signals"
|
|
36
|
+
}
|
|
37
|
+
ENGINE_INFO = {
|
|
38
|
+
"template_fp": TEMPLATES_DIR / "engine.py",
|
|
39
|
+
"test_template_fp": TEMPLATES_DIR / "test.py",
|
|
40
|
+
"template_dump_dp": SRC_CODE_DIR / "engines",
|
|
41
|
+
"test_template_dump_dp": TESTS_DIR / "test_engines"
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class TemplateGenerator():
|
|
46
|
+
"""
|
|
47
|
+
Generates template for `plugin`, `engine`, `signal`, `generator` along with its corresponding `test` file
|
|
48
|
+
in the `tests` directory.
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@staticmethod
|
|
53
|
+
def get_path_info(for_what: str):
|
|
54
|
+
if for_what == "plugin": return PLUGIN_INFO
|
|
55
|
+
if for_what == "io": return IO_INFO
|
|
56
|
+
if for_what == "signal": return SIGNAL_INFO
|
|
57
|
+
if for_what == "engine": return ENGINE_INFO
|
|
58
|
+
if for_what == "generator": return GENERATOR_INFO
|
|
59
|
+
|
|
60
|
+
@staticmethod
|
|
61
|
+
def ask_questions(for_what: str, path_info: dict) -> dict:
|
|
62
|
+
"""Asks question about the template to be generated."""
|
|
63
|
+
print("----------------------")
|
|
64
|
+
print(for_what.upper())
|
|
65
|
+
print("----------------------")
|
|
66
|
+
module_name = questionary.text("Module name (snake_case): ").ask()
|
|
67
|
+
|
|
68
|
+
if module_name is None:
|
|
69
|
+
sys.exit(1)
|
|
70
|
+
|
|
71
|
+
if not module_name.endswith(".py"): # Adding extension
|
|
72
|
+
module_name = module_name + ".py"
|
|
73
|
+
# Checking if the module name already exists in the dump directory
|
|
74
|
+
if (path_info["template_dump_dp"] / module_name).exists():
|
|
75
|
+
print(f"⚠️ File already exists, choose another name.")
|
|
76
|
+
sys.exit(1)
|
|
77
|
+
|
|
78
|
+
class_name = questionary.text(f"Class name (CamelCase{for_what.capitalize()}): ").ask()
|
|
79
|
+
if class_name is None:
|
|
80
|
+
sys.exit(1)
|
|
81
|
+
|
|
82
|
+
author_name = questionary.text("Author name: ").ask()
|
|
83
|
+
if author_name is None:
|
|
84
|
+
sys.exit(1)
|
|
85
|
+
|
|
86
|
+
author_email = questionary.text("Author email: ").ask()
|
|
87
|
+
if author_email is None:
|
|
88
|
+
sys.exit(1)
|
|
89
|
+
|
|
90
|
+
answers = {"for_what": for_what, "module_name": module_name, "class_name": class_name, "author_name": author_name, "author_email": author_email, "date_created": date.today()}
|
|
91
|
+
|
|
92
|
+
return answers
|
|
93
|
+
|
|
94
|
+
@staticmethod
|
|
95
|
+
def load_template_file(template_fp: Path) -> str:
|
|
96
|
+
"""Loads template file."""
|
|
97
|
+
if not template_fp.exists():
|
|
98
|
+
print(f"❌ Template not found: {template_fp}")
|
|
99
|
+
sys.exit(1)
|
|
100
|
+
|
|
101
|
+
template_code = template_fp.read_text()
|
|
102
|
+
|
|
103
|
+
return template_code
|
|
104
|
+
|
|
105
|
+
@staticmethod
|
|
106
|
+
def fill_placeholders(template_code: str, placehoders_dict: dict) -> str:
|
|
107
|
+
"""Fills placeholder in the template with the user input from CLI."""
|
|
108
|
+
template_code = template_code.format(**placehoders_dict) # Fill placeholders
|
|
109
|
+
return template_code
|
|
110
|
+
|
|
111
|
+
@staticmethod
|
|
112
|
+
def save_file(content: str, output_path: Path) -> None:
|
|
113
|
+
"""Saves file in the correct directory with the right tempalate content."""
|
|
114
|
+
output_path.parent.mkdir(parents=True, exist_ok=True)
|
|
115
|
+
output_path.write_text(content)
|
|
116
|
+
|
|
117
|
+
# Generating a corresponding test file too
|
|
118
|
+
what_for = output_path.parent.name # plugins, generators, ...
|
|
119
|
+
module_name = output_path.name # this.py
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
@staticmethod
|
|
123
|
+
def create_template(for_what: str) -> None:
|
|
124
|
+
|
|
125
|
+
# Load correct path location info for the templates and where to dump the files
|
|
126
|
+
path_info: dict = TemplateGenerator.get_path_info(for_what)
|
|
127
|
+
|
|
128
|
+
# Ask basic questions to create the template for `plugin`, `generator`, ...
|
|
129
|
+
answers: dict = TemplateGenerator.ask_questions(for_what, path_info)
|
|
130
|
+
|
|
131
|
+
# Load the correct template file and test file
|
|
132
|
+
template_code: str = TemplateGenerator.load_template_file(template_fp=path_info['template_fp'])
|
|
133
|
+
test_code: str = TemplateGenerator.load_template_file(template_fp=path_info['test_template_fp'])
|
|
134
|
+
|
|
135
|
+
# Update the dynamic values based on the answers
|
|
136
|
+
template_code: str = TemplateGenerator.fill_placeholders(template_code, answers)
|
|
137
|
+
test_code: str = TemplateGenerator.fill_placeholders(test_code, answers)
|
|
138
|
+
|
|
139
|
+
# Save it to a file and put it in the correct folder
|
|
140
|
+
TemplateGenerator.save_file(content=template_code, output_path=path_info['template_dump_dp'] / answers['module_name'])
|
|
141
|
+
TemplateGenerator.save_file(content=test_code, output_path=path_info['test_template_dump_dp'] / answers['module_name'])
|
|
142
|
+
|
|
143
|
+
print(f"✅ {for_what}:", "open " + str(path_info['template_dump_dp'] / answers['module_name']))
|
|
144
|
+
print(f"✅ test:", "open " + str(path_info['test_template_dump_dp'] / answers['module_name']))
|
|
@@ -20,10 +20,12 @@ def main():
|
|
|
20
20
|
create_parser = subparsers.add_parser("create", help="Create new Modusa components")
|
|
21
21
|
create_subparsers = create_parser.add_subparsers(dest="what", required=True)
|
|
22
22
|
|
|
23
|
-
create_subparsers.add_parser("engine", help="Create a new engine class").set_defaults(func=lambda:TemplateGenerator.create_template("
|
|
24
|
-
create_subparsers.add_parser("plugin", help="Create a new plugin class").set_defaults(func=lambda:TemplateGenerator.create_template("
|
|
25
|
-
create_subparsers.add_parser("signal", help="Create a new signal class").set_defaults(func=lambda:TemplateGenerator.create_template("
|
|
26
|
-
create_subparsers.add_parser("generator", help="Create a new signal generator class").set_defaults(func=lambda:TemplateGenerator.create_template("
|
|
23
|
+
create_subparsers.add_parser("engine", help="Create a new engine class").set_defaults(func=lambda:TemplateGenerator.create_template("engine"))
|
|
24
|
+
create_subparsers.add_parser("plugin", help="Create a new plugin class").set_defaults(func=lambda:TemplateGenerator.create_template("plugin"))
|
|
25
|
+
create_subparsers.add_parser("signal", help="Create a new signal class").set_defaults(func=lambda:TemplateGenerator.create_template("signal"))
|
|
26
|
+
create_subparsers.add_parser("generator", help="Create a new signal generator class").set_defaults(func=lambda:TemplateGenerator.create_template("generator"))
|
|
27
|
+
create_subparsers.add_parser("io", help="Create a new IO class").set_defaults(func=lambda:TemplateGenerator.create_template("io"))
|
|
28
|
+
|
|
27
29
|
|
|
28
30
|
# --- LIST group ---
|
|
29
31
|
list_parser = subparsers.add_parser("list", help="List information about Modusa components")
|
|
@@ -3,20 +3,21 @@
|
|
|
3
3
|
|
|
4
4
|
from modusa import excp
|
|
5
5
|
from modusa.decorators import validate_args_type
|
|
6
|
-
from modusa.engines
|
|
6
|
+
from modusa.engines import ModusaEngine
|
|
7
7
|
from typing import Any
|
|
8
8
|
|
|
9
|
+
|
|
9
10
|
class {class_name}(ModusaEngine):
|
|
10
11
|
"""
|
|
11
|
-
|
|
12
|
+
|
|
12
13
|
"""
|
|
13
14
|
|
|
14
15
|
#--------Meta Information----------
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
_name = ""
|
|
17
|
+
_description = ""
|
|
18
|
+
_author_name = "{author_name}"
|
|
19
|
+
_author_email = "{author_email}"
|
|
20
|
+
_created_at = "{date_created}"
|
|
20
21
|
#----------------------------------
|
|
21
22
|
|
|
22
23
|
def __init__(self):
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
from modusa import excp
|
|
4
5
|
from modusa.decorators import validate_args_type
|
|
5
|
-
from modusa.generators
|
|
6
|
+
from modusa.generators import ModusaGenerator
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
class {class_name}(ModusaGenerator):
|
|
@@ -11,16 +12,13 @@ class {class_name}(ModusaGenerator):
|
|
|
11
12
|
"""
|
|
12
13
|
|
|
13
14
|
#--------Meta Information----------
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
_name = ""
|
|
16
|
+
_description = ""
|
|
17
|
+
_author_name = "{author_name}"
|
|
18
|
+
_author_email = "{author_email}"
|
|
19
|
+
_created_at = "{date_created}"
|
|
19
20
|
#----------------------------------
|
|
20
21
|
|
|
21
22
|
def __init__(self):
|
|
22
23
|
super().__init__()
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
def generate(self) -> Any:
|
|
26
|
-
pass
|
|
24
|
+
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
from modusa import excp
|
|
5
|
+
from modusa.decorators import validate_args_type
|
|
6
|
+
from modusa.io import ModusaIO
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class {class_name}(ModusaIO):
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
#--------Meta Information----------
|
|
15
|
+
_name = ""
|
|
16
|
+
_description = ""
|
|
17
|
+
_author_name = "{author_name}"
|
|
18
|
+
_author_email = "{author_email}"
|
|
19
|
+
_created_at = "{date_created}"
|
|
20
|
+
#----------------------------------
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
from modusa
|
|
4
|
+
from modusa import excp
|
|
5
5
|
from modusa.decorators import immutable_property, validate_args_type, plugin_safety_check
|
|
6
|
+
from modusa.plugins import ModusaPlugin
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
class {class_name}(ModusaPlugin):
|
|
@@ -11,11 +12,11 @@ class {class_name}(ModusaPlugin):
|
|
|
11
12
|
"""
|
|
12
13
|
|
|
13
14
|
#--------Meta Information----------
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
_name = ""
|
|
16
|
+
_description = ""
|
|
17
|
+
_author_name = "{author_name}"
|
|
18
|
+
_author_email = "{author_email}"
|
|
19
|
+
_created_at = "{date_created}"
|
|
19
20
|
#----------------------------------
|
|
20
21
|
|
|
21
22
|
def __init__(self):
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
from modusa import excp
|
|
5
|
+
from modusa.decorators import immutable_property, validate_args_type
|
|
6
|
+
from modusa.signals.base import ModusaSignal
|
|
7
|
+
from typing import Self, Any
|
|
8
|
+
import numpy as np
|
|
9
|
+
|
|
10
|
+
class {class_name}(ModusaSignal):
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
#--------Meta Information----------
|
|
16
|
+
_name = ""
|
|
17
|
+
_description = ""
|
|
18
|
+
_author_name = "{author_name}"
|
|
19
|
+
_author_email = "{author_email}"
|
|
20
|
+
_created_at = "{date_created}"
|
|
21
|
+
#----------------------------------
|
|
22
|
+
|
|
23
|
+
@validate_args_type()
|
|
24
|
+
def __init__(self):
|
|
25
|
+
super().__init__() # Instantiating `ModusaSignal` class
|
|
26
|
+
|
|
27
|
+
self.title = "" # This title will be used as plot title by default
|
|
28
|
+
|
|
29
|
+
#----------------------
|
|
30
|
+
# Properties
|
|
31
|
+
#----------------------
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
#----------------------
|
|
39
|
+
# Tools
|
|
40
|
+
#----------------------
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
#--------Meta Information----------
|
|
5
|
+
_class_name = "{class_name}"
|
|
6
|
+
_author_name = "{author_name}"
|
|
7
|
+
_author_email = "{author_email}"
|
|
8
|
+
_created_at = "{date_created}"
|
|
9
|
+
#----------------------------------
|
|
10
|
+
|
|
11
|
+
from modusa.{for_what}s import {class_name}
|
|
Binary file
|