machineconfig 3.83__py3-none-any.whl → 3.85__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.
Potentially problematic release.
This version of machineconfig might be problematic. Click here for more details.
- machineconfig/cluster/sessions_managers/zellij_local.py +2 -2
- machineconfig/cluster/sessions_managers/zellij_remote.py +2 -2
- machineconfig/cluster/sessions_managers/zellij_utils/example_usage.py +2 -2
- machineconfig/jobs/python/vscode/api.py +8 -7
- machineconfig/scripts/python/ai/initai.py +1 -11
- machineconfig/scripts/python/cloud_copy.py +33 -27
- machineconfig/scripts/python/cloud_manager.py +0 -2
- machineconfig/scripts/python/cloud_mount.py +13 -10
- machineconfig/scripts/python/cloud_sync.py +30 -28
- machineconfig/scripts/python/croshell.py +46 -53
- machineconfig/scripts/python/dotfile.py +16 -16
- machineconfig/scripts/python/fire_jobs.py +30 -14
- machineconfig/scripts/python/fire_jobs_args_helper.py +43 -15
- machineconfig/scripts/python/helpers/helpers4.py +0 -2
- machineconfig/scripts/python/scheduler.py +0 -1
- machineconfig/scripts/python/share_terminal.py +41 -0
- machineconfig/scripts/python/start_slidev.py +15 -13
- machineconfig/scripts/python/start_terminals.py +19 -19
- machineconfig/scripts/python/t4.py +16 -0
- machineconfig/scripts/python/wifi_conn.py +16 -14
- machineconfig/scripts/python/wsl_windows_transfer.py +23 -29
- machineconfig/utils/ai/generate_file_checklist.py +17 -17
- {machineconfig-3.83.dist-info → machineconfig-3.85.dist-info}/METADATA +1 -1
- {machineconfig-3.83.dist-info → machineconfig-3.85.dist-info}/RECORD +27 -28
- {machineconfig-3.83.dist-info → machineconfig-3.85.dist-info}/entry_points.txt +5 -5
- machineconfig/cluster/templates/cli_gooey.py +0 -115
- machineconfig/jobs/python/vscode/link_ve.py +0 -63
- machineconfig/jobs/python/vscode/select_interpreter.py +0 -87
- {machineconfig-3.83.dist-info → machineconfig-3.85.dist-info}/WHEEL +0 -0
- {machineconfig-3.83.dist-info → machineconfig-3.85.dist-info}/top_level.txt +0 -0
|
@@ -8,7 +8,6 @@ fire
|
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
10
|
from machineconfig.scripts.python.helpers.helpers4 import search_for_files_of_interest
|
|
11
|
-
from machineconfig.scripts.python.helpers.helpers4 import convert_kwargs_to_fire_kwargs_str
|
|
12
11
|
from machineconfig.scripts.python.helpers.helpers4 import parse_pyfile
|
|
13
12
|
from machineconfig.scripts.python.helpers.helpers4 import get_import_module_code
|
|
14
13
|
from machineconfig.utils.ve import get_ve_activate_line, get_ve_path_and_ipython_profile
|
|
@@ -17,7 +16,7 @@ from machineconfig.utils.path_helper import match_file_name, sanitize_path
|
|
|
17
16
|
|
|
18
17
|
from machineconfig.utils.path_extended import PathExtended as PathExtended
|
|
19
18
|
from machineconfig.utils.accessories import get_repo_root, randstr
|
|
20
|
-
from machineconfig.scripts.python.fire_jobs_args_helper import FireJobArgs, extract_kwargs
|
|
19
|
+
from machineconfig.scripts.python.fire_jobs_args_helper import FireJobArgs, extract_kwargs, parse_fire_args_from_context
|
|
21
20
|
import platform
|
|
22
21
|
from typing import Optional, Annotated
|
|
23
22
|
from pathlib import Path
|
|
@@ -26,7 +25,7 @@ import typer
|
|
|
26
25
|
# import os
|
|
27
26
|
|
|
28
27
|
|
|
29
|
-
def route(args: FireJobArgs) -> None:
|
|
28
|
+
def route(args: FireJobArgs, fire_args: str = "") -> None:
|
|
30
29
|
if args.layout:
|
|
31
30
|
from machineconfig.scripts.python.fire_jobs_layout_helper import handle_layout_args
|
|
32
31
|
|
|
@@ -51,7 +50,7 @@ def route(args: FireJobArgs) -> None:
|
|
|
51
50
|
ipy_profile = "default"
|
|
52
51
|
|
|
53
52
|
if choice_file.suffix == ".py":
|
|
54
|
-
kwargs = extract_kwargs(args)
|
|
53
|
+
kwargs = extract_kwargs(args) # This now returns empty dict, but kept for compatibility
|
|
55
54
|
activate_ve_line = get_ve_activate_line(ve_root=args.ve or ve_root_from_file or "$HOME/code/machineconfig/.venv")
|
|
56
55
|
else:
|
|
57
56
|
activate_ve_line = ""
|
|
@@ -217,8 +216,7 @@ except ImportError as _ex:
|
|
|
217
216
|
# both selected function and kwargs are mentioned in the made up script, therefore no need for fire module.
|
|
218
217
|
command = f"{exe} {choice_file} "
|
|
219
218
|
elif choice_function is not None:
|
|
220
|
-
|
|
221
|
-
command = f"{exe} -m fire {choice_file} {choice_function} {kwargs_str}"
|
|
219
|
+
command = f"{exe} -m fire {choice_file} {choice_function} {fire_args}"
|
|
222
220
|
elif args.streamlit:
|
|
223
221
|
# for .streamlit config to work, it needs to be in the current directory.
|
|
224
222
|
if args.holdDirectory:
|
|
@@ -230,8 +228,7 @@ except ImportError as _ex:
|
|
|
230
228
|
command = rf""" cd /d {choice_file.parent} & {exe} {choice_file.name} """
|
|
231
229
|
else:
|
|
232
230
|
if choice_file.suffix == "":
|
|
233
|
-
|
|
234
|
-
command = f"{exe} {choice_file} {kwargs_raw}"
|
|
231
|
+
command = f"{exe} {choice_file} {fire_args}"
|
|
235
232
|
else:
|
|
236
233
|
# command = f"cd {choice_file.parent}\n{exe} {choice_file.name}\ncd {PathExtended.cwd()}"
|
|
237
234
|
command = f"{exe} {choice_file} "
|
|
@@ -330,7 +327,8 @@ python -m machineconfig.cluster.templates.cli_click --file {choice_file} """
|
|
|
330
327
|
|
|
331
328
|
|
|
332
329
|
def main(
|
|
333
|
-
|
|
330
|
+
ctx: typer.Context,
|
|
331
|
+
path: Annotated[str, typer.Argument(help="Path to the Python file to run")] = ".",
|
|
334
332
|
function: Annotated[Optional[str], typer.Argument(help="Function to run")] = None,
|
|
335
333
|
ve: Annotated[str, typer.Option("--ve", "-v", help="Virtual environment name")] = "",
|
|
336
334
|
cmd: Annotated[bool, typer.Option("--cmd", "-B", help="Create a cmd fire command to launch the job asynchronously")] = False,
|
|
@@ -351,10 +349,13 @@ def main(
|
|
|
351
349
|
Nprocess: Annotated[int, typer.Option("--Nprocess", "-p", help="Number of processes to use")] = 1,
|
|
352
350
|
zellij_tab: Annotated[Optional[str], typer.Option("--zellij_tab", "-z", help="Open in a new zellij tab")] = None,
|
|
353
351
|
watch: Annotated[bool, typer.Option("--watch", "-w", help="Watch the file for changes")] = False,
|
|
354
|
-
kw: Annotated[Optional[list[str]], typer.Option("--kw", help="Keyword arguments to pass to the function in the form of k1 v1 k2 v2 ... (meaning k1=v1, k2=v2, etc)")] = None,
|
|
355
352
|
layout: Annotated[bool, typer.Option("--layout", "-L", help="Use layout configuration (Zellij Or WindowsTerminal)")] = False,
|
|
356
353
|
) -> None:
|
|
357
354
|
"""Main function to process fire jobs arguments."""
|
|
355
|
+
|
|
356
|
+
# Get Fire arguments from context
|
|
357
|
+
fire_args = parse_fire_args_from_context(ctx)
|
|
358
|
+
|
|
358
359
|
args = FireJobArgs(
|
|
359
360
|
path=path,
|
|
360
361
|
function=function,
|
|
@@ -377,16 +378,31 @@ def main(
|
|
|
377
378
|
Nprocess=Nprocess,
|
|
378
379
|
zellij_tab=zellij_tab,
|
|
379
380
|
watch=watch,
|
|
380
|
-
kw=kw,
|
|
381
381
|
layout=layout,
|
|
382
382
|
)
|
|
383
|
-
|
|
383
|
+
try:
|
|
384
|
+
route(args, fire_args)
|
|
385
|
+
except SystemExit:
|
|
386
|
+
# Re-raise SystemExit to preserve exit codes and allow clean exits
|
|
387
|
+
raise
|
|
388
|
+
except Exception as e:
|
|
389
|
+
# For other exceptions, print clean error message and exit
|
|
390
|
+
import sys
|
|
391
|
+
print(f"❌ Error: {e}", file=sys.stderr)
|
|
392
|
+
sys.exit(1)
|
|
384
393
|
|
|
385
394
|
|
|
386
395
|
def main_from_parser():
|
|
387
|
-
typer
|
|
396
|
+
# from trogon.typer import init_tui
|
|
397
|
+
# from trogon.typer import init_tui
|
|
398
|
+
from typer import Typer
|
|
399
|
+
app = Typer(add_completion=False)
|
|
400
|
+
app.command(context_settings={"allow_extra_args": True, "allow_interspersed_args": False})(main)
|
|
401
|
+
# typer.run(main)
|
|
402
|
+
# init_tui(app)
|
|
403
|
+
app()
|
|
388
404
|
|
|
389
405
|
|
|
390
406
|
if __name__ == "__main__":
|
|
391
407
|
# options, func_args = parse_pyfile(file_path="C:/Users/aalsaf01/code/machineconfig/myresources/crocodile/core.py")
|
|
392
|
-
|
|
408
|
+
main_from_parser()
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from dataclasses import dataclass
|
|
2
|
-
from typing import Optional
|
|
2
|
+
from typing import Optional, Any
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
@dataclass
|
|
@@ -27,21 +27,49 @@ class FireJobArgs:
|
|
|
27
27
|
Nprocess: int = 1
|
|
28
28
|
zellij_tab: Optional[str] = None
|
|
29
29
|
watch: bool = False
|
|
30
|
-
kw: Optional[list[str]] = None
|
|
31
30
|
layout: bool = False
|
|
32
31
|
|
|
33
32
|
|
|
34
33
|
def extract_kwargs(args: FireJobArgs) -> dict[str, object]:
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
34
|
+
"""Extract kwargs from command line using -- separator.
|
|
35
|
+
|
|
36
|
+
Returns empty dict since kwargs are now parsed directly from sys.argv
|
|
37
|
+
using the -- separator pattern in the main function.
|
|
38
|
+
"""
|
|
39
|
+
return {}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def parse_fire_args_from_argv() -> str:
|
|
43
|
+
"""Parse arguments after -- separator for Fire compatibility.
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
String of Fire-compatible arguments to append to command
|
|
47
|
+
"""
|
|
48
|
+
import sys
|
|
49
|
+
|
|
50
|
+
if '--' in sys.argv:
|
|
51
|
+
separator_index = sys.argv.index('--')
|
|
52
|
+
fire_args = sys.argv[separator_index + 1:]
|
|
53
|
+
# Join all Fire arguments - they should already be in Fire format
|
|
54
|
+
return ' '.join(fire_args) if fire_args else ''
|
|
55
|
+
|
|
56
|
+
return ''
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def parse_fire_args_from_context(ctx: Any) -> str:
|
|
60
|
+
"""Parse Fire arguments from typer context.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
ctx: Typer context containing raw arguments
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
String of Fire-compatible arguments to append to command
|
|
67
|
+
"""
|
|
68
|
+
# Get remaining args that weren't consumed by typer
|
|
69
|
+
if hasattr(ctx, 'args') and ctx.args:
|
|
70
|
+
args = ctx.args
|
|
71
|
+
# Filter out the -- separator if present
|
|
72
|
+
if args and args[0] == '--':
|
|
73
|
+
args = args[1:]
|
|
74
|
+
return ' '.join(args)
|
|
75
|
+
return ''
|
|
@@ -2,9 +2,7 @@ from typing import Any, Callable, Optional
|
|
|
2
2
|
import inspect
|
|
3
3
|
import os
|
|
4
4
|
|
|
5
|
-
# import argparse
|
|
6
5
|
from machineconfig.utils.path_extended import PathExtended as PathExtended
|
|
7
|
-
# from machineconfig.utils.utils import choose_ssh_host
|
|
8
6
|
|
|
9
7
|
|
|
10
8
|
def search_for_files_of_interest(path_obj: PathExtended):
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Optional
|
|
5
|
+
# import typer
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
"""
|
|
9
|
+
reference:
|
|
10
|
+
# https://github.com/tsl0922/ttyd/wiki/Serving-web-fonts
|
|
11
|
+
# -t "fontFamily=CaskaydiaCove" bash
|
|
12
|
+
# --terminal-type xterm-kitty
|
|
13
|
+
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def share_terminal(port: int, password: Optional[str]) -> None:
|
|
18
|
+
if password is None:
|
|
19
|
+
pwd_path = Path.home().joinpath("dotfiles/creds/passwords/quick_password")
|
|
20
|
+
if pwd_path.exists():
|
|
21
|
+
password = pwd_path.read_text(encoding="utf-8").strip()
|
|
22
|
+
else:
|
|
23
|
+
raise ValueError("Password not provided and default password file does not exist.")
|
|
24
|
+
|
|
25
|
+
import socket
|
|
26
|
+
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
27
|
+
s.connect(('8.8.8.8',80))
|
|
28
|
+
local_ip_v4 = s.getsockname()[0]
|
|
29
|
+
s.close()
|
|
30
|
+
|
|
31
|
+
print(f"\n🌐 Access your terminal at: http://{local_ip_v4}:{port}\n")
|
|
32
|
+
|
|
33
|
+
code = f"""
|
|
34
|
+
#!/bin/bash
|
|
35
|
+
uv run --python 3.13 --with machineconfig install -ttyd
|
|
36
|
+
|
|
37
|
+
ttyd --writable -t enableSixel=true --port {port} --credential "$USER:{password}" -t 'theme={"background": "black"}' bash
|
|
38
|
+
|
|
39
|
+
"""
|
|
40
|
+
import subprocess
|
|
41
|
+
subprocess.run(code, shell=True, check=True)
|
|
@@ -6,6 +6,8 @@ from machineconfig.utils.source_of_truth import CONFIG_PATH
|
|
|
6
6
|
from machineconfig.utils.code import print_code
|
|
7
7
|
from machineconfig.utils.path_extended import PathExtended as PathExtended
|
|
8
8
|
from machineconfig.utils.terminal import Terminal
|
|
9
|
+
from typing import Annotated, Optional
|
|
10
|
+
import typer
|
|
9
11
|
import subprocess
|
|
10
12
|
import platform
|
|
11
13
|
|
|
@@ -47,28 +49,24 @@ def jupyter_to_markdown(file: PathExtended):
|
|
|
47
49
|
return op_dir
|
|
48
50
|
|
|
49
51
|
|
|
50
|
-
def main(
|
|
51
|
-
|
|
52
|
-
|
|
52
|
+
def main(
|
|
53
|
+
directory: Annotated[Optional[str], typer.Option("-d", "--directory", help="📁 Directory of the report.")] = None,
|
|
54
|
+
jupyter_file: Annotated[Optional[str], typer.Option("-j", "--jupyter-file", help="📓 Jupyter notebook file to convert to slides. If not provided, slides.md is used.")] = None,
|
|
55
|
+
) -> None:
|
|
53
56
|
print("\n" + "=" * 50)
|
|
54
57
|
print("🎥 Welcome to the Slidev Presentation Tool")
|
|
55
58
|
print("=" * 50 + "\n")
|
|
56
59
|
|
|
57
|
-
parser = argparse.ArgumentParser()
|
|
58
|
-
parser.add_argument("-d", "--directory", default=None, help="📁 Directory of the report.")
|
|
59
|
-
parser.add_argument("-j", "--jupyter-file", default=None, help="📓 Jupyter notebook file to convert to slides. If not provided, slides.md is used.")
|
|
60
|
-
args = parser.parse_args()
|
|
61
|
-
|
|
62
60
|
port = PORT_DEFAULT
|
|
63
61
|
|
|
64
|
-
if
|
|
62
|
+
if jupyter_file is not None:
|
|
65
63
|
print("📓 Jupyter file provided. Converting to markdown...")
|
|
66
|
-
report_dir = jupyter_to_markdown(PathExtended(
|
|
64
|
+
report_dir = jupyter_to_markdown(PathExtended(jupyter_file))
|
|
67
65
|
else:
|
|
68
|
-
if
|
|
66
|
+
if directory is None:
|
|
69
67
|
report_dir = PathExtended.cwd()
|
|
70
68
|
else:
|
|
71
|
-
report_dir = PathExtended(
|
|
69
|
+
report_dir = PathExtended(directory)
|
|
72
70
|
|
|
73
71
|
assert report_dir.exists(), f"❌ Directory {report_dir} does not exist."
|
|
74
72
|
assert report_dir.is_dir(), f"❌ {report_dir} is not a directory."
|
|
@@ -108,5 +106,9 @@ def main() -> None:
|
|
|
108
106
|
print_code(code=program, lexer="bash", desc="Run the following command to start the presentation")
|
|
109
107
|
|
|
110
108
|
|
|
109
|
+
def arg_parser() -> None:
|
|
110
|
+
typer.run(main)
|
|
111
|
+
|
|
112
|
+
|
|
111
113
|
if __name__ == "__main__":
|
|
112
|
-
|
|
114
|
+
arg_parser()
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
from machineconfig.utils.options import choose_from_options, get_ssh_hosts
|
|
4
4
|
import platform
|
|
5
5
|
from itertools import cycle
|
|
6
|
-
from typing import Literal
|
|
6
|
+
from typing import Literal, Optional, Annotated
|
|
7
|
+
import typer
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
COLOR_SCHEMES = ["Campbell", "Campbell Powershell", "Solarized Dark", "Ubuntu-ColorScheme", "Retro"]
|
|
@@ -70,40 +71,35 @@ wt --window {window} --title {hosts[0]} powershell -Command "ssh {host_linux} {s
|
|
|
70
71
|
return cmd
|
|
71
72
|
|
|
72
73
|
|
|
73
|
-
def main(
|
|
74
|
-
|
|
75
|
-
|
|
74
|
+
def main(
|
|
75
|
+
panes: Annotated[Optional[int], typer.Option("--panes", "-p", help="🔲 The number of panes to open.")] = 4,
|
|
76
|
+
vertical: Annotated[bool, typer.Option("--vertical", "-V", help="↕️ Switch orientation to vertical from default horizontal.")] = False,
|
|
77
|
+
window: Annotated[int, typer.Option("--window", "-w", help="🪟 The window ID to use.")] = 0,
|
|
78
|
+
hosts: Annotated[Optional[list[str]], typer.Option("--hosts", "-H", help="🌐 The hosts to connect to.")] = None,
|
|
79
|
+
) -> None:
|
|
76
80
|
print("\n" + "=" * 50)
|
|
77
81
|
print("🖥️ Welcome to the Terminal Starter Tool")
|
|
78
82
|
print("=" * 50 + "\n")
|
|
79
83
|
|
|
80
|
-
|
|
81
|
-
parser.add_argument("--panes", "-p", type=int, help="🔲 The number of panes to open.", default=4)
|
|
82
|
-
parser.add_argument("--vertical", "-V", action="store_true", help="↕️ Switch orientation to vertical from default horizontal.")
|
|
83
|
-
parser.add_argument("--window", "-w", type=int, help="🪟 The window ID to use.", default=0) # 0 refers to this window.
|
|
84
|
-
parser.add_argument("--hosts", "-H", type=str, nargs="*", help="🌐 The hosts to connect to.", default=None)
|
|
85
|
-
args = parser.parse_args()
|
|
86
|
-
|
|
87
|
-
if args.panes:
|
|
84
|
+
if panes:
|
|
88
85
|
print("🔲 Configuring panes...")
|
|
89
|
-
cmd = f"wt --window {
|
|
86
|
+
cmd = f"wt --window {window} --colorScheme '{next(THEMES_ITER)}' pwsh -NoExit -Command '{next(INIT_COMMANDS_ITER)}' "
|
|
90
87
|
cmd += f" `; new-tab --colorScheme '{next(THEMES_ITER)}' --profile pwsh --title 't2' --tabColor '#f59218' "
|
|
91
88
|
cmd += f" `; new-tab --colorScheme '{next(THEMES_ITER)}' --profile pwsh --title 't3' --tabColor '#009999' "
|
|
92
|
-
for idx in range(
|
|
89
|
+
for idx in range(panes):
|
|
93
90
|
if idx % 2 == 0:
|
|
94
91
|
cmd += f" `; move-focus down split-pane --horizontal --size {next(SIZE_ITER)} --colorScheme '{next(THEMES_ITER)}' pwsh -NoExit -Command '{next(INIT_COMMANDS_ITER)}' "
|
|
95
92
|
else:
|
|
96
93
|
cmd += f" `; move-focus up split-pane --vertical --size {next(SIZE_ITER)} --colorScheme '{next(THEMES_ITER)}' pwsh -NoExit -Command '{next(INIT_COMMANDS_ITER)}' "
|
|
97
94
|
|
|
98
95
|
else:
|
|
99
|
-
if
|
|
96
|
+
if hosts is None:
|
|
100
97
|
print("🌐 No hosts provided. Displaying options...")
|
|
101
98
|
hosts = choose_from_options(msg="Select hosts:", options=get_ssh_hosts() + [THIS_MACHINE], multi=True, fzf=True)
|
|
102
99
|
else:
|
|
103
|
-
print("🌐 Using provided hosts:",
|
|
104
|
-
hosts = args.hosts
|
|
100
|
+
print("🌐 Using provided hosts:", hosts)
|
|
105
101
|
assert isinstance(hosts, list)
|
|
106
|
-
cmd = main_windows_and_wsl(window=
|
|
102
|
+
cmd = main_windows_and_wsl(window=window, hosts=hosts, orientation="vertical" if vertical else "horizontal")
|
|
107
103
|
|
|
108
104
|
print("\n📋 Generated Command:")
|
|
109
105
|
print("-" * 50)
|
|
@@ -117,5 +113,9 @@ def main():
|
|
|
117
113
|
print("✅ Command saved successfully!\n")
|
|
118
114
|
|
|
119
115
|
|
|
116
|
+
def arg_parser() -> None:
|
|
117
|
+
typer.run(main)
|
|
118
|
+
|
|
119
|
+
|
|
120
120
|
if __name__ == "__main__":
|
|
121
|
-
|
|
121
|
+
arg_parser()
|
|
@@ -28,7 +28,8 @@ Usage examples:
|
|
|
28
28
|
|
|
29
29
|
"""
|
|
30
30
|
|
|
31
|
-
import
|
|
31
|
+
from typing import Annotated
|
|
32
|
+
import typer
|
|
32
33
|
import configparser
|
|
33
34
|
from pathlib import Path
|
|
34
35
|
import os
|
|
@@ -262,24 +263,21 @@ def manual_network_selection() -> bool:
|
|
|
262
263
|
return False
|
|
263
264
|
|
|
264
265
|
|
|
265
|
-
def main(
|
|
266
|
+
def main(
|
|
267
|
+
ssid: Annotated[str, typer.Option("-n", "--ssid", help="🔗 SSID of WiFi (from config)")] = "MyPhoneHotSpot",
|
|
268
|
+
manual: Annotated[bool, typer.Option("-m", "--manual", help="🔍 Manual network selection mode")] = False,
|
|
269
|
+
list_: Annotated[bool, typer.Option("-l", "--list", help="📡 List available networks only")] = False,
|
|
270
|
+
) -> None:
|
|
266
271
|
"""Main function with fallback network selection"""
|
|
267
272
|
console.print(Panel("📶 Welcome to the WiFi Connector Tool", title="[bold blue]WiFi Connection[/bold blue]", border_style="blue"))
|
|
268
273
|
|
|
269
|
-
parser = argparse.ArgumentParser(description="WiFi Connector")
|
|
270
|
-
parser.add_argument("-n", "--ssid", help="🔗 SSID of WiFi (from config)", default="MyPhoneHotSpot")
|
|
271
|
-
parser.add_argument("-m", "--manual", action="store_true", help="🔍 Manual network selection mode")
|
|
272
|
-
parser.add_argument("-l", "--list", action="store_true", help="📡 List available networks only")
|
|
273
|
-
|
|
274
|
-
args = parser.parse_args()
|
|
275
|
-
|
|
276
274
|
# If user just wants to list networks
|
|
277
|
-
if
|
|
275
|
+
if list_:
|
|
278
276
|
display_available_networks()
|
|
279
277
|
return
|
|
280
278
|
|
|
281
279
|
# If user wants manual mode, skip config and go straight to selection
|
|
282
|
-
if
|
|
280
|
+
if manual:
|
|
283
281
|
console.print("[blue]🔍 Manual network selection mode[/blue]")
|
|
284
282
|
if manual_network_selection():
|
|
285
283
|
console.print("[green]🎉 Successfully connected![/green]")
|
|
@@ -288,9 +286,9 @@ def main():
|
|
|
288
286
|
return
|
|
289
287
|
|
|
290
288
|
# Try to connect using configuration first
|
|
291
|
-
console.print(f"[blue]🔍 Attempting to connect to configured network: {
|
|
289
|
+
console.print(f"[blue]🔍 Attempting to connect to configured network: {ssid}[/blue]")
|
|
292
290
|
|
|
293
|
-
if try_config_connection(
|
|
291
|
+
if try_config_connection(ssid):
|
|
294
292
|
console.print("[green]🎉 Successfully connected using configuration![/green]")
|
|
295
293
|
return
|
|
296
294
|
|
|
@@ -306,6 +304,10 @@ def main():
|
|
|
306
304
|
console.print("[blue]👋 Goodbye![/blue]")
|
|
307
305
|
|
|
308
306
|
|
|
307
|
+
def arg_parser() -> None:
|
|
308
|
+
typer.run(main)
|
|
309
|
+
|
|
310
|
+
|
|
309
311
|
def get_current_wifi_name() -> str:
|
|
310
312
|
"""Get the name of the currently connected WiFi network"""
|
|
311
313
|
console.print("\n[blue]🔍 Checking current WiFi connection...[/blue]")
|
|
@@ -413,4 +415,4 @@ def create_new_connection(name: str, ssid: str, password: str):
|
|
|
413
415
|
|
|
414
416
|
|
|
415
417
|
if __name__ == "__main__":
|
|
416
|
-
|
|
418
|
+
arg_parser()
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"""TWSL"""
|
|
2
2
|
|
|
3
3
|
from machineconfig.utils.path_extended import PathExtended as PathExtended
|
|
4
|
-
import
|
|
4
|
+
from typing import Annotated, Optional
|
|
5
|
+
import typer
|
|
5
6
|
import platform
|
|
6
7
|
import getpass
|
|
7
8
|
from pathlib import Path
|
|
@@ -20,53 +21,46 @@ WSL_FROM_WIN = Path(r"\\wsl.localhost\Ubuntu-22.04\home") # PathExtended(rf"\\w
|
|
|
20
21
|
WIN_FROM_WSL = Path(r"/mnt/c/Users")
|
|
21
22
|
|
|
22
23
|
|
|
23
|
-
def main(
|
|
24
|
+
def main(
|
|
25
|
+
path: Annotated[str, typer.Argument(help="📁 Path of file/folder to transfer over.")],
|
|
26
|
+
same_file_system: Annotated[bool, typer.Option("--same_file_system", "-s", help="⚠️ Move file across the same file system (not recommended).")] = False,
|
|
27
|
+
destination: Annotated[str, typer.Option("--destination", "-d", help="📍 New path.")] = "",
|
|
28
|
+
pwd: Annotated[Optional[str], typer.Option("--pwd", "-P", help="🔑 Password for encryption.")] = None,
|
|
29
|
+
sshkey: Annotated[Optional[str], typer.Option("--sshkey", "-i", help="🔐 Path to SSH private key.")] = None,
|
|
30
|
+
port: Annotated[Optional[str], typer.Option("--port", "-p", help="🔌 Port number.")] = None,
|
|
31
|
+
zip_first: Annotated[bool, typer.Option("--zip_first", "-z", help="📦 Zip before transferring.")] = False,
|
|
32
|
+
) -> None:
|
|
24
33
|
print("\n" + "=" * 50)
|
|
25
34
|
print("🔄 Welcome to the WSL-Windows File Transfer Tool")
|
|
26
35
|
print("=" * 50 + "\n")
|
|
27
36
|
|
|
28
|
-
|
|
29
|
-
description="""📂 Move and copy files across WSL & Windows.
|
|
30
|
-
The direction is automatically determined by sensing the execution environment.
|
|
31
|
-
Otherwise, a flag must be raised to indicate the direction."""
|
|
32
|
-
)
|
|
37
|
+
path_obj = PathExtended(path).expanduser().absolute()
|
|
33
38
|
|
|
34
|
-
|
|
35
|
-
parser.add_argument("path", help="📁 Path of file/folder to transfer over.")
|
|
36
|
-
# FLAGS
|
|
37
|
-
# this is dangerous and no gaurantee on no corruption.
|
|
38
|
-
parser.add_argument("--same_file_system", "-s", help="⚠️ Move file across the same file system (not recommended).", action="store_true") # default is False
|
|
39
|
-
# optional argument
|
|
40
|
-
parser.add_argument("--destination", "-d", help="📍 New path.", default="")
|
|
41
|
-
parser.add_argument("--pwd", "-P", help="🔑 Password for encryption.", default=None)
|
|
42
|
-
parser.add_argument("--sshkey", "-i", help="🔐 Path to SSH private key.", default=None)
|
|
43
|
-
parser.add_argument("--port", "-p", help="🔌 Port number.", default=None)
|
|
44
|
-
parser.add_argument("--zip_first", "-z", help="📦 Zip before transferring.", action="store_true") # default is False
|
|
45
|
-
|
|
46
|
-
args = parser.parse_args()
|
|
47
|
-
path = PathExtended(args.path).expanduser().absolute()
|
|
48
|
-
|
|
49
|
-
if args.same_file_system:
|
|
39
|
+
if same_file_system:
|
|
50
40
|
print("⚠️ Using a not recommended transfer method! Copying files across the same file system.")
|
|
51
41
|
if system == "Windows": # move files over to WSL
|
|
52
42
|
print("📤 Transferring files from Windows to WSL...")
|
|
53
|
-
|
|
43
|
+
path_obj.copy(folder=WSL_FROM_WIN.joinpath(UserName).joinpath(path_obj.rel2home().parent), overwrite=True) # the following works for files and folders alike.
|
|
54
44
|
else: # move files from WSL to win
|
|
55
45
|
print("📤 Transferring files from WSL to Windows...")
|
|
56
|
-
|
|
46
|
+
path_obj.copy(folder=WIN_FROM_WSL.joinpath(UserName).joinpath(path_obj.rel2home().parent), overwrite=True)
|
|
57
47
|
print("✅ Transfer completed successfully!\n")
|
|
58
48
|
else:
|
|
59
49
|
from machineconfig.utils.ssh import SSH
|
|
60
50
|
import platform
|
|
61
51
|
|
|
62
|
-
|
|
52
|
+
port_int = int(port) if port else (2222 if system == "Windows" else 22)
|
|
63
53
|
username = UserName
|
|
64
54
|
hostname = platform.node()
|
|
65
|
-
ssh = SSH(hostname=hostname, username=username, port=
|
|
55
|
+
ssh = SSH(hostname=hostname, username=username, port=port_int, sshkey=sshkey)
|
|
66
56
|
print("🌐 Initiating SSH transfer...")
|
|
67
|
-
ssh.copy_from_here(source=
|
|
57
|
+
ssh.copy_from_here(source=path_obj, target=destination, z=zip_first)
|
|
68
58
|
print("✅ SSH transfer completed successfully!\n")
|
|
69
59
|
|
|
70
60
|
|
|
61
|
+
def arg_parser() -> None:
|
|
62
|
+
typer.run(main)
|
|
63
|
+
|
|
64
|
+
|
|
71
65
|
if __name__ == "__main__":
|
|
72
|
-
|
|
66
|
+
arg_parser()
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env python
|
|
2
2
|
|
|
3
3
|
from pathlib import Path
|
|
4
|
-
from typing import List, Optional, Union
|
|
4
|
+
from typing import List, Optional, Union, Annotated
|
|
5
5
|
from rich.console import Console
|
|
6
6
|
from rich.panel import Panel
|
|
7
7
|
|
|
8
|
+
import typer
|
|
8
9
|
|
|
9
10
|
def generate_file_checklist(repo_root: Union[str, Path], exclude_dirs: Optional[List[str]] = None) -> Path:
|
|
10
11
|
actual_exclude_dirs: List[str] = [".venv", ".git", "__pycache__", "build", "dist", "*.egg-info"]
|
|
@@ -41,28 +42,27 @@ def generate_file_checklist(repo_root: Union[str, Path], exclude_dirs: Optional[
|
|
|
41
42
|
|
|
42
43
|
print(f"📋 Checklist generated at: {output_path}")
|
|
43
44
|
return output_path
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
parser = argparse.ArgumentParser(description="Generate a markdown file with checkboxes for all .py and .sh files.")
|
|
50
|
-
parser.add_argument("--repo", "-r", type=str, default=str(Path.cwd()), help="Repository root path. Defaults to current working directory.")
|
|
51
|
-
parser.add_argument("--exclude", "-e", nargs="+", type=str, help="Additional directories to exclude (by default excludes .venv, .git, __pycache__, build, dist, *.egg-info)")
|
|
52
|
-
|
|
53
|
-
args = parser.parse_args()
|
|
54
|
-
|
|
45
|
+
def main(
|
|
46
|
+
repo: Annotated[str, typer.Argument(help="Repository root path. Defaults to current working directory.")] = str(Path.cwd()),
|
|
47
|
+
exclude: Annotated[Optional[List[str]], typer.Option("--exclude", "-e", help="Additional directories to exclude (by default excludes .venv, .git, __pycache__, build, dist, *.egg-info)")] = None,
|
|
48
|
+
) -> None:
|
|
55
49
|
exclude_dirs: List[str] = [".venv", ".git", "__pycache__", "build", "dist", "*.egg-info"]
|
|
56
|
-
if
|
|
57
|
-
exclude_dirs.extend(
|
|
58
|
-
if
|
|
50
|
+
if exclude:
|
|
51
|
+
exclude_dirs.extend(exclude)
|
|
52
|
+
if repo == "":
|
|
59
53
|
print("Error: Repository path cannot be empty.")
|
|
60
54
|
return
|
|
61
55
|
|
|
62
|
-
output_path = generate_file_checklist(
|
|
56
|
+
output_path = generate_file_checklist(repo, exclude_dirs)
|
|
63
57
|
console = Console()
|
|
64
58
|
console.print(Panel(f"✅ SUCCESS | Markdown checklist generated successfully!\n📄 File Location: {output_path}", border_style="bold blue", expand=False))
|
|
65
59
|
|
|
66
60
|
|
|
61
|
+
def main_from_parser():
|
|
62
|
+
typer.run(main)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
|
|
67
67
|
if __name__ == "__main__":
|
|
68
|
-
|
|
68
|
+
main_from_parser()
|