ConsoleFramework 1.0.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.
@@ -0,0 +1,795 @@
1
+ """
2
+ ConsoleFramework - The best Console Library of the Python.
3
+ By: Suleiman
4
+ Copyright © Suleiman 2026
5
+ All rights are reserved.
6
+ """
7
+ import os
8
+ import sys
9
+ import time
10
+ import math
11
+ import random
12
+ import socket
13
+ import zlib
14
+ import urllib.request
15
+ import json
16
+ import threading
17
+ import platform
18
+ import zipfile
19
+ import stat
20
+ import subprocess as CMD
21
+ import threading
22
+ import urllib.request
23
+ import urllib.parse
24
+ import base64
25
+ class Colors:
26
+ RESET = "\033[0m"
27
+ RED = "\033[31m"
28
+ GREEN = "\033[32m"
29
+ BLUE = "\033[34m"
30
+ CYAN = "\033[36m"
31
+ MAGENTA = "\033[35m"
32
+ YELLOW = "\033[33m"
33
+ WHITE = "\033[37m"
34
+ BLACK = "\033[30m"
35
+ BG_RED = "\033[41m"
36
+ BG_GREEN = "\033[42m"
37
+ BG_BLUE = "\033[44m"
38
+ BG_CYAN = "\033[46m"
39
+ BG_MAGENTA = "\033[45m"
40
+ BG_YELLOW = "\033[43m"
41
+ BG_WHITE = "\033[47m"
42
+ BG_BLACK = "\033[40m"
43
+ BOLD = "\033[1m"
44
+ DIM = "\033[2m"
45
+ ITALIC = "\033[3m"
46
+ UNDERLINE = "\033[4m"
47
+ BLINK = "\033[5m"
48
+ REVERSE = "\033[7m"
49
+ HIDDEN = "\033[8m"
50
+ STRIKE = "\033[9m"
51
+
52
+ @staticmethod
53
+ def rgb(r, g, b):
54
+ return f"\033[38;2;{r};{g};{b}m"
55
+
56
+ @staticmethod
57
+ def bg_rgb(r, g, b):
58
+ return f"\033[48;2;{r};{g};{b}m"
59
+
60
+ @staticmethod
61
+ def colorize(text, color, reset=True):
62
+ reset_code = Colors.RESET if reset else ""
63
+ return f"{color}{text}{reset_code}"
64
+
65
+ class Render:
66
+ @staticmethod
67
+ def DrawPic(points=None, width=80, height=25, clear_before_draw=False, default_char=' '):
68
+ if clear_before_draw:
69
+ os.system("cls" if os.name == "nt" else "clear")
70
+ field = [[default_char for _ in range(width)] for _ in range(height)]
71
+ if points:
72
+ for item in points:
73
+ if len(item) >= 3:
74
+ x, y, char = item[0], item[1], item[2]
75
+ if 0 <= x < width and 0 <= y < height:
76
+ if len(item) == 4:
77
+ color = item[3]
78
+ field[y][x] = f"{color}{char}{Colors.RESET}"
79
+ elif len(item) == 5:
80
+ color, bg = item[3], item[4]
81
+ field[y][x] = f"{color}{bg}{char}{Colors.RESET}"
82
+ else:
83
+ field[y][x] = char
84
+ for row in field:
85
+ print(''.join(row))
86
+ @staticmethod
87
+ def _apply_color(points, color=None, bg=None):
88
+ if color is None and bg is None:
89
+ return points
90
+ result = []
91
+ for p in points:
92
+ if len(p) == 3:
93
+ x, y, char = p
94
+ if color and bg:
95
+ result.append((x, y, char, color, bg))
96
+ elif color:
97
+ result.append((x, y, char, color))
98
+ else:
99
+ result.append((x, y, char, Colors.BG_BLACK + bg))
100
+ else:
101
+ result.append(p)
102
+ return result
103
+
104
+ @staticmethod
105
+ def get_line_points(x1, y1, x2, y2, char='#', color=None, bg=None):
106
+ points = []
107
+ dx = abs(x2 - x1)
108
+ dy = abs(y2 - y1)
109
+ sx = 1 if x1 < x2 else -1
110
+ sy = 1 if y1 < y2 else -1
111
+ err = dx - dy
112
+ while True:
113
+ points.append((x1, y1, char))
114
+ if x1 == x2 and y1 == y2:
115
+ break
116
+ e2 = err * 2
117
+ if e2 > -dy:
118
+ err -= dy
119
+ x1 += sx
120
+ if e2 < dx:
121
+ err += dx
122
+ y1 += sy
123
+ return Render._apply_color(points, color, bg)
124
+
125
+ @staticmethod
126
+ def get_circle_points(cx, cy, r, char='#', color=None, bg=None):
127
+ points = []
128
+ for angle in range(0, 360, 5):
129
+ rad = angle * math.pi / 180
130
+ x = int(cx + r * math.cos(rad))
131
+ y = int(cy + r * math.sin(rad))
132
+ points.append((x, y, char))
133
+ return Render._apply_color(points, color, bg)
134
+
135
+ @staticmethod
136
+ def get_filled_circle_points(cx, cy, r, char='#', color=None, bg=None):
137
+ points = []
138
+ for y in range(cy - r, cy + r + 1):
139
+ for x in range(cx - r, cx + r + 1):
140
+ if (x - cx) ** 2 + (y - cy) ** 2 <= r ** 2:
141
+ points.append((x, y, char))
142
+ return Render._apply_color(points, color, bg)
143
+
144
+ @staticmethod
145
+ def get_rect_points(x1, y1, x2, y2, char='#', color=None, bg=None):
146
+ points = []
147
+ for x in range(x1, x2 + 1):
148
+ points.append((x, y1, char))
149
+ points.append((x, y2, char))
150
+ for y in range(y1, y2 + 1):
151
+ points.append((x1, y, char))
152
+ points.append((x2, y, char))
153
+ return Render._apply_color(points, color, bg)
154
+
155
+ @staticmethod
156
+ def get_fill_rect_points(x1, y1, x2, y2, char='#', color=None, bg=None):
157
+ points = []
158
+ for y in range(y1, y2 + 1):
159
+ for x in range(x1, x2 + 1):
160
+ points.append((x, y, char))
161
+ return Render._apply_color(points, color, bg)
162
+
163
+ @staticmethod
164
+ def get_text_points(x, y, text, char=None, color=None, bg=None):
165
+ points = []
166
+ if char is None:
167
+ for i, ch in enumerate(text):
168
+ points.append((x + i, y, ch))
169
+ else:
170
+ for i in range(len(text)):
171
+ points.append((x + i, y, char))
172
+ return Render._apply_color(points, color, bg)
173
+
174
+ @staticmethod
175
+ def get_triangle_points(x1, y1, x2, y2, x3, y3, char='#', color=None, bg=None):
176
+ points = []
177
+ points.extend(Render.get_line_points(x1, y1, x2, y2, char))
178
+ points.extend(Render.get_line_points(x2, y2, x3, y3, char))
179
+ points.extend(Render.get_line_points(x3, y3, x1, y1, char))
180
+ return Render._apply_color(points, color, bg)
181
+
182
+ @staticmethod
183
+ def get_filled_triangle_points(x1, y1, x2, y2, x3, y3, char='#', color=None, bg=None):
184
+ points = []
185
+ min_x = min(x1, x2, x3)
186
+ max_x = max(x1, x2, x3)
187
+ min_y = min(y1, y2, y3)
188
+ max_y = max(y1, y2, y3)
189
+ for y in range(min_y, max_y + 1):
190
+ for x in range(min_x, max_x + 1):
191
+ if Render._point_in_triangle(x, y, x1, y1, x2, y2, x3, y3):
192
+ points.append((x, y, char))
193
+ return Render._apply_color(points, color, bg)
194
+
195
+ @staticmethod
196
+ def get_heart_points(cx, cy, size=5, char='#', color=None, bg=None):
197
+ points = []
198
+ for y in range(-size, size + 1):
199
+ for x in range(-size, size + 1):
200
+ if ((x * x + y * y - size * size) ** 3 <= size * size * x * x * y * y * 0.5):
201
+ points.append((cx + x, cy - y, char))
202
+ return Render._apply_color(points, color, bg)
203
+
204
+ @staticmethod
205
+ def get_star_points(cx, cy, radius=5, points_count=5, char='*', color=None, bg=None):
206
+ points = []
207
+ angle = -math.pi / 2
208
+ step = math.pi / points_count
209
+ outer_points = []
210
+ inner_points = []
211
+ for i in range(points_count * 2):
212
+ r = radius if i % 2 == 0 else radius * 0.4
213
+ x = cx + r * math.cos(angle + i * step)
214
+ y = cy + r * math.sin(angle + i * step)
215
+ if i % 2 == 0:
216
+ outer_points.append((x, y))
217
+ else:
218
+ inner_points.append((x, y))
219
+ for i in range(points_count):
220
+ p1 = outer_points[i]
221
+ p2 = inner_points[i]
222
+ p3 = outer_points[(i + 1) % points_count]
223
+ points.extend(Render.get_line_points(int(p1[0]), int(p1[1]), int(p2[0]), int(p2[1]), char))
224
+ points.extend(Render.get_line_points(int(p2[0]), int(p2[1]), int(p3[0]), int(p3[1]), char))
225
+ return Render._apply_color(points, color, bg)
226
+
227
+ @staticmethod
228
+ def get_bezier_points(x1, y1, x2, y2, x3, y3, steps=20, char='#', color=None, bg=None):
229
+ points = []
230
+ for t in range(steps + 1):
231
+ t = t / steps
232
+ x = (1 - t) ** 2 * x1 + 2 * (1 - t) * t * x2 + t ** 2 * x3
233
+ y = (1 - t) ** 2 * y1 + 2 * (1 - t) * t * y2 + t ** 2 * y3
234
+ points.append((int(x), int(y), char))
235
+ return Render._apply_color(points, color, bg)
236
+
237
+ @staticmethod
238
+ def get_wave_points(cx, cy, amplitude=5, length=20, char='~', color=None, bg=None):
239
+ points = []
240
+ for x in range(length):
241
+ y = cy + int(amplitude * math.sin(x * 0.5))
242
+ points.append((cx + x, y, char))
243
+ return Render._apply_color(points, color, bg)
244
+
245
+ @staticmethod
246
+ def get_spiral_points(cx, cy, turns=3, radius=10, step=0.1, char='*', color=None, bg=None):
247
+ points = []
248
+ angle = 0
249
+ r = 0
250
+ while r < radius:
251
+ x = int(cx + r * math.cos(angle))
252
+ y = int(cy + r * math.sin(angle))
253
+ points.append((x, y, char))
254
+ angle += step
255
+ r += step * 2
256
+ return Render._apply_color(points, color, bg)
257
+
258
+ @staticmethod
259
+ def get_grid_points(x1, y1, x2, y2, step=2, char='+', color=None, bg=None):
260
+ points = []
261
+ for x in range(x1, x2 + 1, step):
262
+ for y in range(y1, y2 + 1, step):
263
+ points.append((x, y, char))
264
+ return Render._apply_color(points, color, bg)
265
+
266
+ @staticmethod
267
+ def get_noise_points(cx, cy, radius, count=50, char='.', color=None, bg=None):
268
+ points = []
269
+ for _ in range(count):
270
+ angle = random.uniform(0, 2 * math.pi)
271
+ r = random.uniform(0, radius)
272
+ x = int(cx + r * math.cos(angle))
273
+ y = int(cy + r * math.sin(angle))
274
+ points.append((x, y, char))
275
+ return Render._apply_color(points, color, bg)
276
+
277
+ # ---- 3D ----
278
+ @staticmethod
279
+ def _point_in_triangle(px, py, x1, y1, x2, y2, x3, y3):
280
+ def sign(a, b, c):
281
+ return (a[0] - c[0]) * (b[1] - c[1]) - (b[0] - c[0]) * (a[1] - c[1])
282
+ p = (px, py)
283
+ d1 = sign(p, (x2, y2), (x1, y1))
284
+ d2 = sign(p, (x3, y3), (x2, y2))
285
+ d3 = sign(p, (x1, y1), (x3, y3))
286
+ has_neg = (d1 < 0) or (d2 < 0) or (d3 < 0)
287
+ has_pos = (d1 > 0) or (d2 > 0) or (d3 > 0)
288
+ return not (has_neg and has_pos)
289
+
290
+ @staticmethod
291
+ def _rotx(x, y, z, angle):
292
+ rad = math.radians(angle)
293
+ cos_a = math.cos(rad)
294
+ sin_a = math.sin(rad)
295
+ y_new = y * cos_a - z * sin_a
296
+ z_new = y * sin_a + z * cos_a
297
+ return x, y_new, z_new
298
+
299
+ @staticmethod
300
+ def _roty(x, y, z, angle):
301
+ rad = math.radians(angle)
302
+ cos_a = math.cos(rad)
303
+ sin_a = math.sin(rad)
304
+ x_new = x * cos_a + z * sin_a
305
+ z_new = -x * sin_a + z * cos_a
306
+ return x_new, y, z_new
307
+
308
+ @staticmethod
309
+ def _rotz(x, y, z, angle):
310
+ rad = math.radians(angle)
311
+ cos_a = math.cos(rad)
312
+ sin_a = math.sin(rad)
313
+ x_new = x * cos_a - y * sin_a
314
+ y_new = x * sin_a + y * cos_a
315
+ return x_new, y_new, z
316
+
317
+ @staticmethod
318
+ def _project_3d(x, y, z, rotx, roty, rotz, scale, cx, cy):
319
+ x, y, z = Render._rotx(x, y, z, rotx)
320
+ x, y, z = Render._roty(x, y, z, roty)
321
+ x, y, z = Render._rotz(x, y, z, rotz)
322
+ x2d = int(x * scale + cx)
323
+ y2d = int(-y * scale + cy)
324
+ return x2d, y2d
325
+
326
+ @staticmethod
327
+ def get_cube_3d_points(size=5, rotx=0, roty=0, rotz=0, scale=10, cx=40, cy=12, char='#', color=None, bg=None):
328
+ s = size / 2
329
+ vertices = [
330
+ (-s, -s, -s), (s, -s, -s), (s, s, -s), (-s, s, -s),
331
+ (-s, -s, s), (s, -s, s), (s, s, s), (-s, s, s)
332
+ ]
333
+ edges = [
334
+ (0,1), (1,2), (2,3), (3,0),
335
+ (4,5), (5,6), (6,7), (7,4),
336
+ (0,4), (1,5), (2,6), (3,7)
337
+ ]
338
+ points = []
339
+ projected = []
340
+ for v in vertices:
341
+ x2d, y2d = Render._project_3d(v[0], v[1], v[2], rotx, roty, rotz, scale, cx, cy)
342
+ projected.append((x2d, y2d))
343
+ for edge in edges:
344
+ x1, y1 = projected[edge[0]]
345
+ x2, y2 = projected[edge[1]]
346
+ points.extend(Render.get_line_points(x1, y1, x2, y2, char))
347
+ return Render._apply_color(points, color, bg)
348
+
349
+ @staticmethod
350
+ def get_pyramid_3d_points(size=5, rotx=0, roty=0, rotz=0, scale=10, cx=40, cy=12, char='#', color=None, bg=None):
351
+ s = size / 2
352
+ vertices = [
353
+ (-s, -s, -s), (s, -s, -s), (s, -s, s), (-s, -s, s),
354
+ (0, s, 0)
355
+ ]
356
+ edges = [
357
+ (0,1), (1,2), (2,3), (3,0),
358
+ (0,4), (1,4), (2,4), (3,4)
359
+ ]
360
+ points = []
361
+ projected = []
362
+ for v in vertices:
363
+ x2d, y2d = Render._project_3d(v[0], v[1], v[2], rotx, roty, rotz, scale, cx, cy)
364
+ projected.append((x2d, y2d))
365
+ for edge in edges:
366
+ x1, y1 = projected[edge[0]]
367
+ x2, y2 = projected[edge[1]]
368
+ points.extend(Render.get_line_points(x1, y1, x2, y2, char))
369
+ return Render._apply_color(points, color, bg)
370
+
371
+ @staticmethod
372
+ def get_cylinder_3d_points(radius=5, height=10, segments=12, rotx=0, roty=0, rotz=0, scale=10, cx=40, cy=12, char='#', color=None, bg=None):
373
+ points = []
374
+ top_points = []
375
+ bottom_points = []
376
+ for i in range(segments):
377
+ rad = i / segments * 2 * math.pi
378
+ x = radius * math.cos(rad)
379
+ z = radius * math.sin(rad)
380
+ top_points.append((x, height/2, z))
381
+ bottom_points.append((x, -height/2, z))
382
+ all_vertices = top_points + bottom_points
383
+ projected = []
384
+ for v in all_vertices:
385
+ x2d, y2d = Render._project_3d(v[0], v[1], v[2], rotx, roty, rotz, scale, cx, cy)
386
+ projected.append((x2d, y2d))
387
+ for i in range(segments):
388
+ j = (i + 1) % segments
389
+ x1, y1 = projected[i]
390
+ x2, y2 = projected[j]
391
+ points.extend(Render.get_line_points(x1, y1, x2, y2, char))
392
+ x1, y1 = projected[i + segments]
393
+ x2, y2 = projected[j + segments]
394
+ points.extend(Render.get_line_points(x1, y1, x2, y2, char))
395
+ x1, y1 = projected[i]
396
+ x2, y2 = projected[i + segments]
397
+ points.extend(Render.get_line_points(x1, y1, x2, y2, char))
398
+ return Render._apply_color(points, color, bg)
399
+
400
+ @staticmethod
401
+ def get_sphere_3d_points(radius=5, segments=12, rotx=0, roty=0, rotz=0, scale=10, cx=40, cy=12, char='#', color=None, bg=None):
402
+ points = []
403
+ for i in range(segments):
404
+ theta = i / segments * math.pi
405
+ for j in range(segments):
406
+ phi = j / segments * 2 * math.pi
407
+ x = radius * math.sin(theta) * math.cos(phi)
408
+ y = radius * math.cos(theta)
409
+ z = radius * math.sin(theta) * math.sin(phi)
410
+ x2d, y2d = Render._project_3d(x, y, z, rotx, roty, rotz, scale, cx, cy)
411
+ points.append((x2d, y2d, char))
412
+ return Render._apply_color(points, color, bg)
413
+
414
+ @staticmethod
415
+ def get_cone_3d_points(radius=5, height=10, segments=12, rotx=0, roty=0, rotz=0, scale=10, cx=40, cy=12, char='#', color=None, bg=None):
416
+ points = []
417
+ base_points = []
418
+ for i in range(segments):
419
+ rad = i / segments * 2 * math.pi
420
+ x = radius * math.cos(rad)
421
+ z = radius * math.sin(rad)
422
+ base_points.append((x, -height/2, z))
423
+ apex = (0, height/2, 0)
424
+ all_vertices = base_points + [apex]
425
+ projected = []
426
+ for v in all_vertices:
427
+ x2d, y2d = Render._project_3d(v[0], v[1], v[2], rotx, roty, rotz, scale, cx, cy)
428
+ projected.append((x2d, y2d))
429
+ for i in range(segments):
430
+ j = (i + 1) % segments
431
+ x1, y1 = projected[i]
432
+ x2, y2 = projected[j]
433
+ points.extend(Render.get_line_points(x1, y1, x2, y2, char))
434
+ x1, y1 = projected[i]
435
+ x2, y2 = projected[-1]
436
+ points.extend(Render.get_line_points(x1, y1, x2, y2, char))
437
+ return Render._apply_color(points, color, bg)
438
+
439
+ @staticmethod
440
+ def get_torus_3d_points(radius=8, tube=3, segments=16, rotx=0, roty=0, rotz=0, scale=10, cx=40, cy=12, char='#', color=None, bg=None):
441
+ points = []
442
+ for i in range(segments):
443
+ theta = i / segments * 2 * math.pi
444
+ for j in range(segments):
445
+ phi = j / segments * 2 * math.pi
446
+ x = (radius + tube * math.cos(phi)) * math.cos(theta)
447
+ y = tube * math.sin(phi)
448
+ z = (radius + tube * math.cos(phi)) * math.sin(theta)
449
+ x2d, y2d = Render._project_3d(x, y, z, rotx, roty, rotz, scale, cx, cy)
450
+ points.append((x2d, y2d, char))
451
+ return Render._apply_color(points, color, bg)
452
+
453
+ @staticmethod
454
+ def get_ico_sphere_3d_points(radius=5, rotx=0, roty=0, rotz=0, scale=10, cx=40, cy=12, char='#', color=None, bg=None):
455
+ points = []
456
+ phi = (1 + math.sqrt(5)) / 2
457
+ vertices = [
458
+ (-1, phi, 0), ( 1, phi, 0), (-1, -phi, 0), ( 1, -phi, 0),
459
+ ( 0, -1, phi), ( 0, 1, phi), ( 0, -1, -phi), ( 0, 1, -phi),
460
+ ( phi, 0, -1), ( phi, 0, 1), (-phi, 0, -1), (-phi, 0, 1)
461
+ ]
462
+ vertices = [(x * radius / 1.618, y * radius / 1.618, z * radius / 1.618) for x, y, z in vertices]
463
+ edges = [
464
+ (0,1), (0,4), (0,5), (0,10), (0,11),
465
+ (1,2), (1,5), (1,7), (1,8), (1,9),
466
+ (2,3), (2,6), (2,7), (2,10), (2,11),
467
+ (3,4), (3,6), (3,8), (3,9), (3,11),
468
+ (4,5), (4,9), (4,11),
469
+ (5,7), (5,9),
470
+ (6,7), (6,10),
471
+ (7,8),
472
+ (8,9), (8,10),
473
+ (10,11)
474
+ ]
475
+ projected = []
476
+ for v in vertices:
477
+ x2d, y2d = Render._project_3d(v[0], v[1], v[2], rotx, roty, rotz, scale, cx, cy)
478
+ projected.append((x2d, y2d))
479
+ for edge in edges:
480
+ x1, y1 = projected[edge[0]]
481
+ x2, y2 = projected[edge[1]]
482
+ points.extend(Render.get_line_points(x1, y1, x2, y2, char))
483
+ return Render._apply_color(points, color, bg)
484
+
485
+ class Animate:
486
+ @staticmethod
487
+ def clear_screen():
488
+ os.system("cls" if os.name == "nt" else "clear")
489
+
490
+ @staticmethod
491
+ def animate_print(text, delay=0.05, end="\n", flush=True, backspace_effect=False):
492
+ if backspace_effect:
493
+ for ch in text:
494
+ sys.stdout.write(ch)
495
+ sys.stdout.flush()
496
+ time.sleep(delay)
497
+ time.sleep(0.2)
498
+ for _ in text:
499
+ sys.stdout.write("\b \b")
500
+ sys.stdout.flush()
501
+ time.sleep(delay / 2)
502
+ for ch in text:
503
+ sys.stdout.write(ch)
504
+ sys.stdout.flush()
505
+ time.sleep(delay)
506
+ else:
507
+ for ch in text:
508
+ sys.stdout.write(ch)
509
+ if flush:
510
+ sys.stdout.flush()
511
+ time.sleep(delay)
512
+ sys.stdout.write(end)
513
+ if flush:
514
+ sys.stdout.flush()
515
+
516
+ @staticmethod
517
+ def spinning_cursor(message="Loading", duration=3.0, delay=0.1, frames=None, clear_before=False):
518
+ if clear_before:
519
+ Animate.clear_screen()
520
+ if frames is None:
521
+ frames = ["|", "/", "-", "\\"]
522
+ end_time = time.time() + duration
523
+ idx = 0
524
+ while time.time() < end_time:
525
+ frame = frames[idx % len(frames)]
526
+ sys.stdout.write(f"\r{message} {frame} ")
527
+ sys.stdout.flush()
528
+ time.sleep(delay)
529
+ idx += 1
530
+ sys.stdout.write("\r" + " " * (len(message) + 3) + "\r")
531
+ sys.stdout.flush()
532
+
533
+ @staticmethod
534
+ def countdown(seconds, message="Countdown", clear_before=False):
535
+ if clear_before:
536
+ Animate.clear_screen()
537
+ for remaining in range(seconds, 0, -1):
538
+ sys.stdout.write(f"\r{message}: {remaining:2d} seconds remaining ")
539
+ sys.stdout.flush()
540
+ time.sleep(1)
541
+ sys.stdout.write(f"\r{message}: 0 seconds remaining! Done!\n")
542
+ sys.stdout.flush()
543
+
544
+ class Keyboard:
545
+ @staticmethod
546
+ def GetKey():
547
+ try:
548
+ import termios
549
+ import tty
550
+ fd = sys.stdin.fileno()
551
+ old = termios.tcgetattr(fd)
552
+ try:
553
+ tty.setraw(fd)
554
+ return sys.stdin.read(1)
555
+ finally:
556
+ termios.tcsetattr(fd, termios.TCSADRAIN, old)
557
+ except:
558
+ import msvcrt
559
+ return msvcrt.getch().decode()
560
+
561
+ class ConsoleInfo:
562
+ @staticmethod
563
+ def GetConsole():
564
+ return sys.stdout
565
+
566
+ @staticmethod
567
+ def GetPipVer():
568
+ try:
569
+ result = CMD.run(['python', '-m', 'pip', '--version'], capture_output=True, text=True, check=True)
570
+ return result.stdout.strip()
571
+ except:
572
+ return "Error: pip not found"
573
+
574
+ class Process:
575
+ @staticmethod
576
+ def StartPyCode(code, wait=False, args=None, python="python"):
577
+ try:
578
+ cmd = [python, "-c", code]
579
+ if args:
580
+ cmd.extend(args)
581
+ if wait:
582
+ proc = CMD.run(cmd, capture_output=True, text=True)
583
+ return proc
584
+ else:
585
+ proc = CMD.Popen(cmd)
586
+ return proc
587
+ except Exception as e:
588
+ print(f"Error executing code: {e}")
589
+ return None
590
+
591
+ @staticmethod
592
+ def KillPyScript(pid):
593
+ try:
594
+ os.kill(pid, 15)
595
+ time.sleep(0.2)
596
+ return True
597
+ except ProcessLookupError:
598
+ print(f"Process {pid} not found")
599
+ return False
600
+ except PermissionError:
601
+ print(f"Permission denied to kill process {pid}")
602
+ return False
603
+ except Exception as e:
604
+ print(f"Error killing process: {e}")
605
+ return False
606
+
607
+ @staticmethod
608
+ def KillPyScriptForce(pid):
609
+ try:
610
+ os.kill(pid, 9)
611
+ return True
612
+ except ProcessLookupError:
613
+ print(f"Process {pid} not found")
614
+ return False
615
+ except PermissionError:
616
+ print(f"Permission denied to kill process {pid}")
617
+ return False
618
+ except Exception as e:
619
+ print(f"Error killing process: {e}")
620
+ return False
621
+
622
+ @staticmethod
623
+ def IsRunning(pid):
624
+ try:
625
+ os.kill(pid, 0)
626
+ return True
627
+ except ProcessLookupError:
628
+ return False
629
+ except PermissionError:
630
+ return True
631
+
632
+ @staticmethod
633
+ def GetProcessList():
634
+ try:
635
+ result = CMD.run(['ps', '-e', '-o', 'pid,comm'], capture_output=True, text=True)
636
+ lines = result.stdout.strip().split('\n')[1:]
637
+ processes = []
638
+ for line in lines:
639
+ parts = line.strip().split(' ', 1)
640
+ if len(parts) == 2:
641
+ pid = int(parts[0])
642
+ name = parts[1]
643
+ processes.append({'pid': pid, 'name': name})
644
+ return processes
645
+ except Exception:
646
+ return []
647
+
648
+ @staticmethod
649
+ def GetProcessInfo(pid):
650
+ try:
651
+ result = CMD.run(['ps', '-p', str(pid), '-o', 'pid,comm,%cpu,%mem,etime'], capture_output=True, text=True)
652
+ lines = result.stdout.strip().split('\n')
653
+ if len(lines) < 2:
654
+ return None
655
+ parts = lines[1].strip().split()
656
+ if len(parts) >= 5:
657
+ return {
658
+ 'pid': int(parts[0]),
659
+ 'name': parts[1],
660
+ 'cpu': parts[2],
661
+ 'memory': parts[3],
662
+ 'time': parts[4]
663
+ }
664
+ return None
665
+ except Exception:
666
+ return None
667
+
668
+ @staticmethod
669
+ def WaitForProcess(pid, timeout=None):
670
+ start_time = time.time()
671
+ while Process.IsRunning(pid):
672
+ if timeout and (time.time() - start_time) > timeout:
673
+ return False
674
+ time.sleep(0.5)
675
+ return True
676
+
677
+ @staticmethod
678
+ def GetCurrentPID():
679
+ return os.getpid()
680
+
681
+ class Channel:
682
+ def __init__(self):
683
+ self.connection = None
684
+ self.host = None
685
+ self.port = None
686
+ self.is_server = False
687
+
688
+ @staticmethod
689
+ def _get(url, timeout=5):
690
+ try:
691
+ import urllib.request
692
+ with urllib.request.urlopen(url, timeout=timeout) as response:
693
+ return response.read().decode()
694
+ except Exception:
695
+ return None
696
+
697
+ @staticmethod
698
+ def GetPublicIP():
699
+ ip = Channel._get('https://api.ipify.org')
700
+ return ip
701
+
702
+ def Connect(self, host='127.0.0.1', port=54321):
703
+ self.host = host
704
+ self.port = port
705
+ try:
706
+ self.connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
707
+ self.connection.connect((host, port))
708
+ return self.connection
709
+ except Exception as e:
710
+ print(f"[Error] Connection failed: {e}")
711
+ return None
712
+
713
+ def ConnectPublic(self, port=54321):
714
+ public_ip = Channel.GetPublicIP()
715
+ if not public_ip:
716
+ print("[Error] Could not get public IP")
717
+ return None
718
+ return self.Connect(host=public_ip, port=port)
719
+
720
+ def CreateServer(self, port=54321):
721
+ self.is_server = True
722
+ self.port = port
723
+ try:
724
+ server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
725
+ server.bind(('0.0.0.0', port))
726
+ server.listen(1)
727
+ self.connection, addr = server.accept()
728
+ return self.connection
729
+ except Exception as e:
730
+ print(f"[Error] Server failed: {e}")
731
+ return None
732
+
733
+ def Disconnect(self):
734
+ if self.connection:
735
+ self.connection.close()
736
+ self.connection = None
737
+
738
+ def Send(self, message):
739
+ if not self.connection:
740
+ return False
741
+ try:
742
+ if isinstance(message, str):
743
+ message = message.encode()
744
+ self.connection.send(message + b'\n')
745
+ return True
746
+ except Exception:
747
+ return False
748
+
749
+ def Receive(self):
750
+ if not self.connection:
751
+ return None
752
+ try:
753
+ data = self.connection.recv(1024).decode().strip()
754
+ return data
755
+ except Exception:
756
+ return None
757
+
758
+ class Web:
759
+ def UploadPaste(text, title="My Paste"):
760
+ def _get_api_key():
761
+ decoded = base64.b64decode("eJyzNLY0sTAxsTQtyymzNK+IDC/JztM1yA82N8zTDcv2TQ6NCnQ2igxPAwDwCwxD".encode("utf-8"))
762
+ decompressed = zlib.decompress(decoded).decode("utf-8")
763
+ if decompressed.startswith("93948449"):
764
+ return decompressed[len("93948449"):]
765
+ return None
766
+ api_key = _get_api_key()
767
+ data = {
768
+ 'api_dev_key': api_key,
769
+ 'api_option': 'paste',
770
+ 'api_paste_code': text,
771
+ 'api_paste_name': title,
772
+ 'api_paste_private': '0',
773
+ 'api_paste_expire_date': 'N',
774
+ }
775
+ encoded_data = urllib.parse.urlencode(data).encode('utf-8')
776
+ req = urllib.request.Request(
777
+ "https://pastebin.com/api/api_post.php",
778
+ data=encoded_data,
779
+ method="POST",
780
+ headers={
781
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
782
+ }
783
+ )
784
+ try:
785
+ with urllib.request.urlopen(req) as response:
786
+ result = response.read().decode('utf-8')
787
+ if result.startswith("https://pastebin.com/"):
788
+ paste_id = result.split("/")[-1]
789
+ return f"https://pastebin.com/raw/{paste_id}"
790
+ else:
791
+ return f"Pastebin error: {result}"
792
+ except urllib.error.HTTPError as e:
793
+ return f"HTTP Error {e.code}: {e.reason}"
794
+ except Exception as e:
795
+ return f"Error: {e}"
@@ -0,0 +1,24 @@
1
+ Metadata-Version: 2.4
2
+ Name: ConsoleFramework
3
+ Version: 1.0.0
4
+ Summary: The best Console Library of the Python.
5
+ Author: Suleiman
6
+ Author-email: steal.apet@mail.ru
7
+ License: MIT
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.6
12
+ Description-Content-Type: text/plain
13
+ License-File: LICENSE
14
+ Dynamic: author
15
+ Dynamic: author-email
16
+ Dynamic: classifier
17
+ Dynamic: description
18
+ Dynamic: description-content-type
19
+ Dynamic: license
20
+ Dynamic: license-file
21
+ Dynamic: requires-python
22
+ Dynamic: summary
23
+
24
+ ConsoleFramework - Pure Python library for console rendering, animations, processes and more. In this module ONLY standart python, no other modules.
@@ -0,0 +1,8 @@
1
+ LICENSE
2
+ setup.py
3
+ ConsoleFramework/__init__.py
4
+ ConsoleFramework.egg-info/PKG-INFO
5
+ ConsoleFramework.egg-info/SOURCES.txt
6
+ ConsoleFramework.egg-info/dependency_links.txt
7
+ ConsoleFramework.egg-info/not-zip-safe
8
+ ConsoleFramework.egg-info/top_level.txt
@@ -0,0 +1 @@
1
+ ConsoleFramework
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Suleiman
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,24 @@
1
+ Metadata-Version: 2.4
2
+ Name: ConsoleFramework
3
+ Version: 1.0.0
4
+ Summary: The best Console Library of the Python.
5
+ Author: Suleiman
6
+ Author-email: steal.apet@mail.ru
7
+ License: MIT
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.6
12
+ Description-Content-Type: text/plain
13
+ License-File: LICENSE
14
+ Dynamic: author
15
+ Dynamic: author-email
16
+ Dynamic: classifier
17
+ Dynamic: description
18
+ Dynamic: description-content-type
19
+ Dynamic: license
20
+ Dynamic: license-file
21
+ Dynamic: requires-python
22
+ Dynamic: summary
23
+
24
+ ConsoleFramework - Pure Python library for console rendering, animations, processes and more. In this module ONLY standart python, no other modules.
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,20 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ setup(
4
+ name="ConsoleFramework",
5
+ version="1.0.0",
6
+ description="The best Console Library of the Python.",
7
+ long_description="ConsoleFramework - Pure Python library for console rendering, animations, processes and more. In this module ONLY standart python, no other modules.",
8
+ long_description_content_type="text/plain",
9
+ author="Suleiman",
10
+ author_email="steal.apet@mail.ru",
11
+ license="MIT",
12
+ packages=find_packages(),
13
+ python_requires=">=3.6",
14
+ zip_safe=False,
15
+ classifiers=[
16
+ "Programming Language :: Python :: 3",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Operating System :: OS Independent",
19
+ ],
20
+ )