prs-progress-bar 0.1.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.
- prs_progress_bar-0.1.0/PKG-INFO +7 -0
- prs_progress_bar-0.1.0/README.md +0 -0
- prs_progress_bar-0.1.0/prs_progress_bar/__init__.py +0 -0
- prs_progress_bar-0.1.0/prs_progress_bar/cli.py +140 -0
- prs_progress_bar-0.1.0/prs_progress_bar.egg-info/PKG-INFO +7 -0
- prs_progress_bar-0.1.0/prs_progress_bar.egg-info/SOURCES.txt +9 -0
- prs_progress_bar-0.1.0/prs_progress_bar.egg-info/dependency_links.txt +1 -0
- prs_progress_bar-0.1.0/prs_progress_bar.egg-info/entry_points.txt +5 -0
- prs_progress_bar-0.1.0/prs_progress_bar.egg-info/top_level.txt +1 -0
- prs_progress_bar-0.1.0/pyproject.toml +21 -0
- prs_progress_bar-0.1.0/setup.cfg +4 -0
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import os
|
|
3
|
+
import time
|
|
4
|
+
import shutil
|
|
5
|
+
import subprocess
|
|
6
|
+
import threading
|
|
7
|
+
import itertools
|
|
8
|
+
|
|
9
|
+
# --- CREDITS FOOTER (BRIGHT BLUE) ---
|
|
10
|
+
CREDITS = "\033[94m\nPRS-Progress-Bar built by 'Shrimurali'\033[0m\n"
|
|
11
|
+
|
|
12
|
+
# --- ANIMATION ENGINE ---
|
|
13
|
+
|
|
14
|
+
SPINNERS = {
|
|
15
|
+
"dots": ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"],
|
|
16
|
+
"circles": ["◐", "◓", "◑", "◒"],
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
def render_bar(current, total, length=20):
|
|
20
|
+
percent = float(current) / total if total > 0 else 1.0
|
|
21
|
+
filled = int(round(length * percent))
|
|
22
|
+
bar = "█" * filled + "░" * (length - filled)
|
|
23
|
+
pct_str = f"{int(percent * 100)}%"
|
|
24
|
+
return bar, pct_str
|
|
25
|
+
|
|
26
|
+
class SpinnerThread:
|
|
27
|
+
def __init__(self, title, subtitle="", style="circles"):
|
|
28
|
+
self.title = title
|
|
29
|
+
self.subtitle = subtitle
|
|
30
|
+
self.frames = SPINNERS.get(style, SPINNERS["dots"])
|
|
31
|
+
self.running = False
|
|
32
|
+
self.thread = None
|
|
33
|
+
|
|
34
|
+
def _animate(self):
|
|
35
|
+
for frame in itertools.cycle(self.frames):
|
|
36
|
+
if not self.running:
|
|
37
|
+
break
|
|
38
|
+
sys.stdout.write(f"\r\033[K{self.title}\n{frame} {self.subtitle}\033[F")
|
|
39
|
+
sys.stdout.flush()
|
|
40
|
+
time.sleep(0.08)
|
|
41
|
+
sys.stdout.write("\r\033[K\n\033[K\033[F")
|
|
42
|
+
|
|
43
|
+
def start(self):
|
|
44
|
+
self.running = True
|
|
45
|
+
self.thread = threading.Thread(target=self._animate)
|
|
46
|
+
self.thread.start()
|
|
47
|
+
|
|
48
|
+
def stop(self, success_msg=""):
|
|
49
|
+
self.running = False
|
|
50
|
+
if self.thread:
|
|
51
|
+
self.thread.join()
|
|
52
|
+
if success_msg:
|
|
53
|
+
print(f"\r\033[K✓ {success_msg}")
|
|
54
|
+
|
|
55
|
+
# --- STANDALONE COMMAND ENTRY POINTS ---
|
|
56
|
+
|
|
57
|
+
def remove_cmd():
|
|
58
|
+
"""Triggered by direct command: remove <target>"""
|
|
59
|
+
args = sys.argv[1:]
|
|
60
|
+
target = args[0] if args else "folder"
|
|
61
|
+
print(f"🗑 Removing {target}\n")
|
|
62
|
+
|
|
63
|
+
if os.path.isdir(target):
|
|
64
|
+
files = [os.path.join(r, f) for r, _, fn in os.walk(target) for f in fn]
|
|
65
|
+
total = len(files) or 1
|
|
66
|
+
for idx, file_path in enumerate(files, 1):
|
|
67
|
+
try:
|
|
68
|
+
os.remove(file_path)
|
|
69
|
+
except Exception:
|
|
70
|
+
pass
|
|
71
|
+
bar, pct = render_bar(idx, total)
|
|
72
|
+
sys.stdout.write(f"\r{bar} {pct} {idx} / {total} files removed")
|
|
73
|
+
sys.stdout.flush()
|
|
74
|
+
time.sleep(0.001)
|
|
75
|
+
shutil.rmtree(target, ignore_errors=True)
|
|
76
|
+
else:
|
|
77
|
+
bar, pct = render_bar(100, 100)
|
|
78
|
+
sys.stdout.write(f"\r{bar} {pct} Process completed!")
|
|
79
|
+
|
|
80
|
+
print("\n\n✓ Success")
|
|
81
|
+
print(CREDITS)
|
|
82
|
+
|
|
83
|
+
def download_cmd():
|
|
84
|
+
"""Triggered by direct command: download <file>"""
|
|
85
|
+
args = sys.argv[1:]
|
|
86
|
+
filename = args[0] if args else "model.gguf"
|
|
87
|
+
print(f"🧠 Downloading {filename}\n")
|
|
88
|
+
|
|
89
|
+
spinner = SpinnerThread("Connecting to host...", "Fetching headers...", style="circles")
|
|
90
|
+
spinner.start()
|
|
91
|
+
time.sleep(1.2)
|
|
92
|
+
spinner.stop()
|
|
93
|
+
|
|
94
|
+
total_mb = 5000
|
|
95
|
+
for downloaded in range(0, total_mb + 1, 200):
|
|
96
|
+
bar, pct = render_bar(downloaded, total_mb)
|
|
97
|
+
sys.stdout.write(f"\r{bar} {pct} {downloaded / 1000:.1f}GB / {total_mb / 1000:.1f}GB ⚡ 45 MB/s ⏱ ETA 00:30")
|
|
98
|
+
sys.stdout.flush()
|
|
99
|
+
time.sleep(0.05)
|
|
100
|
+
|
|
101
|
+
print("\n\n✓ Download complete")
|
|
102
|
+
print(CREDITS)
|
|
103
|
+
|
|
104
|
+
def pip_cmd():
|
|
105
|
+
"""Triggered by direct command: pip install <package>"""
|
|
106
|
+
args = sys.argv[1:]
|
|
107
|
+
if len(args) >= 2 and args[0] == "install":
|
|
108
|
+
pkg = args[1]
|
|
109
|
+
print(f"📦 Installing packages ({pkg})\n")
|
|
110
|
+
|
|
111
|
+
spinner = SpinnerThread(f"⠋ Resolving dependencies...", "Fetching metadata...", style="dots")
|
|
112
|
+
spinner.start()
|
|
113
|
+
|
|
114
|
+
# Run real pip install in background
|
|
115
|
+
cmd = [sys.executable, "-m", "pip"] + args
|
|
116
|
+
proc = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
117
|
+
spinner.stop()
|
|
118
|
+
|
|
119
|
+
for idx in range(1, 101, 10):
|
|
120
|
+
bar, pct = render_bar(idx, 100)
|
|
121
|
+
sys.stdout.write(f"\r{bar} {pct} {idx * 1.5:.0f} / 150 packages")
|
|
122
|
+
sys.stdout.flush()
|
|
123
|
+
time.sleep(0.03)
|
|
124
|
+
|
|
125
|
+
print("\n\n✓ Success")
|
|
126
|
+
print(CREDITS)
|
|
127
|
+
else:
|
|
128
|
+
subprocess.run([sys.executable, "-m", "pip"] + args)
|
|
129
|
+
|
|
130
|
+
def ask_cmd():
|
|
131
|
+
"""Triggered by direct command: ask <prompt>"""
|
|
132
|
+
prompt = " ".join(sys.argv[1:]) if len(sys.argv) > 1 else "create website"
|
|
133
|
+
print(f"🤖 PRS AI Thinking\n")
|
|
134
|
+
|
|
135
|
+
spinner = SpinnerThread("🧠 Analyzing request", "Generating response...", style="circles")
|
|
136
|
+
spinner.start()
|
|
137
|
+
time.sleep(2.0)
|
|
138
|
+
spinner.stop("Response ready:")
|
|
139
|
+
print(f"\n> Executing task: {prompt}")
|
|
140
|
+
print(CREDITS)
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
prs_progress_bar/__init__.py
|
|
4
|
+
prs_progress_bar/cli.py
|
|
5
|
+
prs_progress_bar.egg-info/PKG-INFO
|
|
6
|
+
prs_progress_bar.egg-info/SOURCES.txt
|
|
7
|
+
prs_progress_bar.egg-info/dependency_links.txt
|
|
8
|
+
prs_progress_bar.egg-info/entry_points.txt
|
|
9
|
+
prs_progress_bar.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
prs_progress_bar
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "prs-progress-bar"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
authors = [
|
|
9
|
+
{ name="Shrimurali", email="prsshrimurali@gmail.com" }
|
|
10
|
+
]
|
|
11
|
+
description = "Animated progress bars and icons for terminal commands."
|
|
12
|
+
readme = "README.md"
|
|
13
|
+
requires-python = ">=3.7"
|
|
14
|
+
dependencies = []
|
|
15
|
+
|
|
16
|
+
# MAP DIRECT BARE TERMINAL COMMANDS HERE:
|
|
17
|
+
[project.scripts]
|
|
18
|
+
remove = "prs_progress_bar.cli:remove_cmd"
|
|
19
|
+
download = "prs_progress_bar.cli:download_cmd"
|
|
20
|
+
pip = "prs_progress_bar.cli:pip_cmd"
|
|
21
|
+
ask = "prs_progress_bar.cli:ask_cmd"
|