machineconfig 5.91__py3-none-any.whl → 5.93__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.

@@ -2,12 +2,11 @@
2
2
 
3
3
  import psutil
4
4
  from rich.progress import Progress, SpinnerColumn, TextColumn
5
- from zoneinfo import ZoneInfo
6
5
  from machineconfig.utils.options import choose_from_options
7
- from typing import Optional, Any
6
+ from typing import Optional, TypedDict, List, Dict
8
7
  from rich.console import Console
9
8
  from rich.panel import Panel
10
- from datetime import datetime, timezone
9
+ from datetime import datetime
11
10
  from machineconfig.utils.accessories import pprint
12
11
 
13
12
  console = Console()
@@ -15,11 +14,29 @@ console = Console()
15
14
  BOX_WIDTH = 78 # width for box drawing
16
15
 
17
16
 
18
- def get_processes_accessing_file(path: str):
17
+ class ProcessInfo(TypedDict):
18
+ """TypedDict for process information."""
19
+ command: str
20
+ pid: int
21
+ name: str
22
+ username: str
23
+ cpu_percent: float
24
+ memory_usage_mb: float
25
+ status: str
26
+ create_time: datetime
27
+
28
+
29
+ class FileAccessInfo(TypedDict):
30
+ """TypedDict for file access information."""
31
+ pid: int
32
+ files: List[str]
33
+
34
+
35
+ def get_processes_accessing_file(path: str) -> List[FileAccessInfo]:
19
36
  # header for searching processes
20
37
  title = "🔍 SEARCHING FOR PROCESSES ACCESSING FILE"
21
38
  console.print(Panel(title, title="[bold blue]Process Info[/bold blue]", border_style="blue"))
22
- res: dict[int, list[str]] = {}
39
+ res: Dict[int, List[str]] = {}
23
40
 
24
41
  with Progress(SpinnerColumn(), TextColumn("[progress.description]{task.description}")) as progress:
25
42
  progress.add_task("🔎 Scanning processes...", total=None)
@@ -34,7 +51,7 @@ def get_processes_accessing_file(path: str):
34
51
  res[proc.pid] = tmp
35
52
 
36
53
  # Convert to list of dictionaries for consistent data structure
37
- result_data = [{"pid": pid, "files": files} for pid, files in res.items()]
54
+ result_data: List[FileAccessInfo] = [{"pid": pid, "files": files} for pid, files in res.items()]
38
55
  console.print(Panel(f"✅ Found {len(res)} processes accessing the specified file", title="[bold blue]Process Info[/bold blue]", border_style="blue"))
39
56
  return result_data
40
57
 
@@ -57,15 +74,13 @@ class ProcessManager:
57
74
  # header for initializing process manager
58
75
  title = "📊 INITIALIZING PROCESS MANAGER"
59
76
  console.print(Panel(title, title="[bold blue]Process Info[/bold blue]", border_style="blue"))
60
- process_info = []
77
+ process_info: List[ProcessInfo] = []
61
78
  with Progress(SpinnerColumn(), TextColumn("[progress.description]{task.description}")) as progress:
62
79
  progress.add_task("🔍 Reading system processes...", total=None)
63
80
  for proc in psutil.process_iter():
64
81
  try:
65
82
  mem_usage_mb = proc.memory_info().rss / (1024 * 1024)
66
- # Convert create_time to local timezone
67
- create_time_utc = datetime.fromtimestamp(proc.create_time(), tz=timezone.utc)
68
- create_time_local = create_time_utc.astimezone(ZoneInfo("Australia/Adelaide"))
83
+ create_time = datetime.fromtimestamp(proc.create_time(), tz=None)
69
84
 
70
85
  process_info.append(
71
86
  {
@@ -75,7 +90,7 @@ class ProcessManager:
75
90
  "cpu_percent": proc.cpu_percent(),
76
91
  "memory_usage_mb": mem_usage_mb,
77
92
  "status": proc.status(),
78
- "create_time": create_time_local,
93
+ "create_time": create_time,
79
94
  "command": " ".join(proc.cmdline()),
80
95
  }
81
96
  )
@@ -93,8 +108,8 @@ class ProcessManager:
93
108
  return ""
94
109
 
95
110
  # Create header
96
- _headers = ["PID", "Name", "Username", "CPU%", "Memory(MB)", "Status", "Create Time", "Command"]
97
- header_line = f"{'PID':<8} {'Name':<20} {'Username':<12} {'CPU%':<8} {'Memory(MB)':<12} {'Status':<12} {'Create Time':<20} {'Command':<50}"
111
+ _headers = ["Command", "PID", "Name", "Username", "CPU%", "Memory(MB)", "Status", "Create Time"]
112
+ header_line = f"{'Command':<50} {'PID':<8} {'Name':<20} {'Username':<12} {'CPU%':<8} {'Memory(MB)':<12} {'Status':<12} {'Create Time':<20}"
98
113
  separator = "-" * len(header_line)
99
114
 
100
115
  lines = [header_line, separator]
@@ -105,7 +120,7 @@ class ProcessManager:
105
120
  # Truncate command if too long
106
121
  command = process["command"][:47] + "..." if len(process["command"]) > 50 else process["command"]
107
122
 
108
- line = f"{process['pid']:<8} {process['name'][:19]:<20} {process['username'][:11]:<12} {process['cpu_percent']:<8.1f} {process['memory_usage_mb']:<12.2f} {process['status'][:11]:<12} {create_time_str:<20} {command:<50}"
123
+ line = f"{command:<50} {process['pid']:<8} {process['name'][:19]:<20} {process['username'][:11]:<12} {process['cpu_percent']:<8.1f} {process['memory_usage_mb']:<12.2f} {process['status'][:11]:<12} {create_time_str:<20}"
109
124
  lines.append(line)
110
125
 
111
126
  return "\n".join(lines)
@@ -129,7 +144,7 @@ class ProcessManager:
129
144
  print(f"PID: {process['pid']}, Name: {process['name']}, Memory: {process['memory_usage_mb']:.2f}MB")
130
145
 
131
146
  for idx, process in enumerate(selected_processes):
132
- pprint(process, f"📌 Process {idx}")
147
+ pprint(dict(process), f"📌 Process {idx}")
133
148
 
134
149
  kill_all = input("\n⚠️ Confirm killing ALL selected processes? y/[n] ").lower() == "y"
135
150
  if kill_all:
@@ -141,7 +156,7 @@ class ProcessManager:
141
156
  indices = [int(val) for val in kill_by_index.split(" ")]
142
157
  target_processes = [selected_processes[i] for i in indices]
143
158
  for idx2, process in enumerate(target_processes):
144
- pprint(process, f"🎯 Target Process {idx2}")
159
+ pprint(dict(process), f"🎯 Target Process {idx2}")
145
160
  _ = self.kill(pids=[p["pid"] for p in target_processes]) if input("\n⚠️ Confirm termination? y/[n] ").lower() == "y" else None
146
161
  console.print(Panel("🔔 No processes were terminated.", title="[bold blue]Process Info[/bold blue]", border_style="blue"))
147
162
 
@@ -188,7 +203,7 @@ class ProcessManager:
188
203
  try:
189
204
  proc = psutil.Process(pid)
190
205
  proc_name = proc.name()
191
- proc_lifetime = get_age(proc.create_time())
206
+ proc_lifetime = get_age(datetime.fromtimestamp(proc.create_time(), tz=None))
192
207
  proc.kill()
193
208
  print(f'💀 Killed process with PID {pid} and name "{proc_name}". It lived {proc_lifetime}. RIP 🪦💐')
194
209
  killed_count += 1
@@ -208,32 +223,10 @@ class ProcessManager:
208
223
  console.print(Panel(f"✅ Termination complete: {killed_count} processes terminated", title="[bold blue]Process Info[/bold blue]", border_style="blue"))
209
224
 
210
225
 
211
- def get_age(create_time: Any) -> str:
212
- """Calculate age from create_time which can be either float timestamp or datetime object."""
213
- try:
214
- if isinstance(create_time, (int, float)):
215
- # Handle timestampz
216
- create_time_utc = datetime.fromtimestamp(create_time, tz=timezone.utc)
217
- create_time_local = create_time_utc.astimezone(ZoneInfo("Australia/Adelaide"))
218
- else:
219
- # Already a datetime object
220
- create_time_local = create_time
221
-
222
- now_local = datetime.now(tz=ZoneInfo("Australia/Adelaide"))
223
- age = now_local - create_time_local
224
- return str(age)
225
- except Exception as e:
226
- try:
227
- # Fallback without timezone
228
- if isinstance(create_time, (int, float)):
229
- create_time_dt = datetime.fromtimestamp(create_time)
230
- else:
231
- create_time_dt = create_time.replace(tzinfo=None) if create_time.tzinfo else create_time
232
- now_dt = datetime.now()
233
- age = now_dt - create_time_dt
234
- return str(age)
235
- except Exception as ee:
236
- return f"unknown due to {ee} and {e}"
226
+ def get_age(create_time: datetime) -> str:
227
+ dtm_now = datetime.now()
228
+ delta = dtm_now - create_time
229
+ return str(delta).split(".")[0] # remove microseconds
237
230
 
238
231
 
239
232
  def main():
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: machineconfig
3
- Version: 5.91
3
+ Version: 5.93
4
4
  Summary: Dotfiles management package
5
5
  Author-email: Alex Al-Saffar <programmer@usa.com>
6
6
  License: Apache 2.0
@@ -392,7 +392,7 @@ machineconfig/utils/notifications.py,sha256=tuXIudcip0tEioG-bm8BbLr3FMDve4f6Bktl
392
392
  machineconfig/utils/options.py,sha256=vUO4Kej-vDOv64wHr2HNDyu6PATURpjd7xp6N8OOoJg,7083
393
393
  machineconfig/utils/path_extended.py,sha256=4RhL0twcIG2kJxmC4r_YzaiTxrYkSRbdh9SO5ObMABw,53122
394
394
  machineconfig/utils/path_helper.py,sha256=0e3Xh3BAEv27oqcezNeVLHJllGmLEgLH4T1l90m-650,8014
395
- machineconfig/utils/procs.py,sha256=w75oGKfR7FpT1pGTGd2XscnEOO0IHBWxohLbi69hLqg,11418
395
+ machineconfig/utils/procs.py,sha256=rw8LR8MjGgvtrpcgxb3hudq2B9fkkpYUXe9x5-FgHuc,10694
396
396
  machineconfig/utils/scheduler.py,sha256=jZ_1yghqA3-aINPRmE_76gboqJc0UElroR7urNOfXKs,14940
397
397
  machineconfig/utils/scheduling.py,sha256=RF1iXJpqf4Dg18jdZWtBixz97KAHC6VKYqTFSpdLWuc,11188
398
398
  machineconfig/utils/source_of_truth.py,sha256=ZAnCRltiM07ig--P6g9_6nEAvNFC4X4ERFTVcvpIYsE,764
@@ -421,8 +421,8 @@ machineconfig/utils/schemas/installer/installer_types.py,sha256=QClRY61QaduBPJoS
421
421
  machineconfig/utils/schemas/layouts/layout_types.py,sha256=TcqlZdGVoH8htG5fHn1KWXhRdPueAcoyApppZsPAPto,2020
422
422
  machineconfig/utils/schemas/repos/repos_types.py,sha256=ECVr-3IVIo8yjmYmVXX2mnDDN1SLSwvQIhx4KDDQHBQ,405
423
423
  machineconfig/utils/ssh_utils/utils.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
424
- machineconfig-5.91.dist-info/METADATA,sha256=GhvLlUJSx4c1ZSW0-rkO3Okoh-yx_b4oJSKIo6Dpj3M,3012
425
- machineconfig-5.91.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
426
- machineconfig-5.91.dist-info/entry_points.txt,sha256=M0jwN_brZdXWhmNVeXLvdKxfkv8WhhXFZYcuKBA9qnk,418
427
- machineconfig-5.91.dist-info/top_level.txt,sha256=porRtB8qms8fOIUJgK-tO83_FeH6Bpe12oUVC670teA,14
428
- machineconfig-5.91.dist-info/RECORD,,
424
+ machineconfig-5.93.dist-info/METADATA,sha256=ppdZOK8vxv-rB6t3fOorFFUKn6JRjcHuLtiNDldb-HQ,3012
425
+ machineconfig-5.93.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
426
+ machineconfig-5.93.dist-info/entry_points.txt,sha256=M0jwN_brZdXWhmNVeXLvdKxfkv8WhhXFZYcuKBA9qnk,418
427
+ machineconfig-5.93.dist-info/top_level.txt,sha256=porRtB8qms8fOIUJgK-tO83_FeH6Bpe12oUVC670teA,14
428
+ machineconfig-5.93.dist-info/RECORD,,