From 4f7a5b1a30ee91c1480866ee09b360bb7767c36e Mon Sep 17 00:00:00 2001 From: mas6y6 <125225333+mas6y6@users.noreply.github.com> Date: Fri, 6 Dec 2024 23:36:45 -0600 Subject: [PATCH] More fixes --- cipher/packagemanager.py | 208 ++++++++++------------------- plugins/et_encrypto/plugin.yml | 4 +- plugins/hacknet/cursor/__init__.py | 4 + plugins/hacknet/cursor/cursor.py | 50 +++++++ plugins/hacknet/plugin.yml | 3 +- 5 files changed, 131 insertions(+), 138 deletions(-) create mode 100644 plugins/hacknet/cursor/__init__.py create mode 100644 plugins/hacknet/cursor/cursor.py diff --git a/cipher/packagemanager.py b/cipher/packagemanager.py index bd75be5..2ab23e6 100644 --- a/cipher/packagemanager.py +++ b/cipher/packagemanager.py @@ -1,15 +1,19 @@ -import importlib, progressbar, requests, os, tarfile, shutil, zipfile +import importlib +import os +import progressbar +import requests +import shutil +import tarfile +import zipfile from wheel.wheelfile import WheelFile +import rich.console class PackageManager(): - def __init__(self,api): + def __init__(self, api): self.resolved_dependencies = set() self.api = api - + def _is_compatible_whl(self, filename): - """ - Check if a .whl file is compatible with the current system and Python version. - """ import sysconfig python_version = sysconfig.get_python_version() @@ -35,21 +39,22 @@ def _is_compatible_whl(self, filename): return python_compatible and platform_compatible - - def download_package(self, package_name, version=None): - """ - Downloads the specified package from PyPI, resolving dependencies recursively. - - :param package_name: Name of the PyPI package. - :param version: Optional version of the package to download. - """ base_url = "https://pypi.org/pypi" version_part = f"/{version}" if version else "" url = f"{base_url}/{package_name}{version_part}/json" download_dir = os.path.join(self.api.starterdir, "data", "cache", "packageswhl") packages_dir = os.path.join(self.api.starterdir, "data", "cache", "packages") + identifier = f"{package_name}=={version}" if version else package_name + + if identifier in self.resolved_dependencies: + if self.api.debug: + self.api.console.print(f"[DEBUG] Package already resolved: {identifier}", style="dim") + return + + self.resolved_dependencies.add(identifier) + try: response = requests.get(url) response.raise_for_status() @@ -57,13 +62,12 @@ def download_package(self, package_name, version=None): dependencies = data.get("info", {}).get("requires_dist", []) if dependencies: - self.api.console.print(f"Resolving dependencies for "+ package_name+ ": "+ f"{dependencies}",style="bold bright_yellow") + self.api.console.print(f"Resolving dependencies for {package_name}: {dependencies}", style="bold bright_yellow") for dep in dependencies: dep_name, dep_version = self._parse_dependency(dep) - if dep_name and not self.is_package_installed( - dep_name, dep_version - ): + if dep_name and not self.is_package_installed(dep_name, dep_version): self.download_package(dep_name, dep_version) + releases = data.get("releases", {}) if version: files = releases.get(version, []) @@ -89,142 +93,78 @@ def download_package(self, package_name, version=None): ) if self.api.debug: - self.api.console.print(f"Available files for {package_name}: {[file_info['filename'] for file_info in files]}") - - if self.api.debug: - self.api.console.print(f"Available files for {package_name} that works on this system: {compatible_files}") + self.api.console.print(f"[DEBUG] Compatible files for {package_name}: {compatible_files}") + if not compatible_files: - self.api.console.print("No compatible .whl files. Falling back to .tar.gz.") - tar_gz_files = [ - file_info["url"] - for file_info in files - if file_info["url"].endswith(".tar.gz") - ] - if tar_gz_files: - download_url = tar_gz_files[0] - else: - self.api.console.print("No valid files found.") - return - + self.api.console.print(f"[ERROR] No compatible files found for {package_name}", style="bold red") + return + download_url = compatible_files[0] filename = download_url.split("/")[-1] os.makedirs(download_dir, exist_ok=True) file_path = os.path.join(download_dir, filename) - print(f"Downloading {package_name} from {download_url}...") - with requests.get(download_url, stream=True) as r: - r.raise_for_status() - total_size = int(r.headers.get("Content-Length", 0)) - with open(file_path, "wb") as f: - bar = progressbar.ProgressBar( - maxval=total_size, - widgets=[ - "Downloading: ", - progressbar.Percentage(), - " [", - progressbar.Bar(), - " ]", - progressbar.ETA(), - ], - ) - bar.start() - downloaded = 0 - for chunk in r.iter_content(chunk_size=8192): - f.write(chunk) - downloaded += len(chunk) - bar.update(downloaded) - bar.finish() - - if filename.endswith(".zip"): - os.makedirs(packages_dir, exist_ok=True) - with zipfile.ZipFile(file_path, "r") as zip_ref: - zip_ref.extractall(packages_dir) - - elif filename.endswith(".whl"): - with WheelFile(file_path, "r") as whl_ref: - whl_ref.extractall(packages_dir) - - elif filename.endswith(".tar.gz"): - try: - temp_dir = os.path.join(download_dir, "temp_extract") - os.makedirs(temp_dir, exist_ok=True) - - with tarfile.open(file_path, "r:gz") as tar_ref: - tar_ref.extractall(temp_dir) - - setup_py = os.path.join(temp_dir, 'setup.py') - package_dir = None - - if os.path.exists(setup_py): - print(f"Found setup.py in {setup_py}. Attempting to find the main package...") - from setuptools import find_packages - found_packages = find_packages(where=temp_dir) - if found_packages: - package_dir = os.path.join(temp_dir, found_packages[0]) - - if not package_dir: - extracted_folders = [f for f in os.listdir(temp_dir) if os.path.isdir(os.path.join(temp_dir, f))] - if extracted_folders: - package_dir = os.path.join(temp_dir, extracted_folders[0]) - - if package_dir: - print(f"Found main package directory: {package_dir}") - for item in os.listdir(package_dir): - s = os.path.join(package_dir, item) - d = os.path.join(packages_dir, item) - if os.path.isdir(s): - shutil.copytree(s, d, dirs_exist_ok=True) - else: - shutil.copy2(s, d) - - print(f"Package {package_name} extracted and moved to {packages_dir}") - except (tarfile.TarError, IOError) as e: - RuntimeError(f"Error extracting {filename}: {e}") - finally: - if os.path.exists(temp_dir): - shutil.rmtree(temp_dir) + self._download_file(download_url, file_path) + self._extract_package(file_path, packages_dir, filename) - else: - raise TypeError("File format is invalid to the extractor") except requests.RequestException as e: - self.api.console.print(f"Failed to download package '{package_name}':\n {e}",style="bold bright_red") - + self.api.console.print(f"[ERROR] Failed to fetch package metadata for {package_name}: {e}", style="bold red") except Exception as e: - self.api.console.print(f"An error occurred while extracting/downloading '{package_name}':\n {e}",style="bold bright_red") + self.api.console.print(f"[ERROR] An unexpected error occurred: {e}", style="bold red") + + def _download_file(self, url, path): + with requests.get(url, stream=True) as r: + r.raise_for_status() + total_size = int(r.headers.get("Content-Length", 0)) + with open(path, "wb") as f: + bar = progressbar.ProgressBar( + maxval=total_size, + widgets=[ + "Downloading: ", + progressbar.Percentage(), + " [", + progressbar.Bar(), + " ]", + progressbar.ETA(), + ], + ) + bar.start() + downloaded = 0 + for chunk in r.iter_content(chunk_size=8192): + f.write(chunk) + downloaded += len(chunk) + bar.update(downloaded) + bar.finish() + + def _extract_package(self, file_path, target_dir, filename): + os.makedirs(target_dir, exist_ok=True) + if filename.endswith(".zip"): + with zipfile.ZipFile(file_path, "r") as zip_ref: + zip_ref.extractall(target_dir) + elif filename.endswith(".whl"): + with WheelFile(file_path, "r") as whl_ref: + whl_ref.extractall(target_dir) + elif filename.endswith(".tar.gz"): + with tarfile.open(file_path, "r:gz") as tar_ref: + tar_ref.extractall(target_dir) + else: + raise TypeError("Unsupported file format") def _parse_dependency(self, dependency_string): - """ - Parse a dependency string from requires_dist into name and version. - - :param dependency_string: A dependency string from requires_dist. - :return: A tuple of (name, version) or (name, None). - """ import re - - match = re.match(r"([a-zA-Z0-9_\-\.]+)(?:\[.*\])?(?:\s*\(([^)]+)\))?", dependency_string) + match = re.match(r"([a-zA-Z0-9_\-.]+)(?:\[.*\])?(?:\s+\((.+)\))?", dependency_string) if match: dep_name = match.group(1).strip() dep_version = match.group(2) - return dep_name, dep_version.strip() if dep_version else None - + return dep_name, dep_version return dependency_string, None def is_package_installed(self, package_name, version=None): - """ - Checks if a package is already downloaded and installed. - - :param package_name: Name of the package. - :param version: Optional version of the package. - :return: True if installed, False otherwise. - """ try: importlib.import_module(package_name) return True except ImportError: - installed_dir = os.path.join(self.starterdir, "data", "cache", "packages") - if version: - package_path = os.path.join(installed_dir, f"{package_name}-{version}") - else: - package_path = os.path.join(installed_dir, package_name) - return os.path.exists(package_path) \ No newline at end of file + installed_dir = os.path.join(self.api.starterdir, "data", "cache", "packages") + package_path = os.path.join(installed_dir, package_name) + return os.path.exists(package_path) diff --git a/plugins/et_encrypto/plugin.yml b/plugins/et_encrypto/plugin.yml index 38e90da..a65439b 100644 --- a/plugins/et_encrypto/plugin.yml +++ b/plugins/et_encrypto/plugin.yml @@ -8,5 +8,5 @@ displayname: "Entech Encrypto" description: A encrypting software like 7zip class: EntechEncrypto dependencies: - - cryptography - - bcrypt \ No newline at end of file +# - cryptography +# - bcrypt \ No newline at end of file diff --git a/plugins/hacknet/cursor/__init__.py b/plugins/hacknet/cursor/__init__.py new file mode 100644 index 0000000..76a4f67 --- /dev/null +++ b/plugins/hacknet/cursor/__init__.py @@ -0,0 +1,4 @@ +from .cursor import hide, show, HiddenCursor + +__all__ = ["hide", "show", "HiddenCursor"] + diff --git a/plugins/hacknet/cursor/cursor.py b/plugins/hacknet/cursor/cursor.py new file mode 100644 index 0000000..d73e867 --- /dev/null +++ b/plugins/hacknet/cursor/cursor.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- + +## Author: James Spencer: http://stackoverflow.com/users/1375885/james-spencer +## Packager: Gijs Timmers: https://github.com/GijsTimmers + +## Based on James Spencer's answer on StackOverflow: +## http://stackoverflow.com/q/5174810 + +## Licence: GPL v3 +## https://www.gnu.org/licenses/gpl-3.0.html + +import sys +import os + +if os.name == 'nt': + import ctypes + + class _CursorInfo(ctypes.Structure): + _fields_ = [("size", ctypes.c_int), + ("visible", ctypes.c_byte)] + +def hide(stream=sys.stdout): + if os.name == 'nt': + ci = _CursorInfo() + handle = ctypes.windll.kernel32.GetStdHandle(-11) + ctypes.windll.kernel32.GetConsoleCursorInfo(handle, ctypes.byref(ci)) + ci.visible = False + ctypes.windll.kernel32.SetConsoleCursorInfo(handle, ctypes.byref(ci)) + elif os.name == 'posix': + stream.write("\033[?25l") + stream.flush() + +def show(stream=sys.stdout): + if os.name == 'nt': + ci = _CursorInfo() + handle = ctypes.windll.kernel32.GetStdHandle(-11) + ctypes.windll.kernel32.GetConsoleCursorInfo(handle, ctypes.byref(ci)) + ci.visible = True + ctypes.windll.kernel32.SetConsoleCursorInfo(handle, ctypes.byref(ci)) + elif os.name == 'posix': + stream.write("\033[?25h") + stream.flush() + +class HiddenCursor(object): + def __init__(self, stream=sys.stdout): + self._stream = stream + def __enter__(self): + hide(stream=self._stream) + def __exit__(self, type, value, traceback): + show(stream=self._stream) diff --git a/plugins/hacknet/plugin.yml b/plugins/hacknet/plugin.yml index 18986dc..25bea5c 100644 --- a/plugins/hacknet/plugin.yml +++ b/plugins/hacknet/plugin.yml @@ -8,5 +8,4 @@ authors: displayname: "Hacknet Addons" class: HacknetPlugin dependencies: - - pygame - - cursor \ No newline at end of file + - pygame \ No newline at end of file