diff -r 0a74c1efab70 -r 0daf79d65080 install.py --- a/install.py Mon Apr 02 12:04:56 2018 +0200 +++ b/install.py Tue May 01 12:03:52 2018 +0200 @@ -11,13 +11,15 @@ from __future__ import unicode_literals, print_function try: + # Python2 only import cStringIO as io import sip sip.setapi('QString', 2) sip.setapi('QVariant', 2) sip.setapi('QTextStream', 2) + input = raw_input # __IGNORE_WARNING__ except (ImportError): - import io # __IGNORE_WARNING__ + import io # __IGNORE_WARNING__ import sys import os @@ -221,7 +223,8 @@ pyqtVariant = "PyQt4" del sys.modules["PyQt4"] except ImportError: - pyqtVariant = "" + # default to PyQt5, installation will be asked for + pyqtVariant = "PyQt5" def initGlobals(): @@ -240,7 +243,16 @@ if not os.path.exists(platBinDir): platBinDir = platBinDirOld else: - platBinDir = "/usr/local/bin" + pyBinDir = os.path.normpath(os.path.dirname(sys.executable)) + if os.access(pyBinDir, os.W_OK): + # install the eric scripts along the python executable + platBinDir = pyBinDir + else: + # install them in the user's bin directory + platBinDir = os.path.expanduser("~/bin") + if platBinDir != "/usr/local/bin" and \ + os.access("/usr/local/bin", os.W_OK): + platBinDirOld = "/usr/local/bin" modDir = distutils.sysconfig.get_python_lib(True) pyModDir = modDir @@ -249,7 +261,11 @@ if os.path.exists(os.path.join(pyqtDataDir, "qsci")): # it's the installer qtDataDir = pyqtDataDir + elif os.path.exists(os.path.join(pyqtDataDir, "Qt", "qsci")): + # it's the wheel + qtDataDir = os.path.join(pyqtDataDir, "Qt") else: + # determine dynamically try: if pyqtVariant == "PyQt4": from PyQt4.QtCore import QLibraryInfo @@ -286,6 +302,8 @@ @param dst destination file name (string) @param marker marker to be used (string) """ + global cfg + if sys.version_info[0] == 2: f = codecs.open(src, "r", "utf-8") else: @@ -293,6 +311,7 @@ text = f.read() f.close() + text = text.replace("@BINDIR@", cfg['bindir']) text = text.replace("@MARKER@", marker) if marker: t_marker = " ({0})".format(PythonTextMarkers[marker]) @@ -544,25 +563,54 @@ global pyModDir, progLanguages # Remove the menu entry for Linux systems - if sys.platform.startswith("linux") and os.getuid() == 0: - for name in ["/usr/share/pixmaps/eric.png", - "/usr/share/pixmaps/ericWeb.png"]: - if os.path.exists(name): - os.remove(name) - if includePythonVariant: - marker = PythonMarkers[sys.version_info.major] - else: - marker = "" - for name in ["/usr/share/applications/eric6" + marker + ".desktop", - "/usr/share/appdata/eric6" + marker + ".appdata.xml", - "/usr/share/metainfo/eric6" + marker + ".appdata.xml", - "/usr/share/applications/eric6_webbrowser" + marker + - ".desktop", - "/usr/share/applications/eric6_browser" + marker + - ".desktop", - ]: - if os.path.exists(name): - os.remove(name) + if sys.platform.startswith("linux"): + if os.getuid() == 0: + for name in ["/usr/share/pixmaps/eric.png", + "/usr/share/pixmaps/ericWeb.png"]: + if os.path.exists(name): + os.remove(name) + if includePythonVariant: + marker = PythonMarkers[sys.version_info.major] + else: + marker = "" + for name in [ + "/usr/share/applications/eric6" + marker + ".desktop", + "/usr/share/appdata/eric6" + marker + ".appdata.xml", + "/usr/share/metainfo/eric6" + marker + ".appdata.xml", + "/usr/share/applications/eric6_webbrowser" + marker + + ".desktop", + "/usr/share/applications/eric6_browser" + marker + + ".desktop", + "/usr/share/pixmaps/eric" + marker + ".png", + "/usr/share/pixmaps/ericWeb" + marker + ".png", + ]: + if os.path.exists(name): + os.remove(name) + elif os.getuid() >= 1000: + # it is assumed that user ids start at 1000 + for name in ["~/.local/share/pixmaps/eric.png", + "~/.local/share/pixmaps/ericWeb.png"]: + path = os.path.expanduser(name) + if os.path.exists(path): + os.remove(path) + if includePythonVariant: + marker = PythonMarkers[sys.version_info.major] + else: + marker = "" + for name in [ + "~/.local/share/applications/eric6" + marker + ".desktop", + "~/.local/share/appdata/eric6" + marker + ".appdata.xml", + "~/.local/share/metainfo/eric6" + marker + ".appdata.xml", + "~/.local/share/applications/eric6_webbrowser" + marker + + ".desktop", + "~/.local/share/applications/eric6_browser" + marker + + ".desktop", + "~/.local/share/pixmaps/eric" + marker + ".png", + "~/.local/share/pixmaps/ericWeb" + marker + ".png", + ]: + path = os.path.expanduser(name) + if os.path.exists(path): + os.remove(path) # Remove the wrapper scripts rem_wnames = [ @@ -595,9 +643,9 @@ # Cleanup our config file(s) for name in ['eric6config.py', 'eric6config.pyc', 'eric6.pth']: - e5cfile = os.path.join(pyModDir, name) - if os.path.exists(e5cfile): - os.remove(e5cfile) + e6cfile = os.path.join(pyModDir, name) + if os.path.exists(e6cfile): + os.remove(e6cfile) e5cfile = os.path.join(pyModDir, "__pycache__", name) path, ext = os.path.splitext(e5cfile) for f in glob.glob("{0}.*{1}".format(path, ext)): @@ -807,6 +855,8 @@ if installApis: for progLanguage in progLanguages: apidir = os.path.join(cfg['apidir'], progLanguage.lower()) + print("Installing {0} API files to '{1}'.".format( + progLanguage, apidir)) if not os.path.exists(apidir): os.makedirs(apidir) for apiName in glob.glob(os.path.join(sourceDir, "APIs", @@ -814,13 +864,15 @@ try: shutilCopy(apiName, apidir) except EnvironmentError: - print("Could not install '{0}'.".format(apiName)) + print("Could not install '{0}' (no permission)." + .format(apiName)) for apiName in glob.glob(os.path.join(sourceDir, "APIs", progLanguage, "*.bas")): try: shutilCopy(apiName, apidir) except EnvironmentError: - print("Could not install '{0}'.".format(apiName)) + print("Could not install '{0}' (no permission)." + .format(apiName)) if progLanguage == "Python": # copy Python3 API files to the same destination for apiName in glob.glob(os.path.join(sourceDir, "APIs", @@ -828,7 +880,8 @@ try: shutilCopy(apiName, apidir) except EnvironmentError: - print("Could not install '{0}'.".format(apiName)) + print("Could not install '{0}' (no permission)." + .format(apiName)) for apiName in glob.glob(os.path.join(sourceDir, "APIs", "Python3", "*.bas")): if os.path.exists(os.path.join( @@ -837,7 +890,8 @@ try: shutilCopy(apiName, apidir) except EnvironmentError: - print("Could not install '{0}'.".format(apiName)) + print("Could not install '{0}' (no permission)." + .format(apiName)) # create menu entry for Linux systems if sys.platform.startswith("linux"): @@ -910,6 +964,49 @@ "/usr/share/applications/eric6_browser" + marker + ".desktop", marker) + elif os.getuid() >= 1000: + # it is assumed, that user ids start at 1000 + localPath = os.path.join(os.path.expanduser("~"), + ".local", "share") + # create directories first + for directory in [os.path.join(localPath, name) + for name in ("pixmaps", "applications", + "metainfo", "appdata")]: + if not os.path.isdir(directory): + os.makedirs(directory) + # now copy the files + shutilCopy( + os.path.join(sourceDir, "icons", "default", "eric.png"), + os.path.join(localPath, "pixmaps", "eric" + marker + ".png")) + copyDesktopFile( + os.path.join(sourceDir, "eric6.desktop"), + os.path.join(localPath, "applications", + "eric6" + marker + ".desktop"), + marker) + copyAppStreamFile( + os.path.join(sourceDir, "eric6.appdata.xml"), + os.path.join(localPath, "metainfo", + "eric6" + marker + ".appdata.xml"), + marker) + copyAppStreamFile( + os.path.join(sourceDir, "eric6.appdata.xml"), + os.path.join(localPath, "appdata", + "eric6" + marker + ".appdata.xml"), + marker) + shutilCopy( + os.path.join(sourceDir, "icons", "default", "ericWeb48.png"), + os.path.join(localPath, "pixmaps", + "ericWeb" + marker + ".png")) + copyDesktopFile( + os.path.join(sourceDir, "eric6_webbrowser.desktop"), + os.path.join(localPath, "applications", + "eric6_webbrowser" + marker + ".desktop"), + marker) + copyDesktopFile( + os.path.join(sourceDir, "eric6_browser.desktop"), + os.path.join(localPath, "applications", + "eric6_browser" + marker + ".desktop"), + marker) # Create a Mac application bundle if sys.platform == "darwin": @@ -1126,6 +1223,29 @@ copyToFile(fn, config) +def pipInstall(packageName, message): + """ + Install the given package via pip. + + @param packageName name of the package to be installed + @type str + @param message message to be shown to the user + @type str + @return flag indicating a successful installation + @rtype bool + """ + ok = False + print(message, "\n") + answer = input("Shall '{0}' be installed using pip? (Y/n) " + .format(packageName)) + if answer in ("", "Y", "y"): + exitCode = subprocess.call( + [sys.executable, "-m", "pip", "install", packageName]) + ok = (exitCode == 0) + + return ok + + def doDependancyChecks(): """ Perform some dependency checks. @@ -1164,9 +1284,20 @@ try: from PyQt5.QtCore import qVersion except ImportError as msg: - print('Sorry, please install PyQt5.') - print('Error: {0}'.format(msg)) - exit(1) + installed = pipInstall( + "PyQt5", + "PyQt5 could not be detected.\nError: {0}".format(msg) + ) + if installed: + # try to import it again + try: + from PyQt5.QtCore import qVersion + except ImportError as msg: + print('Sorry, please install PyQt5.') + print('Error: {0}'.format(msg)) + exit(1) + else: + exit(1) print("Found PyQt5") try: @@ -1188,10 +1319,25 @@ else: from PyQt5 import Qsci # __IGNORE_WARNING__ except ImportError as msg: - print("Sorry, please install QScintilla2 and") - print("its PyQt5/PyQt4 wrapper.") - print('Error: {0}'.format(msg)) - exit(1) + if pyqtVariant == "PyQt4": + message = str(msg) + else: + installed = pipInstall( + "QScintilla", + "QScintilla could not be detected.\nError: {0}".format(msg) + ) + if installed: + # try to import it again + try: + from PyQt5 import Qsci # __IGNORE_WARNING__ + message = None + except ImportError as msg: + message = str(msg) + if message: + print("Sorry, please install QScintilla2 and") + print("its PyQt5/PyQt4 wrapper.") + print('Error: {0}'.format(msg)) + exit(1) print("Found QScintilla2") if pyqtVariant == "PyQt4":