zhmiscellany 6.0.8__py3-none-any.whl → 6.1.0__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.
@@ -92,41 +92,54 @@ def patch_cpp():
92
92
  if WIN32_AVAILABLE:
93
93
  patch_cpp()
94
94
 
95
+ # Linux specific imports
96
+ if not WIN32_AVAILABLE:
97
+ try:
98
+ import pyautogui
99
+
100
+ # Optimize PyAutoGUI for speed to match ctypes performance
101
+ pyautogui.FAILSAFE = False
102
+ pyautogui.PAUSE = 0
103
+ pyautogui.MINIMUM_DURATION = 0
104
+ except ImportError:
105
+ raise ImportError("Linux support requires pyautogui. Install it via: pip install pyautogui")
106
+
107
+ # Windows specific imports and Structs
108
+ if WIN32_AVAILABLE:
109
+ class POINT(Structure):
110
+ _fields_ = [("x", c_long),
111
+ ("y", c_long)]
95
112
 
96
- class POINT(Structure):
97
- _fields_ = [("x", c_long),
98
- ("y", c_long)]
99
113
 
114
+ class MOUSEINPUT(Structure):
115
+ _fields_ = [("dx", c_long),
116
+ ("dy", c_long),
117
+ ("mouseData", c_uint),
118
+ ("dwFlags", c_uint),
119
+ ("time", c_uint),
120
+ ("dwExtraInfo", POINTER(c_uint))]
100
121
 
101
- class MOUSEINPUT(Structure):
102
- _fields_ = [("dx", c_long),
103
- ("dy", c_long),
104
- ("mouseData", c_uint),
105
- ("dwFlags", c_uint),
106
- ("time", c_uint),
107
- ("dwExtraInfo", POINTER(c_uint))]
108
122
 
123
+ class INPUT_UNION(ctypes.Union):
124
+ _fields_ = [("mi", MOUSEINPUT)]
109
125
 
110
- class INPUT_UNION(ctypes.Union):
111
- _fields_ = [("mi", MOUSEINPUT)]
112
126
 
127
+ class INPUT(Structure):
128
+ _fields_ = [("type", c_int),
129
+ ("union", INPUT_UNION)]
113
130
 
114
- class INPUT(Structure):
115
- _fields_ = [("type", c_int),
116
- ("union", INPUT_UNION)]
117
131
 
132
+ # Constants
133
+ MOUSEEVENTF_ABSOLUTE = 0x8000
134
+ MOUSEEVENTF_MOVE = 0x0001
135
+ MOUSEEVENTF_LEFTDOWN = 0x0002
136
+ MOUSEEVENTF_LEFTUP = 0x0004
137
+ MOUSEEVENTF_RIGHTDOWN = 0x0008
138
+ MOUSEEVENTF_RIGHTUP = 0x0010
139
+ MOUSEEVENTF_MIDDLEDOWN = 0x0020
140
+ MOUSEEVENTF_MIDDLEUP = 0x0040
118
141
 
119
- # Constants
120
- MOUSEEVENTF_ABSOLUTE = 0x8000
121
- MOUSEEVENTF_MOVE = 0x0001
122
- MOUSEEVENTF_LEFTDOWN = 0x0002
123
- MOUSEEVENTF_LEFTUP = 0x0004
124
- MOUSEEVENTF_RIGHTDOWN = 0x0008
125
- MOUSEEVENTF_RIGHTUP = 0x0010
126
- MOUSEEVENTF_MIDDLEDOWN = 0x0020
127
- MOUSEEVENTF_MIDDLEUP = 0x0040
128
142
 
129
- # Screen metrics
130
143
  def get_actual_screen_resolution():
131
144
  if WIN32_AVAILABLE:
132
145
  hdc = windll.user32.GetDC(0)
@@ -135,19 +148,33 @@ def get_actual_screen_resolution():
135
148
  windll.user32.ReleaseDC(0, hdc)
136
149
  return width, height
137
150
  else:
138
- print("get_actual_screen_resolution() only supports Windows! Returning (1920, 1080)")
139
- return 1920, 1080
151
+ # Linux implementation using pyautogui
152
+ try:
153
+ return pyautogui.size()
154
+ except Exception:
155
+ print("Could not determine screen resolution on Linux, defaulting to 1920x1080")
156
+ return 1920, 1080
140
157
 
141
- SCREEN_WIDTH, SCREEN_HEIGHT = (1920, 1080) if not WIN32_AVAILABLE else get_actual_screen_resolution()
142
158
 
159
+ # Initialize Globals
160
+ SCREEN_WIDTH, SCREEN_HEIGHT = get_actual_screen_resolution()
143
161
  calibrated = False
144
162
  calipass = False
163
+ calibration_multiplier_x = 1.0
164
+ calibration_multiplier_y = 1.0
165
+
145
166
 
146
167
  def move_mouse(x: int, y: int, relative=False):
168
+ # --- LINUX IMPLEMENTATION ---
147
169
  if not WIN32_AVAILABLE:
148
- print("move_mouse() only supports Windows! Functionality disabled")
170
+ # PyAutoGUI handles relative/absolute logic natively
171
+ if relative:
172
+ pyautogui.move(x, y)
173
+ else:
174
+ pyautogui.moveTo(x, y)
149
175
  return
150
-
176
+
177
+ # --- WINDOWS IMPLEMENTATION ---
151
178
  if not relative:
152
179
  # Convert coordinates to normalized coordinates (0-65535)
153
180
  normalized_x = int(x * (65535 / SCREEN_WIDTH))
@@ -182,53 +209,70 @@ def move_mouse(x: int, y: int, relative=False):
182
209
 
183
210
  windll.user32.SendInput(1, ctypes.byref(input_struct), sizeof(INPUT))
184
211
 
212
+
185
213
  def get_mouse_xy():
186
- if WIN32_AVAILABLE:
187
- x, y = win32api.GetCursorPos()
188
- return x, y
189
- else:
190
- print("get_mouse_xy() only supports Windows! Returning (0, 0)")
191
- return 0, 0
214
+ # --- LINUX IMPLEMENTATION ---
215
+ if not WIN32_AVAILABLE:
216
+ return pyautogui.position()
217
+
218
+ # --- WINDOWS IMPLEMENTATION ---
219
+ x, y = win32api.GetCursorPos()
220
+ return x, y
221
+
192
222
 
193
223
  def calibrate():
224
+ """
225
+ Windows-specific calibration for relative movement scaling.
226
+ On Linux, libraries handle this abstraction automatically, so we skip it.
227
+ """
194
228
  if not WIN32_AVAILABLE:
195
- print("calibrate() only supports Windows! Functionality disabled")
196
229
  return
197
-
230
+
198
231
  global calibration_multiplier_x, calibration_multiplier_y, calibrated, calipass
199
232
  if calibrated:
200
233
  return
201
234
  if calipass:
202
235
  return
203
236
  calipass = True
237
+
204
238
  # calibrate relative movement, required because windows is weird
205
239
  original_mouse_point = get_mouse_xy()
206
240
  calibration_distance = 128
207
241
  moved_pos = (0, 0)
208
242
  lim = 64
209
243
  i = 0
244
+
245
+ # Note: logic below calls move_mouse, which calls calibrate,
246
+ # but calipass=True prevents recursion loop
210
247
  while ((not moved_pos[0]) or (not moved_pos[1])) and i < lim:
211
248
  i += 1
212
- move_mouse(0,0)
249
+ move_mouse(0, 0) # Reset to 0,0
213
250
  move_mouse(calibration_distance, calibration_distance, relative=True)
214
251
  moved_pos = get_mouse_xy()
252
+
215
253
  if not i < lim:
216
- raise Exception('Relative mouse movement could not be calibrated, maybe you were tabbed into an application that was controlling your mouse?')
217
- calibration_multiplier_x = calibration_distance/moved_pos[0]
218
- calibration_multiplier_y = calibration_distance/moved_pos[1]
254
+ raise Exception('Relative mouse movement could not be calibrated.')
255
+
256
+ calibration_multiplier_x = calibration_distance / moved_pos[0]
257
+ calibration_multiplier_y = calibration_distance / moved_pos[1]
219
258
  calibrated = True
220
- move_mouse(original_mouse_point[0]+1, original_mouse_point[1]+1)
259
+
260
+ # Return mouse to original position
261
+ move_mouse(original_mouse_point[0], original_mouse_point[1])
221
262
 
222
263
 
223
264
  def mouse_down(button: int):
224
265
  """Press mouse button down. button: 1=left, 2=right, 3=middle"""
225
- if not WIN32_AVAILABLE:
226
- print("mouse_down() only supports Windows! Functionality disabled")
227
- return
228
-
229
266
  if button not in [1, 2, 3]:
230
267
  raise ValueError("Button must be 1 (left), 2 (right), or 3 (middle)")
231
268
 
269
+ # --- LINUX IMPLEMENTATION ---
270
+ if not WIN32_AVAILABLE:
271
+ btn_map = {1: 'left', 2: 'right', 3: 'middle'}
272
+ pyautogui.mouseDown(button=btn_map[button])
273
+ return
274
+
275
+ # --- WINDOWS IMPLEMENTATION ---
232
276
  flags = {
233
277
  1: MOUSEEVENTF_LEFTDOWN,
234
278
  2: MOUSEEVENTF_RIGHTDOWN,
@@ -254,13 +298,16 @@ def mouse_down(button: int):
254
298
 
255
299
  def mouse_up(button: int):
256
300
  """Release mouse button. button: 1=left, 2=right, 3=middle"""
257
- if not WIN32_AVAILABLE:
258
- print("mouse_up() only supports Windows! Functionality disabled")
259
- return
260
-
261
301
  if button not in [1, 2, 3]:
262
302
  raise ValueError("Button must be 1 (left), 2 (right), or 3 (middle)")
263
303
 
304
+ # --- LINUX IMPLEMENTATION ---
305
+ if not WIN32_AVAILABLE:
306
+ btn_map = {1: 'left', 2: 'right', 3: 'middle'}
307
+ pyautogui.mouseUp(button=btn_map[button])
308
+ return
309
+
310
+ # --- WINDOWS IMPLEMENTATION ---
264
311
  flags = {
265
312
  1: MOUSEEVENTF_LEFTUP,
266
313
  2: MOUSEEVENTF_RIGHTUP,
@@ -281,4 +328,4 @@ def mouse_up(button: int):
281
328
  )
282
329
  )
283
330
 
284
- windll.user32.SendInput(1, ctypes.byref(input_struct), sizeof(INPUT))
331
+ windll.user32.SendInput(1, ctypes.byref(input_struct), sizeof(INPUT))
@@ -14,10 +14,8 @@ if sys.platform == "win32":
14
14
  RAY_AVAILABLE = True
15
15
  except ImportError:
16
16
  RAY_AVAILABLE = False
17
- print("Warning: Ray not available - multiprocessing functionality disabled")
18
17
  else:
19
18
  RAY_AVAILABLE = False
20
- print("Ray is only supported on Windows - multiprocessing functionality disabled")
21
19
 
22
20
 
23
21
  def clear_logs():
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: zhmiscellany
3
- Version: 6.0.8
3
+ Version: 6.1.0
4
4
  Summary: A collection of useful/interesting python libraries made by zh.
5
5
  Home-page: https://discord.gg/ThBBAuueVJ
6
6
  Author: zh
@@ -1,8 +1,8 @@
1
1
  zhmiscellany/__init__.py,sha256=Oh3gAJRWq2aUEgkolmQyiZOQ3iey5OC4NA2XaTHuVv4,1139
2
2
  zhmiscellany/_discord_supportfuncs.py,sha256=RotSpurqFtL5q6v_ST1e2Y_1qJMaHp1CDsF5i-gR4ec,6524
3
3
  zhmiscellany/_fileio_supportfuncs.py,sha256=soibLv9nOR79sHQ2MGQH2O6MhnqdXqI7ybxHSN2Tfac,434
4
- zhmiscellany/_misc_supportfuncs.py,sha256=3JaEUx2Kq4xfSL91JALAHP2SRjHmmEXnwyzHIhXz_gE,8531
5
- zhmiscellany/_processing_supportfuncs.py,sha256=2xUe5R6xc38LLCWLj9XxGEHMyYvvli_BOppdR9wkJmo,11245
4
+ zhmiscellany/_misc_supportfuncs.py,sha256=pMd7Y4hzstn5BFFlBQbkZYQetvy5WCx8hFb-hL3FO0s,9799
5
+ zhmiscellany/_processing_supportfuncs.py,sha256=u5dzW-2OtyViC74r5fhqd5_2uQ92ZhieRJRTJMevqbg,11071
6
6
  zhmiscellany/_py_resources.py,sha256=HqJs5aRLymLZ2J5Io8g6bY58pGWhN9b8vCktC2DW4KQ,229009
7
7
  zhmiscellany/_resource_files_lookup.py,sha256=hsgPW0dngokgqWrAVAv5rUo-eobzJPjvWHt4xrOG5l0,856
8
8
  zhmiscellany/cpp.py,sha256=XEUEoIKCDCdY5VgwNWE5oXrGjtsmGdz_MnaVwQmi2dk,179
@@ -21,7 +21,7 @@ zhmiscellany/pipes.py,sha256=zETvWP4PF-PuSzYwR1UCodY4ftNAgmCChb9DUMofXok,4657
21
21
  zhmiscellany/processing.py,sha256=sDKIbzG9TNFyT6yJ4TJL59taG-59_v3CBLekVSLrwgE,10899
22
22
  zhmiscellany/rust.py,sha256=znN6DYNoa_p-braTuDZKvUnXX8reWLFu_dG4fv2vLR0,442
23
23
  zhmiscellany/string.py,sha256=xyqE6V5YF2nieZDcg5ZrXTIrH2D9oDRbZ5vQGz8rPys,4787
24
- zhmiscellany-6.0.8.dist-info/METADATA,sha256=oWEEHwOweowIAemVEJZ228WQdIs61E-yt2cdK39YtMk,43560
25
- zhmiscellany-6.0.8.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
26
- zhmiscellany-6.0.8.dist-info/top_level.txt,sha256=ioDtsrevCI52rTxZntMPljRIBsZs73tD0hI00HektiE,13
27
- zhmiscellany-6.0.8.dist-info/RECORD,,
24
+ zhmiscellany-6.1.0.dist-info/METADATA,sha256=IzKNJvKrOuFNwLX6d3-3alPiedJn7KmupqYwQhZgQZI,43560
25
+ zhmiscellany-6.1.0.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
26
+ zhmiscellany-6.1.0.dist-info/top_level.txt,sha256=ioDtsrevCI52rTxZntMPljRIBsZs73tD0hI00HektiE,13
27
+ zhmiscellany-6.1.0.dist-info/RECORD,,