irl-pkg 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.
- irl_pkg-1.0.0/PKG-INFO +24 -0
- irl_pkg-1.0.0/README.md +14 -0
- irl_pkg-1.0.0/irl/__init__.py +1 -0
- irl_pkg-1.0.0/irl/extract.py +36 -0
- irl_pkg-1.0.0/irl/glasses.py +107 -0
- irl_pkg-1.0.0/irl/install.py +35 -0
- irl_pkg-1.0.0/irl/main.py +36 -0
- irl_pkg-1.0.0/irl/wrappers.py +37 -0
- irl_pkg-1.0.0/irl_pkg.egg-info/PKG-INFO +24 -0
- irl_pkg-1.0.0/irl_pkg.egg-info/SOURCES.txt +14 -0
- irl_pkg-1.0.0/irl_pkg.egg-info/dependency_links.txt +1 -0
- irl_pkg-1.0.0/irl_pkg.egg-info/entry_points.txt +2 -0
- irl_pkg-1.0.0/irl_pkg.egg-info/requires.txt +2 -0
- irl_pkg-1.0.0/irl_pkg.egg-info/top_level.txt +1 -0
- irl_pkg-1.0.0/pyproject.toml +20 -0
- irl_pkg-1.0.0/setup.cfg +4 -0
irl_pkg-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: irl-pkg
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: In Real Life - The package installer that touches grass.
|
|
5
|
+
Author: TransPower Team
|
|
6
|
+
Requires-Python: >=3.7
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
Requires-Dist: requests
|
|
9
|
+
Requires-Dist: rich
|
|
10
|
+
|
|
11
|
+
# irl-pkg
|
|
12
|
+
|
|
13
|
+
The universal package installer. Install NPM, PyPI, and GitHub packages natively with the cool "Touching grass..." progress bar.
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# Installs any Python package using pip
|
|
17
|
+
irl install requests
|
|
18
|
+
|
|
19
|
+
# Installs any Node.js package using npm
|
|
20
|
+
irl install chalk
|
|
21
|
+
|
|
22
|
+
# Installs anything from GitHub
|
|
23
|
+
irl install octocat/Hello-World
|
|
24
|
+
```
|
irl_pkg-1.0.0/README.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# irl-pkg
|
|
2
|
+
|
|
3
|
+
The universal package installer. Install NPM, PyPI, and GitHub packages natively with the cool "Touching grass..." progress bar.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
# Installs any Python package using pip
|
|
7
|
+
irl install requests
|
|
8
|
+
|
|
9
|
+
# Installs any Node.js package using npm
|
|
10
|
+
irl install chalk
|
|
11
|
+
|
|
12
|
+
# Installs anything from GitHub
|
|
13
|
+
irl install octocat/Hello-World
|
|
14
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# IRL Package Init
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import requests
|
|
3
|
+
import zipfile
|
|
4
|
+
from rich.progress import Progress, DownloadColumn, TransferSpeedColumn, TextColumn
|
|
5
|
+
|
|
6
|
+
def download_and_extract(url):
|
|
7
|
+
print(f"\nDownloading from {url}...")
|
|
8
|
+
try:
|
|
9
|
+
response = requests.get(url, stream=True)
|
|
10
|
+
response.raise_for_status()
|
|
11
|
+
|
|
12
|
+
total_size = int(response.headers.get('content-length', 0))
|
|
13
|
+
zip_path = "temp_download.zip"
|
|
14
|
+
|
|
15
|
+
with Progress(
|
|
16
|
+
TextColumn("[bold blue]🌱 Touching grass..."),
|
|
17
|
+
"[progress.percentage]{task.percentage:>3.0f}%",
|
|
18
|
+
DownloadColumn(),
|
|
19
|
+
TransferSpeedColumn()
|
|
20
|
+
) as progress:
|
|
21
|
+
task = progress.add_task("Downloading", total=total_size)
|
|
22
|
+
|
|
23
|
+
with open(zip_path, "wb") as file:
|
|
24
|
+
for chunk in response.iter_content(chunk_size=8192):
|
|
25
|
+
file.write(chunk)
|
|
26
|
+
progress.update(task, advance=len(chunk))
|
|
27
|
+
|
|
28
|
+
print("Extracting files...")
|
|
29
|
+
with zipfile.ZipFile(zip_path, 'r') as zip_ref:
|
|
30
|
+
zip_ref.extractall(".")
|
|
31
|
+
|
|
32
|
+
os.remove(zip_path)
|
|
33
|
+
print("✨ Successfully touched grass and installed the package!")
|
|
34
|
+
|
|
35
|
+
except Exception as e:
|
|
36
|
+
print(f"❌ Error during download/extraction: {e}")
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
import json
|
|
3
|
+
from rich.console import Console
|
|
4
|
+
import time
|
|
5
|
+
|
|
6
|
+
console = Console()
|
|
7
|
+
|
|
8
|
+
def format_size(size_in_bytes):
|
|
9
|
+
if not size_in_bytes:
|
|
10
|
+
return "Unknown"
|
|
11
|
+
for unit in ['B', 'KB', 'MB', 'GB']:
|
|
12
|
+
if size_in_bytes < 1024.0:
|
|
13
|
+
return f"{size_in_bytes:.1f} {unit}"
|
|
14
|
+
size_in_bytes /= 1024.0
|
|
15
|
+
return f"{size_in_bytes:.1f} TB"
|
|
16
|
+
|
|
17
|
+
def get_npm_info(package):
|
|
18
|
+
url = f"https://registry.npmjs.org/{package}"
|
|
19
|
+
try:
|
|
20
|
+
response = requests.get(url, timeout=5)
|
|
21
|
+
if response.status_code == 200:
|
|
22
|
+
data = response.json()
|
|
23
|
+
latest_version = data.get("dist-tags", {}).get("latest")
|
|
24
|
+
if latest_version and latest_version in data.get("versions", {}):
|
|
25
|
+
version_data = data["versions"][latest_version]
|
|
26
|
+
size = version_data.get("dist", {}).get("unpackedSize")
|
|
27
|
+
return {
|
|
28
|
+
"package": package,
|
|
29
|
+
"version": latest_version,
|
|
30
|
+
"size": format_size(size) if size else "Unknown (Tarball)",
|
|
31
|
+
"source": "NPM",
|
|
32
|
+
"install_method": "npm"
|
|
33
|
+
}
|
|
34
|
+
except:
|
|
35
|
+
pass
|
|
36
|
+
return None
|
|
37
|
+
|
|
38
|
+
def get_pypi_info(package):
|
|
39
|
+
url = f"https://pypi.org/pypi/{package}/json"
|
|
40
|
+
try:
|
|
41
|
+
response = requests.get(url, timeout=5)
|
|
42
|
+
if response.status_code == 200:
|
|
43
|
+
data = response.json()
|
|
44
|
+
version = data.get("info", {}).get("version", "Unknown")
|
|
45
|
+
urls = data.get("urls", [])
|
|
46
|
+
size = None
|
|
47
|
+
if urls:
|
|
48
|
+
for u in urls:
|
|
49
|
+
if u.get("packagetype") == "bdist_wheel":
|
|
50
|
+
size = u.get("size")
|
|
51
|
+
break
|
|
52
|
+
if not size and urls:
|
|
53
|
+
size = urls[0].get("size")
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
"package": package,
|
|
57
|
+
"version": version,
|
|
58
|
+
"size": format_size(size) if size else "Unknown",
|
|
59
|
+
"source": "PyPI",
|
|
60
|
+
"install_method": "pip"
|
|
61
|
+
}
|
|
62
|
+
except:
|
|
63
|
+
pass
|
|
64
|
+
return None
|
|
65
|
+
|
|
66
|
+
def get_github_info(package):
|
|
67
|
+
if "/" not in package or package.startswith("@"):
|
|
68
|
+
return None
|
|
69
|
+
|
|
70
|
+
url = f"https://api.github.com/repos/{package}"
|
|
71
|
+
try:
|
|
72
|
+
response = requests.get(url, timeout=5)
|
|
73
|
+
if response.status_code == 200:
|
|
74
|
+
data = response.json()
|
|
75
|
+
size_kb = data.get("size", 0)
|
|
76
|
+
return {
|
|
77
|
+
"package": data.get("name", package),
|
|
78
|
+
"version": data.get("default_branch", "main"),
|
|
79
|
+
"size": format_size(size_kb * 1024) if size_kb else "Unknown",
|
|
80
|
+
"source": "GitHub",
|
|
81
|
+
"install_method": "Available"
|
|
82
|
+
}
|
|
83
|
+
except:
|
|
84
|
+
pass
|
|
85
|
+
return None
|
|
86
|
+
|
|
87
|
+
def inspect_package(package):
|
|
88
|
+
console.print("\n[bold cyan]👓 Looking closely...[/bold cyan]\n")
|
|
89
|
+
|
|
90
|
+
time.sleep(1)
|
|
91
|
+
|
|
92
|
+
info = get_npm_info(package)
|
|
93
|
+
if not info:
|
|
94
|
+
info = get_pypi_info(package)
|
|
95
|
+
if not info:
|
|
96
|
+
info = get_github_info(package)
|
|
97
|
+
|
|
98
|
+
if info:
|
|
99
|
+
console.print(f"[bold]Package:[/bold] {info['package']}")
|
|
100
|
+
console.print(f"[bold]Version:[/bold] {info['version']}")
|
|
101
|
+
console.print(f"[bold]Size:[/bold] {info['size']}")
|
|
102
|
+
console.print(f"[bold]Source:[/bold] {info['source']}")
|
|
103
|
+
console.print(f"[bold]Install Method:[/bold] {info['install_method']}\n")
|
|
104
|
+
console.print("[green]Vision enhanced.[/green]\n")
|
|
105
|
+
else:
|
|
106
|
+
console.print(f"[red]❌ Error:[/red] Package '{package}' not found on NPM, PyPI, or GitHub.")
|
|
107
|
+
console.print("[yellow]Vision impaired.[/yellow]\n")
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
from irl.wrappers import install_npm, install_pip
|
|
3
|
+
from irl.extract import download_and_extract
|
|
4
|
+
|
|
5
|
+
def check_registry(url):
|
|
6
|
+
try:
|
|
7
|
+
response = requests.get(url, timeout=5)
|
|
8
|
+
return response.status_code == 200
|
|
9
|
+
except requests.RequestException:
|
|
10
|
+
return False
|
|
11
|
+
|
|
12
|
+
def install_package(target):
|
|
13
|
+
# Direct URL
|
|
14
|
+
if target.startswith("http://") or target.startswith("https://"):
|
|
15
|
+
download_and_extract(target)
|
|
16
|
+
return
|
|
17
|
+
|
|
18
|
+
# GitHub format user/repo
|
|
19
|
+
if "/" in target and not target.startswith("@"):
|
|
20
|
+
url = f"https://github.com/{target}/archive/refs/heads/main.zip"
|
|
21
|
+
download_and_extract(url)
|
|
22
|
+
return
|
|
23
|
+
|
|
24
|
+
# Check NPM
|
|
25
|
+
print(f"🔍 Searching for '{target}'...")
|
|
26
|
+
if check_registry(f"https://registry.npmjs.org/{target}"):
|
|
27
|
+
install_npm(target)
|
|
28
|
+
return
|
|
29
|
+
|
|
30
|
+
# Check PyPI
|
|
31
|
+
if check_registry(f"https://pypi.org/pypi/{target}/json"):
|
|
32
|
+
install_pip(target)
|
|
33
|
+
return
|
|
34
|
+
|
|
35
|
+
print(f"✖ Error: Package '{target}' not found on NPM, PyPI, or GitHub.")
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import sys
|
|
3
|
+
from irl.install import install_package
|
|
4
|
+
from irl.glasses import inspect_package
|
|
5
|
+
|
|
6
|
+
def cli():
|
|
7
|
+
parser = argparse.ArgumentParser(
|
|
8
|
+
prog="irl",
|
|
9
|
+
description="IRL (In Real Life) - The universal package installer that touches grass."
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
subparsers = parser.add_subparsers(dest="command", help="Available commands")
|
|
13
|
+
|
|
14
|
+
install_parser = subparsers.add_parser("install", help="Install a package")
|
|
15
|
+
install_parser.add_argument("package", help="Name of the package, GitHub repo, or direct URL")
|
|
16
|
+
|
|
17
|
+
glasses_parser = subparsers.add_parser("glasses", help="Inspect a package like a detective")
|
|
18
|
+
glasses_parser.add_argument("package", help="Name of the package to inspect")
|
|
19
|
+
|
|
20
|
+
args = parser.parse_args()
|
|
21
|
+
|
|
22
|
+
if args.command == "install":
|
|
23
|
+
if not args.package:
|
|
24
|
+
print("Error: Please provide a package name to install.")
|
|
25
|
+
sys.exit(1)
|
|
26
|
+
install_package(args.package)
|
|
27
|
+
elif args.command == "glasses":
|
|
28
|
+
if not args.package:
|
|
29
|
+
print("Error: Please provide a package name to inspect.")
|
|
30
|
+
sys.exit(1)
|
|
31
|
+
inspect_package(args.package)
|
|
32
|
+
else:
|
|
33
|
+
parser.print_help()
|
|
34
|
+
|
|
35
|
+
if __name__ == "__main__":
|
|
36
|
+
cli()
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
import sys
|
|
3
|
+
from rich.progress import Progress, SpinnerColumn, TextColumn, BarColumn
|
|
4
|
+
|
|
5
|
+
def run_with_progress(command_str, package, manager_name):
|
|
6
|
+
print(f"\nPreparing to install {package} using {manager_name}...")
|
|
7
|
+
|
|
8
|
+
with Progress(
|
|
9
|
+
SpinnerColumn(),
|
|
10
|
+
TextColumn("[progress.description]{task.description}"),
|
|
11
|
+
transient=True,
|
|
12
|
+
) as progress:
|
|
13
|
+
task = progress.add_task(f"[green]🌱 Touching grass... Installing {package}...", start=False)
|
|
14
|
+
|
|
15
|
+
process = subprocess.Popen(
|
|
16
|
+
command_str,
|
|
17
|
+
stdout=subprocess.PIPE,
|
|
18
|
+
stderr=subprocess.PIPE,
|
|
19
|
+
shell=True
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
stdout, stderr = process.communicate()
|
|
23
|
+
|
|
24
|
+
if process.returncode == 0:
|
|
25
|
+
print(f"✨ Successfully touched grass and installed the package!")
|
|
26
|
+
return True
|
|
27
|
+
else:
|
|
28
|
+
print(f"❌ Failed to install {package}.")
|
|
29
|
+
if stderr:
|
|
30
|
+
print(stderr.decode("utf-8", errors="ignore"))
|
|
31
|
+
return False
|
|
32
|
+
|
|
33
|
+
def install_npm(package):
|
|
34
|
+
return run_with_progress(f"npm install {package}", package, "npm")
|
|
35
|
+
|
|
36
|
+
def install_pip(package):
|
|
37
|
+
return run_with_progress(f"pip install {package}", package, "pip")
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: irl-pkg
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: In Real Life - The package installer that touches grass.
|
|
5
|
+
Author: TransPower Team
|
|
6
|
+
Requires-Python: >=3.7
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
Requires-Dist: requests
|
|
9
|
+
Requires-Dist: rich
|
|
10
|
+
|
|
11
|
+
# irl-pkg
|
|
12
|
+
|
|
13
|
+
The universal package installer. Install NPM, PyPI, and GitHub packages natively with the cool "Touching grass..." progress bar.
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# Installs any Python package using pip
|
|
17
|
+
irl install requests
|
|
18
|
+
|
|
19
|
+
# Installs any Node.js package using npm
|
|
20
|
+
irl install chalk
|
|
21
|
+
|
|
22
|
+
# Installs anything from GitHub
|
|
23
|
+
irl install octocat/Hello-World
|
|
24
|
+
```
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
irl/__init__.py
|
|
4
|
+
irl/extract.py
|
|
5
|
+
irl/glasses.py
|
|
6
|
+
irl/install.py
|
|
7
|
+
irl/main.py
|
|
8
|
+
irl/wrappers.py
|
|
9
|
+
irl_pkg.egg-info/PKG-INFO
|
|
10
|
+
irl_pkg.egg-info/SOURCES.txt
|
|
11
|
+
irl_pkg.egg-info/dependency_links.txt
|
|
12
|
+
irl_pkg.egg-info/entry_points.txt
|
|
13
|
+
irl_pkg.egg-info/requires.txt
|
|
14
|
+
irl_pkg.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
irl
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "irl-pkg"
|
|
7
|
+
version = "1.0.0"
|
|
8
|
+
description = "In Real Life - The package installer that touches grass."
|
|
9
|
+
authors = [
|
|
10
|
+
{ name = "TransPower Team" }
|
|
11
|
+
]
|
|
12
|
+
dependencies = [
|
|
13
|
+
"requests",
|
|
14
|
+
"rich"
|
|
15
|
+
]
|
|
16
|
+
readme = "README.md"
|
|
17
|
+
requires-python = ">=3.7"
|
|
18
|
+
|
|
19
|
+
[project.scripts]
|
|
20
|
+
irl = "irl.main:cli"
|
irl_pkg-1.0.0/setup.cfg
ADDED