meerschaum 2.1.2__py3-none-any.whl → 2.1.3.dev3__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.
- meerschaum/__init__.py +10 -4
- meerschaum/_internal/docs/index.py +32 -37
- meerschaum/_internal/entry.py +3 -0
- meerschaum/_internal/shell/Shell.py +106 -78
- meerschaum/_internal/shell/ShellCompleter.py +8 -4
- meerschaum/actions/__init__.py +2 -1
- meerschaum/actions/reload.py +2 -5
- meerschaum/actions/show.py +72 -1
- meerschaum/actions/sync.py +45 -17
- meerschaum/config/_edit.py +10 -34
- meerschaum/config/_formatting.py +4 -0
- meerschaum/config/_version.py +1 -1
- meerschaum/config/static/__init__.py +2 -0
- meerschaum/connectors/sql/_pipes.py +26 -20
- meerschaum/core/Pipe/_data.py +11 -11
- meerschaum/core/Pipe/_fetch.py +4 -4
- meerschaum/plugins/_Plugin.py +6 -8
- meerschaum/plugins/__init__.py +76 -1
- meerschaum/utils/__init__.py +21 -6
- meerschaum/utils/daemon/__init__.py +1 -1
- meerschaum/utils/formatting/__init__.py +4 -0
- meerschaum/utils/formatting/_pipes.py +2 -2
- meerschaum/utils/get_pipes.py +1 -1
- meerschaum/utils/misc.py +2 -1
- meerschaum/utils/packages/__init__.py +46 -7
- meerschaum/utils/schedule.py +1 -1
- meerschaum/utils/venv/__init__.py +22 -3
- {meerschaum-2.1.2.dist-info → meerschaum-2.1.3.dev3.dist-info}/METADATA +2 -2
- {meerschaum-2.1.2.dist-info → meerschaum-2.1.3.dev3.dist-info}/RECORD +35 -35
- {meerschaum-2.1.2.dist-info → meerschaum-2.1.3.dev3.dist-info}/LICENSE +0 -0
- {meerschaum-2.1.2.dist-info → meerschaum-2.1.3.dev3.dist-info}/NOTICE +0 -0
- {meerschaum-2.1.2.dist-info → meerschaum-2.1.3.dev3.dist-info}/WHEEL +0 -0
- {meerschaum-2.1.2.dist-info → meerschaum-2.1.3.dev3.dist-info}/entry_points.txt +0 -0
- {meerschaum-2.1.2.dist-info → meerschaum-2.1.3.dev3.dist-info}/top_level.txt +0 -0
- {meerschaum-2.1.2.dist-info → meerschaum-2.1.3.dev3.dist-info}/zip-safe +0 -0
meerschaum/__init__.py
CHANGED
@@ -22,25 +22,31 @@ import atexit
|
|
22
22
|
from meerschaum.utils.typing import SuccessTuple
|
23
23
|
from meerschaum.core.Pipe import Pipe
|
24
24
|
from meerschaum.plugins import Plugin
|
25
|
-
from meerschaum.utils import get_pipes
|
26
25
|
from meerschaum.utils.venv import Venv
|
26
|
+
from meerschaum.connectors import get_connector
|
27
|
+
from meerschaum.utils import get_pipes
|
27
28
|
from meerschaum.utils.formatting import pprint
|
28
29
|
from meerschaum._internal.docs import index as __doc__
|
29
|
-
from meerschaum.connectors import get_connector
|
30
30
|
from meerschaum.config import __version__, get_config
|
31
31
|
from meerschaum.utils.packages import attempt_import
|
32
32
|
from meerschaum.__main__ import _close_pools
|
33
33
|
|
34
34
|
atexit.register(_close_pools)
|
35
35
|
|
36
|
-
__pdoc__ = {'gui': False, 'api': False, 'core': False,}
|
36
|
+
__pdoc__ = {'gui': False, 'api': False, 'core': False, '_internal': False}
|
37
37
|
__all__ = (
|
38
|
-
"Pipe",
|
39
38
|
"get_pipes",
|
40
39
|
"get_connector",
|
40
|
+
"get_config",
|
41
|
+
"Pipe",
|
41
42
|
"Plugin",
|
42
43
|
"Venv",
|
43
44
|
"Plugin",
|
44
45
|
"pprint",
|
45
46
|
"attempt_import",
|
47
|
+
"actions",
|
48
|
+
"config",
|
49
|
+
"connectors",
|
50
|
+
"plugins",
|
51
|
+
"utils",
|
46
52
|
)
|
@@ -3,7 +3,7 @@
|
|
3
3
|
# vim:fenc=utf-8
|
4
4
|
|
5
5
|
"""
|
6
|
-
<img src="https://meerschaum.io/assets/banner_1920x320.png" alt="Meerschaum banner"/>
|
6
|
+
<img src="https://meerschaum.io/assets/banner_1920x320.png" alt="Meerschaum banner" style="width: 100%;"/>
|
7
7
|
|
8
8
|
| PyPI | GitHub | Info | Stats |
|
9
9
|
|---|---|---|---|
|
@@ -28,17 +28,6 @@ Data engineering often gets in analysts' way, and when work needs to get done, e
|
|
28
28
|
|
29
29
|
Rather than copy / pasting your ETL scripts, simply build pipes with Meerschaum! [Meerschaum gives you the tools to design your data streams how you like](https://towardsdatascience.com/easy-time-series-etl-for-data-scientists-with-meerschaum-5aade339b398) ― and don't worry — you can always incorporate Meerschaum into your existing systems!
|
30
30
|
|
31
|
-
#### Want to Learn More?
|
32
|
-
|
33
|
-
You can find a wealth of information at [meerschaum.io](https://meerschaum.io)!
|
34
|
-
|
35
|
-
Additionally, below are several articles published about Meerschaum:
|
36
|
-
|
37
|
-
- Interview featured in [*Console 100 - The Open Source Newsletter*](https://console.substack.com/p/console-100)
|
38
|
-
- [*A Data Scientist's Guide to Fetching COVID-19 Data in 2022*](https://towardsdatascience.com/a-data-scientists-guide-to-fetching-covid-19-data-in-2022-d952b4697) (Towards Data Science)
|
39
|
-
- [*Time-Series ETL with Meerschaum*](https://towardsdatascience.com/easy-time-series-etl-for-data-scientists-with-meerschaum-5aade339b398) (Towards Data Science)
|
40
|
-
- [*How I automatically extract my M1 Finance transactions*](https://bmeares.medium.com/how-i-automatically-extract-my-m1-finance-transactions-b43cef857bc7)
|
41
|
-
|
42
31
|
## Features
|
43
32
|
|
44
33
|
- 📊 **Built for Data Scientists and Analysts**
|
@@ -58,8 +47,8 @@ Additionally, below are several articles published about Meerschaum:
|
|
58
47
|
- Manage your database connections with [Meerschaum connectors](https://meerschaum.io/reference/connectors/)
|
59
48
|
- Utility commands with sensible syntax let you control many pipes with grace.
|
60
49
|
- 💼 **Portable from the Start**
|
61
|
-
- The environment
|
62
|
-
- No dependencies required; anything needed will be installed into
|
50
|
+
- The environment variables `$MRSM_ROOT_DIR`, `$MRSM_PLUGINS_DIR`, and `$MRSM_VENVS_DIR` let you emulate multiple installations and group together your [instances](https://meerschaum.io/reference/connectors/#instances-and-repositories).
|
51
|
+
- No dependencies required; anything needed will be installed into virtual environments.
|
63
52
|
- [Specify required packages for your plugins](https://meerschaum.io/reference/plugins/writing-plugins/), and users will get those packages in a virtual environment.
|
64
53
|
|
65
54
|
## Installation
|
@@ -81,28 +70,29 @@ Please visit [meerschaum.io](https://meerschaum.io) for setup, usage, and troubl
|
|
81
70
|
```python
|
82
71
|
>>> import meerschaum as mrsm
|
83
72
|
>>> pipe = mrsm.Pipe("plugin:noaa", "weather")
|
84
|
-
>>>
|
85
|
-
>>> df
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
73
|
+
>>> cols_to_select = ['timestamp', 'station', 'temperature (degC)']
|
74
|
+
>>> df = pipe.get_data(cols_to_select, begin='2023-11-15', end='2023-11-20')
|
75
|
+
>>> df
|
76
|
+
timestamp station temperature (degC)
|
77
|
+
0 2023-11-15 00:52:00 KATL 16.1
|
78
|
+
1 2023-11-15 00:52:00 KCLT 11.7
|
79
|
+
2 2023-11-15 00:53:00 KGMU 15.0
|
80
|
+
3 2023-11-15 00:54:00 KCEU 13.9
|
81
|
+
4 2023-11-15 01:52:00 KATL 15.6
|
82
|
+
.. ... ... ...
|
83
|
+
535 2023-11-19 22:54:00 KCEU 15.6
|
84
|
+
536 2023-11-19 23:52:00 KATL 16.7
|
85
|
+
537 2023-11-19 23:52:00 KCLT 13.9
|
86
|
+
538 2023-11-19 23:53:00 KGMU 15.6
|
87
|
+
539 2023-11-19 23:54:00 KCEU 15.0
|
88
|
+
|
89
|
+
[540 rows x 3 columns]
|
100
90
|
>>>
|
101
91
|
```
|
102
92
|
|
103
93
|
## Plugins
|
104
94
|
|
105
|
-
|
95
|
+
Check out the [Awesome Meerschaum list](https://github.com/bmeares/awesome-meerschaum) for a list of community plugins as well as the [public plugins repository](https://api.mrsm.io/dash/plugins).
|
106
96
|
|
107
97
|
For details on installing, using, and writing plugins, check out the [plugins documentation](https://meerschaum.io/reference/plugins/types-of-plugins) at [meerschaum.io](https://meerschaum.io).
|
108
98
|
|
@@ -123,12 +113,17 @@ def register(pipe, **kw):
|
|
123
113
|
}
|
124
114
|
|
125
115
|
def fetch(pipe, **kw):
|
126
|
-
import
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
116
|
+
import random
|
117
|
+
from datetime import datetime
|
118
|
+
docs = [
|
119
|
+
{
|
120
|
+
'dt': datetime.now(),
|
121
|
+
'id': i,
|
122
|
+
'val': random.ranint(0, 200),
|
123
|
+
}
|
124
|
+
for i in range(random.randint(0, 100))
|
125
|
+
]
|
126
|
+
return docs
|
132
127
|
```
|
133
128
|
|
134
129
|
## Support Meerschaum's Development
|
meerschaum/_internal/entry.py
CHANGED
@@ -118,6 +118,7 @@ def entry_with_args(
|
|
118
118
|
return result
|
119
119
|
|
120
120
|
|
121
|
+
_shells = []
|
121
122
|
_shell = None
|
122
123
|
def get_shell(
|
123
124
|
sysargs: Optional[List[str]] = None,
|
@@ -141,4 +142,6 @@ def get_shell(
|
|
141
142
|
_shell = shell_pkg.Shell(actions, sysargs=sysargs)
|
142
143
|
elif reload:
|
143
144
|
_shell.__init__()
|
145
|
+
|
146
|
+
_shells.append(_shell)
|
144
147
|
return _shell
|
@@ -64,6 +64,10 @@ reserved_completers = {
|
|
64
64
|
'instance', 'repo'
|
65
65
|
}
|
66
66
|
|
67
|
+
### To handle dynamic reloading, store shell attributes externally.
|
68
|
+
### This is because the shell object address gets lost upon reloads.
|
69
|
+
shell_attrs = {}
|
70
|
+
|
67
71
|
def _insert_shell_actions(
|
68
72
|
_shell: Optional['Shell'] = None,
|
69
73
|
actions: Optional[Dict[str, Callable[[Any], SuccessTuple]]] = None,
|
@@ -229,7 +233,7 @@ class Shell(cmd.Cmd):
|
|
229
233
|
pass
|
230
234
|
|
231
235
|
from meerschaum.config._paths import SHELL_HISTORY_PATH
|
232
|
-
|
236
|
+
shell_attrs['session'] = prompt_toolkit_shortcuts.PromptSession(
|
233
237
|
history = prompt_toolkit_history.FileHistory(str(SHELL_HISTORY_PATH)),
|
234
238
|
auto_suggest = ValidAutoSuggest(),
|
235
239
|
completer = ShellCompleter(),
|
@@ -260,15 +264,15 @@ class Shell(cmd.Cmd):
|
|
260
264
|
pass
|
261
265
|
|
262
266
|
### NOTE: custom actions must be added to the self._actions dictionary
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
267
|
+
shell_attrs['_actions'] = actions
|
268
|
+
shell_attrs['_sysargs'] = sysargs
|
269
|
+
shell_attrs['_actions']['instance'] = self.do_instance
|
270
|
+
shell_attrs['_actions']['repo'] = self.do_repo
|
271
|
+
shell_attrs['_actions']['debug'] = self.do_debug
|
272
|
+
shell_attrs['_update_bottom_toolbar'] = True
|
273
|
+
shell_attrs['_old_bottom_toolbar'] = ''
|
274
|
+
shell_attrs['debug'] = False
|
275
|
+
shell_attrs['_reload'] = True
|
272
276
|
self.load_config()
|
273
277
|
self.hidden_commands = []
|
274
278
|
### update hidden commands list (cmd2 only)
|
@@ -286,7 +290,7 @@ class Shell(cmd.Cmd):
|
|
286
290
|
from meerschaum.utils.misc import remove_ansi
|
287
291
|
from meerschaum.utils.formatting import CHARSET, ANSI, UNICODE, colored
|
288
292
|
|
289
|
-
if
|
293
|
+
if shell_attrs.get('intro', None) != '':
|
290
294
|
self.intro = get_config('shell', CHARSET, 'intro', patch=patch)
|
291
295
|
self.intro += '\n' + ''.join(
|
292
296
|
[' '
|
@@ -297,25 +301,30 @@ class Shell(cmd.Cmd):
|
|
297
301
|
) + 'v' + version
|
298
302
|
else:
|
299
303
|
self.intro = ""
|
300
|
-
|
301
|
-
|
302
|
-
self.
|
303
|
-
|
304
|
-
self.
|
305
|
-
|
304
|
+
shell_attrs['intro'] = self.intro
|
305
|
+
shell_attrs['_prompt'] = get_config('shell', CHARSET, 'prompt', patch=patch)
|
306
|
+
self.prompt = shell_attrs['_prompt']
|
307
|
+
shell_attrs['ruler'] = get_config('shell', CHARSET, 'ruler', patch=patch)
|
308
|
+
self.ruler = shell_attrs['ruler']
|
309
|
+
shell_attrs['close_message'] = get_config('shell', CHARSET, 'close_message', patch=patch)
|
310
|
+
self.close_message = shell_attrs['close_message']
|
311
|
+
shell_attrs['doc_header'] = get_config('shell', CHARSET, 'doc_header', patch=patch)
|
312
|
+
self.doc_header = shell_attrs['doc_header']
|
313
|
+
shell_attrs['undoc_header'] = get_config('shell', CHARSET, 'undoc_header', patch=patch)
|
314
|
+
self.undoc_header = shell_attrs['undoc_header']
|
306
315
|
|
307
316
|
if instance is None and self.__dict__.get('instance_keys', None) is None:
|
308
317
|
### create default instance and repository connectors
|
309
|
-
|
310
|
-
###
|
311
|
-
|
318
|
+
shell_attrs['instance_keys'] = remove_ansi(get_config('meerschaum', 'instance', patch=patch))
|
319
|
+
### instance is a stylized version of instance_keys
|
320
|
+
shell_attrs['instance'] = str(shell_attrs['instance_keys'])
|
312
321
|
else:
|
313
|
-
|
314
|
-
|
315
|
-
if
|
316
|
-
|
322
|
+
shell_attrs['instance'] = instance
|
323
|
+
shell_attrs['instance_keys'] = remove_ansi(str(instance))
|
324
|
+
if shell_attrs.get('repo_keys', None) is None:
|
325
|
+
shell_attrs['repo_keys'] = get_config('meerschaum', 'default_repository', patch=patch)
|
317
326
|
### this will be updated later in update_prompt ONLY IF {username} is in the prompt
|
318
|
-
|
327
|
+
shell_attrs['username'] = ''
|
319
328
|
|
320
329
|
if ANSI:
|
321
330
|
def apply_colors(attr, key):
|
@@ -325,48 +334,54 @@ class Shell(cmd.Cmd):
|
|
325
334
|
)
|
326
335
|
|
327
336
|
for attr_key in get_config('shell', 'ansi'):
|
328
|
-
if attr_key not in
|
337
|
+
if attr_key not in shell_attrs:
|
329
338
|
continue
|
330
|
-
|
339
|
+
shell_attrs[attr_key] = apply_colors(shell_attrs[attr_key], attr_key)
|
340
|
+
self.__dict__[attr_key] = shell_attrs[attr_key]
|
331
341
|
|
332
342
|
### refresh actions
|
333
343
|
_insert_shell_actions(_shell=self, keep_self=True)
|
334
344
|
|
335
345
|
### replace {instance} in prompt with stylized instance string
|
336
346
|
self.update_prompt()
|
337
|
-
self._dict_backup = {k:v for k, v in self.__dict__.copy().items() if k != '_dict_backup'}
|
338
347
|
|
339
348
|
def insert_actions(self):
|
340
349
|
from meerschaum.actions import actions
|
341
350
|
|
342
351
|
def update_prompt(self, instance: Optional[str] = None, username: Optional[str] = None):
|
343
352
|
from meerschaum.utils.formatting import ANSI, colored
|
344
|
-
|
345
|
-
|
353
|
+
from meerschaum._internal.entry import _shell, get_shell
|
354
|
+
|
355
|
+
cmd.__builtins__['input'] = input_with_sigint(
|
356
|
+
_old_input,
|
357
|
+
shell_attrs['session'],
|
358
|
+
shell = self,
|
359
|
+
)
|
360
|
+
prompt = shell_attrs['_prompt']
|
346
361
|
mask = prompt
|
347
|
-
|
362
|
+
shell_attrs['_update_bottom_toolbar'] = True
|
348
363
|
|
349
|
-
if '{instance}' in
|
364
|
+
if '{instance}' in shell_attrs['_prompt']:
|
350
365
|
if instance is None:
|
351
|
-
instance =
|
352
|
-
|
366
|
+
instance = shell_attrs['instance_keys']
|
367
|
+
shell_attrs['instance'] = instance
|
353
368
|
if ANSI:
|
354
|
-
|
355
|
-
|
369
|
+
shell_attrs['instance'] = colored(
|
370
|
+
shell_attrs['instance'], **get_config(
|
356
371
|
'shell', 'ansi', 'instance', 'rich'
|
357
372
|
)
|
358
373
|
)
|
359
|
-
prompt = prompt.replace('{instance}',
|
374
|
+
prompt = prompt.replace('{instance}', shell_attrs['instance'])
|
360
375
|
mask = mask.replace('{instance}', ''.join(['\0' for c in '{instance}']))
|
361
376
|
|
362
|
-
if '{username}' in
|
377
|
+
if '{username}' in shell_attrs['_prompt']:
|
363
378
|
if username is None:
|
364
379
|
from meerschaum.utils.misc import remove_ansi
|
365
380
|
from meerschaum.connectors.parse import parse_instance_keys
|
366
381
|
from meerschaum.connectors.sql import SQLConnector
|
367
382
|
try:
|
368
383
|
conn_attrs = parse_instance_keys(
|
369
|
-
remove_ansi(
|
384
|
+
remove_ansi(shell_attrs['instance_keys']), construct=False
|
370
385
|
)
|
371
386
|
if 'username' not in conn_attrs:
|
372
387
|
if 'uri' in conn_attrs:
|
@@ -379,14 +394,14 @@ class Shell(cmd.Cmd):
|
|
379
394
|
username = str(e)
|
380
395
|
if username is None:
|
381
396
|
username = '(no username)'
|
382
|
-
|
397
|
+
shell_attrs['username'] = (
|
383
398
|
username if not ANSI else
|
384
399
|
colored(username, **get_config('shell', 'ansi', 'username', 'rich'))
|
385
400
|
)
|
386
|
-
prompt = prompt.replace('{username}',
|
401
|
+
prompt = prompt.replace('{username}', shell_attrs['username'])
|
387
402
|
mask = mask.replace('{username}', ''.join(['\0' for c in '{username}']))
|
388
403
|
|
389
|
-
remainder_prompt = list(
|
404
|
+
remainder_prompt = list(shell_attrs['_prompt'])
|
390
405
|
for i, c in enumerate(mask):
|
391
406
|
if c != '\0':
|
392
407
|
_c = c
|
@@ -394,10 +409,11 @@ class Shell(cmd.Cmd):
|
|
394
409
|
_c = colored(_c, **get_config('shell', 'ansi', 'prompt', 'rich'))
|
395
410
|
remainder_prompt[i] = _c
|
396
411
|
self.prompt = ''.join(remainder_prompt).replace(
|
397
|
-
'{username}',
|
412
|
+
'{username}', shell_attrs['username']
|
398
413
|
).replace(
|
399
|
-
'{instance}',
|
414
|
+
'{instance}', shell_attrs['instance']
|
400
415
|
)
|
416
|
+
shell_attrs['prompt'] = self.prompt
|
401
417
|
### flush stdout
|
402
418
|
print("", end="", flush=True)
|
403
419
|
|
@@ -412,6 +428,9 @@ class Shell(cmd.Cmd):
|
|
412
428
|
### Preserve the working directory.
|
413
429
|
old_cwd = os.getcwd()
|
414
430
|
|
431
|
+
from meerschaum._internal.entry import _shell, get_shell
|
432
|
+
self = get_shell(sysargs=shell_attrs['_sysargs'], debug=shell_attrs.get('debug', False))
|
433
|
+
|
415
434
|
### make a backup of line for later
|
416
435
|
original_line = deepcopy(line)
|
417
436
|
|
@@ -427,7 +446,7 @@ class Shell(cmd.Cmd):
|
|
427
446
|
### if the user specifies, clear the screen before executing any commands
|
428
447
|
if _clear_screen:
|
429
448
|
from meerschaum.utils.formatting._shell import clear_screen
|
430
|
-
clear_screen(debug=
|
449
|
+
clear_screen(debug=shell_attrs['debug'])
|
431
450
|
|
432
451
|
### return blank commands (spaces break argparse)
|
433
452
|
if original_line is None or len(str(line).strip()) == 0:
|
@@ -456,11 +475,10 @@ class Shell(cmd.Cmd):
|
|
456
475
|
args['shell'] = True
|
457
476
|
args['line'] = line
|
458
477
|
|
459
|
-
|
460
478
|
### if debug is not set on the command line,
|
461
479
|
### default to shell setting
|
462
480
|
if not args.get('debug', False):
|
463
|
-
args['debug'] =
|
481
|
+
args['debug'] = shell_attrs['debug']
|
464
482
|
|
465
483
|
### Make sure an action was provided.
|
466
484
|
if not args.get('action', None):
|
@@ -479,17 +497,19 @@ class Shell(cmd.Cmd):
|
|
479
497
|
from meerschaum.actions import get_main_action_name
|
480
498
|
main_action_name = get_main_action_name(args['action'])
|
481
499
|
if main_action_name is None:
|
482
|
-
if not hasattr(self, 'do_'+args['action'][0]):
|
500
|
+
if not hasattr(self, 'do_' + args['action'][0]):
|
483
501
|
args['action'].insert(0, 'sh')
|
484
502
|
main_action_name = 'sh'
|
503
|
+
else:
|
504
|
+
main_action_name = args['action'][0]
|
485
505
|
|
486
506
|
### if no instance is provided, use current shell default,
|
487
507
|
### but not for the 'api' command (to avoid recursion)
|
488
508
|
if 'mrsm_instance' not in args and main_action_name != 'api':
|
489
|
-
args['mrsm_instance'] = str(
|
509
|
+
args['mrsm_instance'] = str(shell_attrs['instance_keys'])
|
490
510
|
|
491
511
|
if 'repository' not in args and main_action_name != 'api':
|
492
|
-
args['repository'] = str(
|
512
|
+
args['repository'] = str(shell_attrs['repo_keys'])
|
493
513
|
|
494
514
|
### parse out empty strings
|
495
515
|
if args['action'][0].strip("\"'") == '':
|
@@ -501,21 +521,25 @@ class Shell(cmd.Cmd):
|
|
501
521
|
args['action'] = ['start', 'jobs'] + args['action']
|
502
522
|
main_action_name = 'start'
|
503
523
|
|
504
|
-
positional_only = (main_action_name not in
|
524
|
+
positional_only = (main_action_name not in shell_attrs['_actions'])
|
505
525
|
if positional_only:
|
506
526
|
return original_line
|
507
527
|
|
508
528
|
from meerschaum._internal.entry import entry_with_args
|
509
529
|
|
510
530
|
try:
|
511
|
-
success_tuple = entry_with_args(_actions=
|
531
|
+
success_tuple = entry_with_args(_actions=shell_attrs['_actions'], **args)
|
532
|
+
# success_tuple = entry_with_args(**args)
|
512
533
|
except Exception as e:
|
513
534
|
success_tuple = False, str(e)
|
514
535
|
|
515
536
|
from meerschaum.utils.formatting import print_tuple
|
516
537
|
if isinstance(success_tuple, tuple):
|
517
538
|
print_tuple(
|
518
|
-
success_tuple,
|
539
|
+
success_tuple,
|
540
|
+
skip_common = (not shell_attrs['debug']),
|
541
|
+
upper_padding = 1,
|
542
|
+
lower_padding = 0,
|
519
543
|
)
|
520
544
|
|
521
545
|
### Restore the old working directory.
|
@@ -525,9 +549,9 @@ class Shell(cmd.Cmd):
|
|
525
549
|
return ""
|
526
550
|
|
527
551
|
def postcmd(self, stop : bool = False, line : str = ""):
|
528
|
-
_reload =
|
552
|
+
_reload = shell_attrs['_reload']
|
529
553
|
if _reload:
|
530
|
-
self.load_config(
|
554
|
+
self.load_config(shell_attrs['instance'])
|
531
555
|
if stop:
|
532
556
|
return True
|
533
557
|
|
@@ -555,15 +579,15 @@ class Shell(cmd.Cmd):
|
|
555
579
|
except (IndexError, AttributeError):
|
556
580
|
state = ''
|
557
581
|
if state == '':
|
558
|
-
|
582
|
+
shell_attrs['debug'] = not shell_attrs['debug']
|
559
583
|
elif state.lower() in on_commands:
|
560
|
-
|
584
|
+
shell_attrs['debug'] = True
|
561
585
|
elif state.lower() in off_commands:
|
562
|
-
|
586
|
+
shell_attrs['debug'] = False
|
563
587
|
else:
|
564
588
|
info(f"Unknown state '{state}'. Ignoring...")
|
565
589
|
|
566
|
-
info(f"Debug mode is {'on' if
|
590
|
+
info(f"Debug mode is {'on' if shell_attrs['debug'] else 'off'}.")
|
567
591
|
|
568
592
|
def do_instance(
|
569
593
|
self,
|
@@ -619,7 +643,7 @@ class Shell(cmd.Cmd):
|
|
619
643
|
else:
|
620
644
|
conn_keys = instance_keys
|
621
645
|
|
622
|
-
|
646
|
+
shell_attrs['instance_keys'] = conn_keys
|
623
647
|
|
624
648
|
self.update_prompt(instance=conn_keys)
|
625
649
|
info(f"Default instance for the current shell: {conn_keys}")
|
@@ -683,7 +707,7 @@ class Shell(cmd.Cmd):
|
|
683
707
|
if conn is None or not conn:
|
684
708
|
conn = get_connector('api', debug=debug)
|
685
709
|
|
686
|
-
|
710
|
+
shell_attrs['repo_keys'] = str(conn)
|
687
711
|
|
688
712
|
info(f"Default repository for the current shell: {conn}")
|
689
713
|
return True, "Success"
|
@@ -712,9 +736,9 @@ class Shell(cmd.Cmd):
|
|
712
736
|
args = parse_line(line)
|
713
737
|
if len(args['action']) == 0:
|
714
738
|
del args['action']
|
715
|
-
|
739
|
+
shell_attrs['_actions']['show'](['actions'], **args)
|
716
740
|
return ""
|
717
|
-
if args['action'][0] not in
|
741
|
+
if args['action'][0] not in shell_attrs['_actions']:
|
718
742
|
try:
|
719
743
|
print(textwrap.dedent(getattr(self, f"do_{args['action'][0]}").__doc__))
|
720
744
|
except Exception as e:
|
@@ -780,17 +804,21 @@ class Shell(cmd.Cmd):
|
|
780
804
|
Patch builtin cmdloop with my own input (defined below).
|
781
805
|
"""
|
782
806
|
import signal, os
|
783
|
-
cmd.__builtins__['input'] = input_with_sigint(
|
807
|
+
cmd.__builtins__['input'] = input_with_sigint(
|
808
|
+
_old_input,
|
809
|
+
shell_attrs['session'],
|
810
|
+
shell = self,
|
811
|
+
)
|
784
812
|
|
785
813
|
### if the user specifies, clear the screen before initializing the shell
|
786
814
|
if _clear_screen:
|
787
815
|
from meerschaum.utils.formatting._shell import clear_screen
|
788
|
-
clear_screen(debug=
|
816
|
+
clear_screen(debug=shell_attrs['debug'])
|
789
817
|
|
790
818
|
### if sysargs are provided, skip printing the intro and execute instead
|
791
|
-
if
|
792
|
-
|
793
|
-
self.precmd(' '.join(
|
819
|
+
if shell_attrs['_sysargs']:
|
820
|
+
shell_attrs['intro'] = ""
|
821
|
+
self.precmd(' '.join(shell_attrs['_sysargs']))
|
794
822
|
|
795
823
|
def postloop(self):
|
796
824
|
print('\n' + self.close_message)
|
@@ -816,24 +844,24 @@ def input_with_sigint(_input, session, shell: Optional[Shell] = None):
|
|
816
844
|
nonlocal last_connected
|
817
845
|
if not get_config('shell', 'bottom_toolbar', 'enabled'):
|
818
846
|
return None
|
819
|
-
if not
|
820
|
-
return
|
847
|
+
if not shell_attrs['_update_bottom_toolbar'] and platform.system() == 'Windows':
|
848
|
+
return shell_attrs['_old_bottom_toolbar']
|
821
849
|
size = os.get_terminal_size()
|
822
850
|
num_cols, num_lines = size.columns, size.lines
|
823
851
|
|
824
852
|
instance_colored = (
|
825
853
|
colored(
|
826
|
-
|
854
|
+
shell_attrs['instance_keys'], 'on ' + get_config(
|
827
855
|
'shell', 'ansi', 'instance', 'rich', 'style'
|
828
856
|
)
|
829
|
-
) if ANSI else colored(
|
857
|
+
) if ANSI else colored(shell_attrs['instance_keys'], 'on white')
|
830
858
|
)
|
831
859
|
repo_colored = (
|
832
|
-
colored(
|
833
|
-
if ANSI else colored(
|
860
|
+
colored(shell_attrs['repo_keys'], 'on ' + get_config('shell', 'ansi', 'repo', 'rich', 'style'))
|
861
|
+
if ANSI else colored(shell_attrs['repo_keys'], 'on white')
|
834
862
|
)
|
835
863
|
try:
|
836
|
-
typ, label =
|
864
|
+
typ, label = shell_attrs['instance_keys'].split(':')
|
837
865
|
connected = typ in connectors and label in connectors[typ]
|
838
866
|
except Exception as e:
|
839
867
|
connected = False
|
@@ -859,9 +887,9 @@ def input_with_sigint(_input, session, shell: Optional[Shell] = None):
|
|
859
887
|
)
|
860
888
|
buffer = (' ' * buffer_size) if buffer_size > 0 else '\n '
|
861
889
|
text = left + buffer + right
|
862
|
-
|
863
|
-
|
864
|
-
return
|
890
|
+
shell_attrs['_old_bottom_toolbar'] = prompt_toolkit_formatted_text.ANSI(text)
|
891
|
+
shell_attrs['_update_bottom_toolbar'] = False
|
892
|
+
return shell_attrs['_old_bottom_toolbar']
|
865
893
|
|
866
894
|
def _patched_prompt(*args):
|
867
895
|
_args = []
|
@@ -24,7 +24,9 @@ class ShellCompleter(Completer):
|
|
24
24
|
"""
|
25
25
|
Bridge the built-in cmd completer with the `prompt_toolkit` completer system.
|
26
26
|
"""
|
27
|
-
|
27
|
+
from meerschaum._internal.shell.Shell import shell_attrs
|
28
|
+
shell = get_shell()
|
29
|
+
shell_actions = [a[3:] for a in dir(shell) if a.startswith('do_')]
|
28
30
|
yielded = []
|
29
31
|
ensure_readline()
|
30
32
|
parts = document.text.split('-')
|
@@ -32,7 +34,6 @@ class ShellCompleter(Completer):
|
|
32
34
|
part_0_subbed_spaces = parts[0].replace(' ', '_')
|
33
35
|
parsed_text = part_0_subbed_spaces + '-'.join(parts[1:])
|
34
36
|
|
35
|
-
shell = get_shell()
|
36
37
|
|
37
38
|
### Index is the rank order (0 is closest match).
|
38
39
|
### Break when no results are returned.
|
@@ -50,11 +51,14 @@ class ShellCompleter(Completer):
|
|
50
51
|
yielded.append(poss)
|
51
52
|
|
52
53
|
args = parse_line(document.text)
|
53
|
-
action_function = get_action(args['action'], _actions=
|
54
|
+
action_function = get_action(args['action'], _actions=shell_attrs.get('_actions', None))
|
54
55
|
if action_function is None:
|
55
56
|
return
|
56
57
|
|
57
|
-
main_action_name = get_main_action_name(
|
58
|
+
main_action_name = get_main_action_name(
|
59
|
+
args['action'],
|
60
|
+
_actions = shell_attrs.get('_actions', None)
|
61
|
+
)
|
58
62
|
|
59
63
|
### If we haven't yet hit space, don't suggest subactions.
|
60
64
|
if not parsed_text.replace(
|
meerschaum/actions/__init__.py
CHANGED
@@ -291,7 +291,6 @@ __all__ = ['actions', 'get_subactions', 'get_action', 'get_main_action_name', 'g
|
|
291
291
|
### functions that do not begin with '_' from all submodules.
|
292
292
|
from inspect import getmembers, isfunction
|
293
293
|
actions = {}
|
294
|
-
"This docstring will be replaced in __pdoc__ at the end of this file."
|
295
294
|
|
296
295
|
for module in modules:
|
297
296
|
### A couple important things happening here:
|
@@ -324,6 +323,8 @@ original_actions = actions.copy()
|
|
324
323
|
from meerschaum._internal.entry import entry, get_shell
|
325
324
|
import meerschaum.plugins
|
326
325
|
make_action = meerschaum.plugins.make_action
|
326
|
+
pre_sync_hook = meerschaum.plugins.pre_sync_hook
|
327
|
+
post_sync_hook = meerschaum.plugins.post_sync_hook
|
327
328
|
|
328
329
|
### Instruct pdoc to skip the `meerschaum.actions.plugins` subdirectory.
|
329
330
|
__pdoc__ = {
|
meerschaum/actions/reload.py
CHANGED
@@ -17,8 +17,5 @@ def reload(
|
|
17
17
|
"""
|
18
18
|
Reload the running Meerschaum instance.
|
19
19
|
"""
|
20
|
-
from meerschaum.utils.packages import
|
21
|
-
|
22
|
-
reload_package('meerschaum')
|
23
|
-
reload_plugins(debug=debug)
|
24
|
-
return True, "Success"
|
20
|
+
from meerschaum.utils.packages import reload_meerschaum
|
21
|
+
return reload_meerschaum(debug=debug)
|