| Server IP : 54.37.205.81 / Your IP : 216.73.216.76 Web Server : nginx/1.22.1 System : Linux vps-249481fa 6.1.0-50-cloud-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.176-1 (2026-07-02) x86_64 User : debian ( 1000) PHP Version : 8.2.32 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /lib/python3/dist-packages/userpath/ |
Upload File : |
import os
import platform
from datetime import datetime
from io import open
from .shells import DEFAULT_SHELLS, SHELLS
from .utils import ensure_parent_dir_exists, get_flat_output, get_parent_process_name, location_in_path, normpath
try:
import winreg
except ImportError:
try:
import _winreg as winreg
except ImportError:
winreg = None
class WindowsInterface:
def __init__(self, **kwargs):
pass
@staticmethod
def _get_new_path():
with winreg.OpenKey(winreg.HKEY_CURRENT_USER, 'Environment', 0, winreg.KEY_READ) as key:
return winreg.QueryValueEx(key, 'PATH')[0]
def location_in_new_path(self, location, check=False):
locations = normpath(location).split(os.pathsep)
new_path = self._get_new_path()
for location in locations:
if not location_in_path(location, new_path):
if check:
raise Exception('Unable to find `{}` in:\n{}'.format(location, new_path))
else:
return False
else:
return True
def put(self, location, front=True, check=False, **kwargs):
import ctypes
location = normpath(location)
head, tail = (location, self._get_new_path()) if front else (self._get_new_path(), location)
new_path = '{}{}{}'.format(head, os.pathsep, tail)
with winreg.OpenKey(winreg.HKEY_CURRENT_USER, 'Environment', 0, winreg.KEY_WRITE) as key:
winreg.SetValueEx(key, 'PATH', 0, winreg.REG_EXPAND_SZ, new_path)
# https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-sendmessagetimeoutw
# https://docs.microsoft.com/en-us/windows/win32/winmsg/wm-settingchange
ctypes.windll.user32.SendMessageTimeoutW(
0xFFFF, # HWND_BROADCAST
0x1A, # WM_SETTINGCHANGE
0, # must be NULL
'Environment',
0x0002, # SMTO_ABORTIFHUNG
5000, # milliseconds
ctypes.wintypes.DWORD(),
)
return self.location_in_new_path(location, check=check)
class UnixInterface:
def __init__(self, shells=None, all_shells=False, home=None):
if shells:
all_shells = False
else:
if all_shells:
shells = sorted(SHELLS)
else:
shells = [self.detect_shell()]
shells = [os.path.basename(shell).lower() for shell in shells if shell]
shells = [shell for shell in shells if shell in SHELLS]
if not shells:
shells = DEFAULT_SHELLS
# De-dup and retain order
deduplicated_shells = set()
selected_shells = []
for shell in shells:
if shell not in deduplicated_shells:
deduplicated_shells.add(shell)
selected_shells.append(shell)
self.shells = [SHELLS[shell](home) for shell in selected_shells]
self.shells_to_verify = [SHELLS[shell](home) for shell in DEFAULT_SHELLS] if all_shells else self.shells
@classmethod
def detect_shell(cls):
# First, try to see what spawned this process
shell = get_parent_process_name().lower()
if shell in SHELLS:
return shell
# Then, search for environment variables that are known to be set by certain shells
# NOTE: This likely does not work when not directly in the shell
if 'BASH_VERSION' in os.environ:
return 'bash'
# Finally, try global environment
shell = os.path.basename(os.environ.get('SHELL', '')).lower()
if shell in SHELLS:
return shell
def location_in_new_path(self, location, check=False):
locations = normpath(location).split(os.pathsep)
for shell in self.shells_to_verify:
for show_path_command in shell.show_path_commands():
new_path = get_flat_output(show_path_command)
for location in locations:
if not location_in_path(location, new_path):
if check:
raise Exception(
'Unable to find `{}` in the output of `{}`:\n{}'.format(
location, show_path_command, new_path
)
)
else:
return False
else:
return True
def put(self, location, front=True, app_name=None, check=False):
location = normpath(location)
app_name = app_name or 'userpath'
for shell in self.shells:
for file, contents in shell.config(location, front=front).items():
try:
ensure_parent_dir_exists(file)
if os.path.exists(file):
with open(file, 'r', encoding='utf-8') as f:
lines = f.readlines()
else:
lines = []
if any(contents in line for line in lines):
continue
lines.append(
u'\n{} Created by `{}` on {}\n'.format(
shell.comment_starter, app_name, datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S')
)
)
lines.append(u'{}\n'.format(contents))
with open(file, 'w', encoding='utf-8') as f:
f.writelines(lines)
except Exception:
continue
return self.location_in_new_path(location, check=check)
__default_interface = WindowsInterface if os.name == 'nt' or platform.system() == 'Windows' else UnixInterface
class Interface(__default_interface):
pass