magmascript 2.2.0__tar.gz → 2.3.0__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.
- {magmascript-2.2.0 → magmascript-2.3.0}/PKG-INFO +1 -1
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/domains/mc1/client.py +5 -1
- magmascript-2.3.0/magmascript/domains/mc1/tools.py +127 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript.egg-info/PKG-INFO +1 -1
- {magmascript-2.2.0 → magmascript-2.3.0}/pyproject.toml +1 -1
- magmascript-2.2.0/magmascript/domains/mc1/tools.py +0 -82
- {magmascript-2.2.0 → magmascript-2.3.0}/LICENSE +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/README.md +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/__init__.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/cli.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/core/__init__.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/core/cache.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/core/commands.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/core/config.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/core/exceptions.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/core/github.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/core/output.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/core/registry.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/core/rpc.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/core/runner.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/domains/__init__.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/domains/archive/__init__.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/domains/archive/client.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/domains/gh/__init__.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/domains/gh/client.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/domains/gh/tools.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/domains/lastfm/__init__.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/domains/lastfm/client.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/domains/mb/__init__.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/domains/mb/client.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/domains/mc1/__init__.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/domains/mcp/__init__.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/domains/mcp/client.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/domains/mcp/tools.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/domains/media/__init__.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/domains/media/client.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/domains/media/providers/__init__.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/domains/media/providers/archive.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/domains/media/providers/met_museum.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/domains/media/providers/openverse.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/domains/media/providers/pexels.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/domains/media/providers/pixabay.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/domains/media/providers/smithsonian.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/domains/media/tools.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/domains/pi/__init__.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/domains/pi/client.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/domains/pi/tools.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/domains/rights/__init__.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/domains/rights/client.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/domains/rights/tools.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/domains/scores/__init__.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/domains/scores/client.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/domains/scores/tools.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/domains/search/__init__.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/domains/search/client.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/lang/__init__.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/lang/ast_nodes.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/lang/builtins.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/lang/domain_bridge.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/lang/environment.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/lang/interpreter.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/lang/lexer.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/lang/parser.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/lang/pygments_mgs.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/lang/tokens.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/lang/util.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript/repl.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript.egg-info/SOURCES.txt +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript.egg-info/dependency_links.txt +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript.egg-info/entry_points.txt +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript.egg-info/requires.txt +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/magmascript.egg-info/top_level.txt +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/setup.cfg +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/tests/test_cache.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/tests/test_classes.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/tests/test_cli.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/tests/test_commands.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/tests/test_domain_bridge.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/tests/test_import.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/tests/test_lang.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/tests/test_mcp_client.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/tests/test_rpc.py +0 -0
- {magmascript-2.2.0 → magmascript-2.3.0}/tests/test_try_catch.py +0 -0
|
@@ -73,7 +73,11 @@ class MC1Client:
|
|
|
73
73
|
'Write-Host \\"UPTIME:$((Get-Date) - $os.LastBootUpTime)\\"; '
|
|
74
74
|
'Write-Host \\"MEMORY:$([math]::Round($os.TotalVisibleMemorySize/1MB, 1))GB/$([math]::Round(($os.TotalVisibleMemorySize - $os.FreePhysicalMemory)/1MB, 1))GB\\"; '
|
|
75
75
|
'Write-Host \\"CPU:$($cpu.LoadPercentage)%\\"; '
|
|
76
|
-
'Write-Host \\"DISK:$([math]::Round($disk.FreeSpace/$disk.Size*100, 1))% free\\"'
|
|
76
|
+
'Write-Host \\"DISK:$([math]::Round($disk.FreeSpace/$disk.Size*100, 1))% free\\"; '
|
|
77
|
+
'Write-Host \\"DISK_FREE_GB:$([math]::Round($disk.FreeSpace/1GB, 1))GB\\"; '
|
|
78
|
+
'Write-Host \\"CPU_NAME:$($cpu.Name)\\"; '
|
|
79
|
+
'Write-Host \\"CPU_CORES:$($cpu.NumberOfCores)\\"; '
|
|
80
|
+
'Write-Host \\"OS_VERSION:$($os.Caption)\\"'
|
|
77
81
|
'"'
|
|
78
82
|
)
|
|
79
83
|
return parse_system_info(stdout)
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"""Typed result dataclasses for the MC1 domain."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass, field
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@dataclass
|
|
9
|
+
class MC1ServiceStatus:
|
|
10
|
+
"""Status of a Windows service."""
|
|
11
|
+
|
|
12
|
+
name: str
|
|
13
|
+
status: str
|
|
14
|
+
ok: bool
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@dataclass
|
|
18
|
+
class MC1SystemInfo:
|
|
19
|
+
"""MC1 system info."""
|
|
20
|
+
|
|
21
|
+
hostname: str
|
|
22
|
+
uptime: str
|
|
23
|
+
memory: str
|
|
24
|
+
cpu_load: str
|
|
25
|
+
disk_free: str
|
|
26
|
+
disk_free_gb: str = ""
|
|
27
|
+
cpu_name: str = ""
|
|
28
|
+
cpu_cores: str = ""
|
|
29
|
+
os_version: str = ""
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
# ---------------------------------------------------------------------------
|
|
33
|
+
# Uptime formatting
|
|
34
|
+
# ---------------------------------------------------------------------------
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _format_uptime(raw: str) -> str:
|
|
38
|
+
"""Parse .NET TimeSpan string (e.g. '1.03:05:36.7441121') into human-readable form.
|
|
39
|
+
|
|
40
|
+
Format: 'D.HH:MM:SS.fffffff' → '1 day, 3 hours, 5 minutes'
|
|
41
|
+
"""
|
|
42
|
+
try:
|
|
43
|
+
# Split on '.' for days, then ':' for time
|
|
44
|
+
parts = raw.split(".", 1)
|
|
45
|
+
days = int(parts[0]) if parts[0].isdigit() else 0
|
|
46
|
+
|
|
47
|
+
if len(parts) > 1:
|
|
48
|
+
time_parts = parts[1].split(":")
|
|
49
|
+
hours = int(time_parts[0]) if len(time_parts) > 0 else 0
|
|
50
|
+
minutes = int(time_parts[1]) if len(time_parts) > 1 else 0
|
|
51
|
+
else:
|
|
52
|
+
hours = 0
|
|
53
|
+
minutes = 0
|
|
54
|
+
|
|
55
|
+
segments = []
|
|
56
|
+
if days > 0:
|
|
57
|
+
segments.append(f"{days} day{'s' if days != 1 else ''}")
|
|
58
|
+
if hours > 0:
|
|
59
|
+
segments.append(f"{hours} hour{'s' if hours != 1 else ''}")
|
|
60
|
+
if minutes > 0 or not segments:
|
|
61
|
+
segments.append(f"{minutes} min{'s' if minutes != 1 else ''}")
|
|
62
|
+
|
|
63
|
+
return ", ".join(segments)
|
|
64
|
+
except (ValueError, IndexError):
|
|
65
|
+
return raw
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
# ---------------------------------------------------------------------------
|
|
69
|
+
# Parsers
|
|
70
|
+
# ---------------------------------------------------------------------------
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def parse_service_list(text: str) -> list[MC1ServiceStatus]:
|
|
74
|
+
"""Parse PowerShell Get-Service output into MC1ServiceStatus list.
|
|
75
|
+
|
|
76
|
+
Expected format (from the PowerShell command):
|
|
77
|
+
AmdPpkgSvc: Running
|
|
78
|
+
AppIDSvc: Running
|
|
79
|
+
"""
|
|
80
|
+
results = []
|
|
81
|
+
for line in text.splitlines():
|
|
82
|
+
line = line.strip()
|
|
83
|
+
if ":" in line:
|
|
84
|
+
name, status = line.split(":", 1)
|
|
85
|
+
name = name.strip()
|
|
86
|
+
status = status.strip()
|
|
87
|
+
results.append(MC1ServiceStatus(
|
|
88
|
+
name=name,
|
|
89
|
+
status=status,
|
|
90
|
+
ok=status.lower() == "running",
|
|
91
|
+
))
|
|
92
|
+
return results
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def parse_system_info(text: str) -> MC1SystemInfo:
|
|
96
|
+
"""Parse the output of the combined system info command.
|
|
97
|
+
|
|
98
|
+
Expected format:
|
|
99
|
+
HOSTNAME:MC1
|
|
100
|
+
UPTIME:07:33:06.0140847
|
|
101
|
+
MEMORY:31.7GB/7.6GB
|
|
102
|
+
CPU:4%
|
|
103
|
+
DISK:93.2% free
|
|
104
|
+
DISK_FREE_GB:776.9GB
|
|
105
|
+
CPU_NAME:AMD Ryzen 7 8700F 8-Core Processor
|
|
106
|
+
CPU_CORES:8
|
|
107
|
+
OS_VERSION:Microsoft Windows 11 Home
|
|
108
|
+
"""
|
|
109
|
+
info = {
|
|
110
|
+
"hostname": "", "uptime": "", "memory": "", "cpu_load": "",
|
|
111
|
+
"disk_free": "", "disk_free_gb": "", "cpu_name": "",
|
|
112
|
+
"cpu_cores": "", "os_version": "",
|
|
113
|
+
}
|
|
114
|
+
for line in text.splitlines():
|
|
115
|
+
line = line.strip()
|
|
116
|
+
if ":" in line:
|
|
117
|
+
key, val = line.split(":", 1)
|
|
118
|
+
key = key.lower().strip()
|
|
119
|
+
val = val.strip()
|
|
120
|
+
if key in info:
|
|
121
|
+
info[key] = val
|
|
122
|
+
|
|
123
|
+
# Format uptime from raw TimeSpan to human-readable
|
|
124
|
+
if info["uptime"]:
|
|
125
|
+
info["uptime"] = _format_uptime(info["uptime"])
|
|
126
|
+
|
|
127
|
+
return MC1SystemInfo(**info)
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
"""Typed result dataclasses for the MC1 domain."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
from dataclasses import dataclass
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
@dataclass
|
|
9
|
-
class MC1ServiceStatus:
|
|
10
|
-
"""Status of a Windows service."""
|
|
11
|
-
|
|
12
|
-
name: str
|
|
13
|
-
status: str
|
|
14
|
-
ok: bool
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
@dataclass
|
|
18
|
-
class MC1SystemInfo:
|
|
19
|
-
"""MC1 system info."""
|
|
20
|
-
|
|
21
|
-
hostname: str
|
|
22
|
-
uptime: str
|
|
23
|
-
memory: str
|
|
24
|
-
cpu_load: str
|
|
25
|
-
disk_free: str
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
# ---------------------------------------------------------------------------
|
|
29
|
-
# Parsers
|
|
30
|
-
# ---------------------------------------------------------------------------
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
def parse_service_list(text: str) -> list[MC1ServiceStatus]:
|
|
34
|
-
"""Parse PowerShell Get-Service output into MC1ServiceStatus list.
|
|
35
|
-
|
|
36
|
-
Expected format (from the PowerShell command):
|
|
37
|
-
AmdPpkgSvc: Running
|
|
38
|
-
AppIDSvc: Running
|
|
39
|
-
"""
|
|
40
|
-
results = []
|
|
41
|
-
for line in text.splitlines():
|
|
42
|
-
line = line.strip()
|
|
43
|
-
if ":" in line:
|
|
44
|
-
name, status = line.split(":", 1)
|
|
45
|
-
name = name.strip()
|
|
46
|
-
status = status.strip()
|
|
47
|
-
results.append(MC1ServiceStatus(
|
|
48
|
-
name=name,
|
|
49
|
-
status=status,
|
|
50
|
-
ok=status.lower() == "running",
|
|
51
|
-
))
|
|
52
|
-
return results
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
def parse_system_info(text: str) -> MC1SystemInfo:
|
|
56
|
-
"""Parse the output of the combined system info command.
|
|
57
|
-
|
|
58
|
-
Expected format:
|
|
59
|
-
HOSTNAME:MC1
|
|
60
|
-
UPTIME:07:33:06.0140847
|
|
61
|
-
MEMORY:31.7GB/7.6GB
|
|
62
|
-
CPU:4%
|
|
63
|
-
DISK:93.2% free
|
|
64
|
-
"""
|
|
65
|
-
info = {"hostname": "", "uptime": "", "memory": "", "cpu_load": "", "disk_free": ""}
|
|
66
|
-
for line in text.splitlines():
|
|
67
|
-
line = line.strip()
|
|
68
|
-
if ":" in line:
|
|
69
|
-
key, val = line.split(":", 1)
|
|
70
|
-
key = key.lower().strip()
|
|
71
|
-
val = val.strip()
|
|
72
|
-
if key == "hostname":
|
|
73
|
-
info["hostname"] = val
|
|
74
|
-
elif key == "uptime":
|
|
75
|
-
info["uptime"] = val
|
|
76
|
-
elif key == "memory":
|
|
77
|
-
info["memory"] = val
|
|
78
|
-
elif key == "cpu":
|
|
79
|
-
info["cpu_load"] = val
|
|
80
|
-
elif key == "disk":
|
|
81
|
-
info["disk_free"] = val
|
|
82
|
-
return MC1SystemInfo(**info)
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|