mtcli 3.7.0.dev5__tar.gz → 3.7.0.dev6__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 (73) hide show
  1. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/PKG-INFO +1 -1
  2. mtcli-3.7.0.dev6/mtcli/plugin_loader.py +123 -0
  3. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/pyproject.toml +1 -1
  4. mtcli-3.7.0.dev5/mtcli/plugin_loader - Copia.py +0 -98
  5. mtcli-3.7.0.dev5/mtcli/plugin_loader.py +0 -226
  6. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/LICENSE +0 -0
  7. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/README.md +0 -0
  8. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/__init__.py +0 -0
  9. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/cli.py +0 -0
  10. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/commands/__init__.py +0 -0
  11. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/commands/bars.py +0 -0
  12. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/commands/conf.py +0 -0
  13. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/conecta.py +0 -0
  14. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/conf.py +0 -0
  15. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/config_registre.py +0 -0
  16. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/data/__init__.py +0 -0
  17. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/data/base.py +0 -0
  18. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/data/csv.py +0 -0
  19. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/data/mt5.py +0 -0
  20. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/database.py +0 -0
  21. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/domain/__init__.py +0 -0
  22. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/domain/timeframe.py +0 -0
  23. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/logger.py +0 -0
  24. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/marketdata/__init__.py +0 -0
  25. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/marketdata/tick_cache.py +0 -0
  26. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/marketdata/tick_repository.py +0 -0
  27. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/models/__init__.py +0 -0
  28. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/models/bar_model.py +0 -0
  29. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/models/bars_model.py +0 -0
  30. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/models/chart_model.py +0 -0
  31. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/models/conf_model.py +0 -0
  32. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/models/consecutive_bars_model.py +0 -0
  33. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/models/rates_model.py +0 -0
  34. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/models/signals_model.py +0 -0
  35. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/models/unconsecutive_bar_model.py +0 -0
  36. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/mt5_context.py +0 -0
  37. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/plugin.py +0 -0
  38. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/plugin_manager.py +0 -0
  39. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/plugins/__init__.py +0 -0
  40. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/plugins/exemplo.py-dist +0 -0
  41. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/plugins/media_movel/__init__.py +0 -0
  42. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/plugins/media_movel/cli.py +0 -0
  43. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/plugins/media_movel/conf.py +0 -0
  44. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/plugins/media_movel/models/__init__.py +0 -0
  45. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/plugins/media_movel/models/model_media_movel.py +0 -0
  46. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/plugins/media_movel/tests/__init__.py +0 -0
  47. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/plugins/media_movel/tests/test_mm.py +0 -0
  48. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/plugins/media_movel/tests/test_model_media_movel.py +0 -0
  49. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/plugins/range_medio/__init__.py +0 -0
  50. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/plugins/range_medio/cli.py +0 -0
  51. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/plugins/range_medio/conf.py +0 -0
  52. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/plugins/range_medio/models/__init__.py +0 -0
  53. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/plugins/range_medio/models/average_range_model.py +0 -0
  54. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/plugins/range_medio/tests/__init__.py +0 -0
  55. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/plugins/range_medio/tests/test_rm.py +0 -0
  56. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/plugins/volume_medio/__init__.py +0 -0
  57. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/plugins/volume_medio/cli.py +0 -0
  58. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/plugins/volume_medio/conf.py +0 -0
  59. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/plugins/volume_medio/models/__init__.py +0 -0
  60. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/plugins/volume_medio/models/model_average_volume.py +0 -0
  61. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/plugins/volume_medio/tests/__init__.py +0 -0
  62. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/plugins/volume_medio/tests/test_vm.py +0 -0
  63. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/views/__init__.py +0 -0
  64. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/views/close_view.py +0 -0
  65. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/views/full_view.py +0 -0
  66. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/views/high_view.py +0 -0
  67. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/views/low_view.py +0 -0
  68. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/views/min_view.py +0 -0
  69. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/views/open_view.py +0 -0
  70. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/views/ranges_view.py +0 -0
  71. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/views/rates_view.py +0 -0
  72. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/views/vars_view.py +0 -0
  73. {mtcli-3.7.0.dev5 → mtcli-3.7.0.dev6}/mtcli/views/volumes_view.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mtcli
3
- Version: 3.7.0.dev5
3
+ Version: 3.7.0.dev6
4
4
  Summary: Aplicativo CLI para exibir gráficos do MetaTrader 5 screen reader friendly
5
5
  License-Expression: MIT
6
6
  License-File: LICENSE
@@ -0,0 +1,123 @@
1
+ """
2
+ Sistema de carregamento de plugins do mtcli.
3
+
4
+ Descobre e registra plugins instalados via entry points.
5
+
6
+ Plugins devem declarar:
7
+
8
+ [project.entry-points."mtcli.plugins"]
9
+ nome = "pacote.plugin:register"
10
+
11
+ O plugin pode fornecer:
12
+
13
+ 1. register(cli)
14
+ 2. um objeto click.Command
15
+ """
16
+
17
+ from __future__ import annotations
18
+
19
+ from typing import Iterable, List
20
+
21
+ import click
22
+
23
+ try:
24
+ from importlib.metadata import EntryPoint, entry_points
25
+ except ImportError: # pragma: no cover
26
+ from importlib_metadata import EntryPoint, entry_points
27
+
28
+ from mtcli.logger import setup_logger
29
+
30
+
31
+ logger = setup_logger(__name__)
32
+
33
+ PLUGIN_GROUP = "mtcli.plugins"
34
+
35
+
36
+ def discover_plugins() -> Iterable[EntryPoint]:
37
+ """
38
+ Descobre plugins registrados via entry points.
39
+
40
+ Returns
41
+ -------
42
+ Iterable[EntryPoint]
43
+ Entry points encontrados.
44
+ """
45
+
46
+ try:
47
+ eps = entry_points()
48
+
49
+ if hasattr(eps, "select"):
50
+ plugins = eps.select(group=PLUGIN_GROUP)
51
+ else:
52
+ plugins = eps.get(PLUGIN_GROUP, [])
53
+
54
+ logger.debug("Plugins descobertos: %s", [ep.name for ep in plugins])
55
+
56
+ return plugins
57
+
58
+ except Exception as exc:
59
+ logger.exception("Erro ao descobrir plugins: %s", exc)
60
+ return []
61
+
62
+
63
+ def register_plugin(cli: click.Group, ep: EntryPoint) -> None:
64
+ """
65
+ Carrega e registra um plugin individual.
66
+ """
67
+
68
+ logger.debug("Carregando plugin: %s -> %s", ep.name, ep.value)
69
+
70
+ plugin = ep.load()
71
+
72
+ if callable(plugin) and not isinstance(plugin, click.Command):
73
+
74
+ plugin(cli)
75
+
76
+ logger.info("Plugin registrado via register(): %s", ep.name)
77
+
78
+ elif isinstance(plugin, click.Command):
79
+
80
+ cli.add_command(plugin)
81
+
82
+ logger.info("Plugin registrado como comando: %s", ep.name)
83
+
84
+ else:
85
+
86
+ raise TypeError(
87
+ f"Plugin '{ep.name}' inválido: "
88
+ "não é click.Command nem função register(cli)"
89
+ )
90
+
91
+
92
+ def load_plugins(cli: click.Group) -> List[str]:
93
+ """
94
+ Descobre e carrega todos os plugins instalados.
95
+ """
96
+
97
+ loaded: List[str] = []
98
+ seen = set()
99
+
100
+ for ep in discover_plugins():
101
+
102
+ if ep.name in seen:
103
+ logger.warning("Plugin duplicado ignorado: %s", ep.name)
104
+ continue
105
+
106
+ try:
107
+
108
+ register_plugin(cli, ep)
109
+
110
+ seen.add(ep.name)
111
+ loaded.append(ep.name)
112
+
113
+ except Exception as exc:
114
+
115
+ logger.exception(
116
+ "Falha ao carregar plugin '%s': %s",
117
+ ep.name,
118
+ exc,
119
+ )
120
+
121
+ logger.info("Total de plugins carregados: %d", len(loaded))
122
+
123
+ return loaded
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "mtcli"
3
- version = "3.7.0.dev5"
3
+ version = "3.7.0.dev6"
4
4
  description = "Aplicativo CLI para exibir gráficos do MetaTrader 5 screen reader friendly"
5
5
  authors = [
6
6
  {name = "Valmir França da Silva",email = "vfranca3@gmail.com"}
@@ -1,98 +0,0 @@
1
- """
2
- Sistema de carregamento de plugins do mtcli.
3
-
4
- Este módulo carrega automaticamente:
5
-
6
- 1. Plugins internos localizados em `mtcli.plugins`
7
- 2. Plugins externos registrados via entry points `mtcli.plugins`
8
-
9
- Plugins devem expor uma função:
10
-
11
- register(cli)
12
-
13
- onde `cli` é o grupo principal do Click.
14
- """
15
-
16
- import importlib
17
- import pkgutil
18
-
19
- import click
20
-
21
- try:
22
- from importlib.metadata import entry_points
23
- except ImportError: # Python < 3.10
24
- from importlib_metadata import entry_points
25
-
26
- import mtcli.plugins
27
-
28
-
29
- def load_internal_plugins(cli: click.Group) -> None:
30
- """
31
- Carrega plugins internos do pacote `mtcli.plugins`.
32
-
33
- Cada módulo encontrado deve expor a função:
34
-
35
- register(cli)
36
-
37
- Args:
38
- cli: grupo principal do Click.
39
- """
40
-
41
- for module_info in pkgutil.iter_modules(mtcli.plugins.__path__):
42
-
43
- module_name = f"mtcli.plugins.{module_info.name}"
44
-
45
- module = importlib.import_module(module_name)
46
-
47
- if hasattr(module, "register"):
48
- module.register(cli)
49
-
50
-
51
- def load_external_plugins(cli: click.Group) -> None:
52
- """
53
- Carrega plugins externos instalados via entry points.
54
-
55
- Os plugins devem declarar no pyproject.toml:
56
-
57
- [project.entry-points."mtcli.plugins"]
58
- nome = "pacote.plugin:register"
59
-
60
- Args:
61
- cli: grupo principal do Click.
62
- """
63
-
64
- eps = entry_points()
65
-
66
- plugins = (
67
- eps.select(group="mtcli.plugins")
68
- if hasattr(eps, "select")
69
- else eps.get("mtcli.plugins", [])
70
- )
71
-
72
- for ep in plugins:
73
-
74
- plugin = ep.load()
75
-
76
- if callable(plugin) and not isinstance(plugin, click.Command):
77
- plugin(cli)
78
-
79
- elif isinstance(plugin, click.Command):
80
- cli.add_command(plugin)
81
-
82
- else:
83
- raise TypeError(
84
- f"Plugin {ep.name} inválido: deve ser um comando Click ou função register."
85
- )
86
-
87
-
88
- def load_plugins(cli: click.Group) -> None:
89
- """
90
- Carrega todos os plugins (internos e externos).
91
-
92
- Args:
93
- cli: grupo principal do Click.
94
- """
95
-
96
- load_internal_plugins(cli)
97
- load_external_plugins(cli)
98
-
@@ -1,226 +0,0 @@
1
- """
2
- Sistema de carregamento de plugins do mtcli.
3
-
4
- Este módulo descobre e registra plugins de duas fontes:
5
-
6
- 1. Plugins internos localizados em ``mtcli.plugins``
7
- 2. Plugins externos registrados via entry points ``mtcli.plugins``
8
-
9
- Plugins podem expor:
10
-
11
- função ``register(cli)``
12
- objeto ``click.Command``
13
-
14
- Entry point exemplo:
15
-
16
- [project.entry-points."mtcli.plugins"]
17
- renko = "mtcli_renko.plugin:register"
18
- """
19
-
20
- from __future__ import annotations
21
-
22
- import importlib
23
- import logging
24
- import pkgutil
25
- from typing import Iterable, List
26
-
27
- import click
28
-
29
- try:
30
- from importlib.metadata import EntryPoint, entry_points
31
- except ImportError: # pragma: no cover
32
- from importlib_metadata import EntryPoint, entry_points
33
-
34
- import mtcli.plugins
35
-
36
-
37
- logger = logging.getLogger(__name__)
38
-
39
- PLUGIN_GROUP = "mtcli.plugins"
40
-
41
-
42
- # ---------------------------------------------------------
43
- # Descoberta de plugins externos
44
- # ---------------------------------------------------------
45
-
46
-
47
- def discover_external_plugins() -> Iterable[EntryPoint]:
48
- """
49
- Descobre plugins externos via entry points.
50
-
51
- Returns
52
- -------
53
- Iterable[EntryPoint]
54
- Entry points encontrados no grupo ``mtcli.plugins``.
55
- """
56
-
57
- try:
58
- eps = entry_points()
59
-
60
- if hasattr(eps, "select"):
61
- return eps.select(group=PLUGIN_GROUP)
62
-
63
- return eps.get(PLUGIN_GROUP, [])
64
-
65
- except Exception as exc: # pragma: no cover
66
- logger.error("Erro ao descobrir plugins externos: %s", exc)
67
- return []
68
-
69
-
70
- # ---------------------------------------------------------
71
- # Registro de plugin
72
- # ---------------------------------------------------------
73
-
74
-
75
- def register_plugin(cli: click.Group, plugin, name: str) -> None:
76
- """
77
- Registra um plugin no CLI.
78
-
79
- O plugin pode ser:
80
-
81
- função ``register(cli)``
82
- objeto ``click.Command``
83
-
84
- Parameters
85
- ----------
86
- cli : click.Group
87
- CLI principal.
88
- plugin : Any
89
- Objeto do plugin carregado.
90
- name : str
91
- Nome do plugin.
92
- """
93
-
94
- if callable(plugin) and not isinstance(plugin, click.Command):
95
- plugin(cli)
96
- logger.debug("Plugin '%s' registrado via register()", name)
97
-
98
- elif isinstance(plugin, click.Command):
99
- cli.add_command(plugin)
100
- logger.debug("Plugin '%s' registrado como comando", name)
101
-
102
- else:
103
- raise TypeError(
104
- f"Plugin '{name}' inválido: não é click.Command nem register(cli)"
105
- )
106
-
107
-
108
- # ---------------------------------------------------------
109
- # Plugins internos
110
- # ---------------------------------------------------------
111
-
112
-
113
- def load_internal_plugins(cli: click.Group) -> List[str]:
114
- """
115
- Carrega plugins internos do pacote ``mtcli.plugins``.
116
-
117
- Cada módulo deve expor a função:
118
-
119
- register(cli)
120
-
121
- Returns
122
- -------
123
- list[str]
124
- Lista de plugins carregados.
125
- """
126
-
127
- loaded = []
128
-
129
- for module_info in pkgutil.iter_modules(mtcli.plugins.__path__):
130
-
131
- module_name = f"mtcli.plugins.{module_info.name}"
132
-
133
- try:
134
- module = importlib.import_module(module_name)
135
-
136
- if hasattr(module, "register"):
137
- module.register(cli)
138
- loaded.append(module_info.name)
139
-
140
- logger.debug("Plugin interno carregado: %s", module_info.name)
141
-
142
- except Exception as exc:
143
- logger.error(
144
- "Falha ao carregar plugin interno '%s': %s",
145
- module_info.name,
146
- exc,
147
- )
148
-
149
- return loaded
150
-
151
-
152
- # ---------------------------------------------------------
153
- # Plugins externos
154
- # ---------------------------------------------------------
155
-
156
-
157
- def load_external_plugins(cli: click.Group) -> List[str]:
158
- """
159
- Carrega plugins externos instalados via entry points.
160
-
161
- Returns
162
- -------
163
- list[str]
164
- Lista de plugins carregados.
165
- """
166
-
167
- loaded = []
168
- seen = set()
169
-
170
- for ep in discover_external_plugins():
171
-
172
- if ep.name in seen:
173
- logger.warning("Plugin duplicado ignorado: %s", ep.name)
174
- continue
175
-
176
- try:
177
- plugin = ep.load()
178
-
179
- register_plugin(cli, plugin, ep.name)
180
-
181
- loaded.append(ep.name)
182
- seen.add(ep.name)
183
-
184
- except Exception as exc:
185
- logger.error(
186
- "Falha ao carregar plugin '%s': %s",
187
- ep.name,
188
- exc,
189
- )
190
-
191
- return loaded
192
-
193
-
194
- # ---------------------------------------------------------
195
- # Loader principal
196
- # ---------------------------------------------------------
197
-
198
-
199
- def load_plugins(cli: click.Group) -> List[str]:
200
- """
201
- Carrega todos os plugins do mtcli.
202
-
203
- Isso inclui:
204
-
205
- • plugins internos
206
- • plugins externos
207
-
208
- Parameters
209
- ----------
210
- cli : click.Group
211
- CLI principal.
212
-
213
- Returns
214
- -------
215
- list[str]
216
- Lista com todos os plugins carregados.
217
- """
218
-
219
- loaded = []
220
-
221
- loaded.extend(load_internal_plugins(cli))
222
- loaded.extend(load_external_plugins(cli))
223
-
224
- logger.info("Plugins carregados: %d", len(loaded))
225
-
226
- return loaded
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes