diff --git a/installPsychoPy.py b/installPsychoPy.py
index 004cdcf8cc..d272688e8f 100644
--- a/installPsychoPy.py
+++ b/installPsychoPy.py
@@ -1,186 +1,109 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-# Part of the PsychoPy library
-# Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2024 Open Science Tools Ltd.
-# Distributed under the terms of the GNU General Public License (GPL).
+## python script to install psychopy including dependencies
+import os, sys
+import pathlib
import subprocess
-import os
-import sys
-import requests
-
-"""This script will install PsychoPy to the current Python environment.
-
-For Linux installations, the script will fetch the supported linux distros for wxPython
-and interactively select the distro and version to download the appropriate .whl file.
-
-After that the script will install PsychoPy using pip.
-
-NB: At present, for windows and MacOS you may as well just use `pip install psychopy` but
-in the future we may add some additional functionality here, like adding application
-shortcuts, checking/recommending virtual envs etc.
-"""
-
-# Author: Florian Osmani
-# Author: Jonathan Peirce
-
-wxLinuxUrl = "https://extras.wxpython.org/wxPython4/extras/linux/gtk3/"
-
-def installWhlFile(whlUrl):
- """Installs a single specified wheel file using pip"""
- wheel_path = os.path.basename(whlUrl)
- subprocess.run([sys.exectuable, '-m', 'pip', 'install', '-U', '-f', wheel_path, 'wxPython'], check=True)
-
-def installPsychoPy():
- """Runs pip install psychopy"""
- subprocess.run([sys.exectuable, '-m', 'pip', 'install', 'psychopy'], check=True)
-
-def getWxUrl(distroNames=None):
- """Fetch the supported linux distros for wx and interactively select the
- distro and version to download the appropriate .whl file.
-
- Args:
- distroNames (_type_, optional): _description_. Defaults to None.
-
- Returns:
- list: URL of the wheel for the selected distro/version
- """
- def extractDistroNames(url):
- """Extract the names of the linux distributions from the html content"""
-
- response = requests.get(url)
- response.raise_for_status()
-
- distro_names = []
- lines = response.text.split('\n')
- for line in lines:
- if ' 10:
- print("Sorry, please use Python 3.8, 3.9, or 3.10 to install Psychopy")
- return None
-
- python_cp = f"cp{version_info.major}{version_info.minor}"
-
- def selectDistro(distroNames):
- print("Please select your Linux distribution:")
- for i, distro in enumerate(distroNames):
- print(f"{i + 1}. {distro}")
-
- while True:
- choice = input("Enter your choice (number): ")
- if choice.isdigit() and 1 <= int(choice) <= len(distroNames):
- return distroNames[int(choice) - 1]
+import platform
+
+_linux_installer = None # will be apt-get or yum depending on system
+
+print(
+ "This `install_psychopy.py` script is EXPERIMENTAL and may not work!"
+ " PsychoPy users have many different systems and it's hard to maintain them all. "
+ " Let us know how you get on!\n"
+)
+if sys.version_info[:2] != (3,10):
+ print(
+ "PsychoPy is designed for Python 3.10.x "
+ f"You are running Python {sys.version_info[0]}.{sys.version_info[1]}.{sys.version_info[2]}. "
+ "PsychoPy may not work and may not even install!\n"
+ )
+
+print(
+ "This `install_psychopy.py` script is EXPERIMENTAL and may not work!"
+ " PsychoPy users have many different systems and it's hard to maintain them all. "
+ " Let us know how you get on!\n"
+)
+
+def pip_install(*packages):
+ """Install packages using pip."""
+ print('Installing packages:', packages)
+ subprocess.run([sys.executable, '-m', 'pip', 'install', '--upgrade'] + list(packages))
+
+def check_venv():
+ """Check if this is a virtual environment. If not, recommend quitting and creating one.
+ """
+ # If this is not a venv then recommend quitting to create one
+ if not hasattr(sys, 'real_prefix'):
+ print(
+ 'You should install PsychoPy in a virtual environment,'
+ ' to avoid conflicts with other packages, or damaging your system.'
+ ' To create a virtual environment in the current directory, run:')
+ print(' python3 -m venv .')
+ print('Then activate the virtual environment with:')
+ print(' source bin/activate')
+ print('Then run this script again.')
+ response = input('Shall we QUIT now? [y]/n: ')
+ if response.lower() != 'n':
+ sys.exit(1)
+
+def apt_install(*packages):
+ """Install packages using apt, yum, or similar"""
+ global _linux_installer
+ # check if using this system has apt-get or yum
+ if _linux_installer is None:
+ for installer in ['apt', 'yum', 'dnf', 'zypper', 'apt-cyg']:
+ out = subprocess.run(['which', installer], stdout=subprocess.PIPE)
+ if out.returncode == 0:
+ _linux_installer = installer
+ break
+ if _linux_installer is None:
+ print('On Linux systems, this script requires either apt-get or yum.')
+ sys.exit(1)
+
+ def find_package(package):
+ # check pacakage name according to apt/yum
+ packages_lookup = {
+ 'python3-dev': {'apt':'libgtk-3-dev', 'yum':'gtk3-devel'},
+ 'libgtk-3-dev': {'apt':'libgtk-3-dev', 'yum':'gtk3-devel'},
+ 'libwebkit2gtk-4.0-dev': {'apt':'libwebkit2gtk-4.0-dev', 'yum':'webkit2gtk3-devel'},
+ 'libxcb-xinerama0': {'apt':'libxcb-xinerama0', 'yum':'libxcb-xinerama'},
+ 'libegl1-mesa-dev': {'apt':'libegl1-mesa-dev', 'yum':'mesa-libEGL-devel'},
+ }
+ if package in packages_lookup:
+ if _linux_installer in packages_lookup[package]:
+ return packages_lookup[package][_linux_installer]
else:
- print("Invalid choice, please try again.")
-
- def organizeDistributions(distroNames):
- distroDict = {}
- for distro in distroNames:
- nameParts = distro.split('-')
- distroName = '-'.join(nameParts[:-1])
- version = nameParts[-1] if len(nameParts) > 1 else 'default'
-
- if distroName in distroDict:
- distroDict[distroName].append(version)
- else:
- distroDict[distroName] = [version]
-
- return distroDict
-
- def selectVersion(selectedDistro, versions):
- while True:
- print("Please select the version:")
- for i, version in enumerate(versions):
- print(f"{i + 1}. {selectedDistro}-{version}")
- print("0. Go back")
-
- choice = input("Enter your choice (number): ")
- if choice.isdigit():
- choice = int(choice)
- if 1 <= choice <= len(versions):
- return versions[choice - 1]
- elif choice == 0:
- return None
- print("Invalid choice, please try again.")
-
- def fetchWhlFiles(htmlContent, pythonVersions):
- all = []
- recommended = []
- lines = htmlContent.split('\n')
- for line in lines:
- if '