Skip to content
Snippets Groups Projects
dct_utils_platform.py 8.89 KiB
'''
Created on Jan 30, 2013

@author: ben
'''

import subprocess
import os
import re

class UtilsFactory (object):

    @staticmethod
    def getMachineDep():
        import platform

        machine = platform.machine()
        system = platform.system()
        hostname = platform.node()
        if system == 'Linux':
            distro = platform.linux_distribution()
            ver_num_major = distro[1].split(".")[0]
            distro = "".join([distro[0], ver_num_major])
            return UtilsLinux(machine = machine, hostname = hostname, \
                              distro = distro)
        else:
            raise SystemError("Unsupported system: '%s' on machine: '%s'" % (system, machine))

class UtilsInterface(object):

    def __init__(self, machine, hostname):
        self.machine = machine
        self.hostname = hostname

    def getUserConfDir(self, dct_version):
        return ""

    def getUserConfFile(self, dct_version, file_name):
        return ""

    def getSystemDescription(self):
        return ""

    def guessUserRealName(self):
        return ""

    def guessUserEmail(self):
        return ""

    def checkGitVersion(self, min_ver = [0, 0, 0, 0]):
        subobj = subprocess.Popen(['git', '--version'], stdout=subprocess.PIPE)

        if subobj.poll() > 0:
            raise SystemError("Git is not installed!")

        output = subobj.stdout.read().split()

        version = [int(piece) for piece in output[2].split('.')]

        for indx in range(len(version)):
            if (version[indx] < min_ver[indx]):
                raise SystemError("Git version: %s is too old, upgrade to at least %s" % (output[2], "%d.%d.%d.%d" % min_ver))

        return output[2]


    def checkSvnServers(self):
        svnservers = self._getSvnServersPath()

        try:
            fid = open(svnservers, "r")
            lines = fid.readlines()
            fid.close()

            searchPatterns = [("^\s*http-proxy-host = .*", "http-proxy-host = proxy.esrf.fr"), \
                              ("^\s*http-proxy-port = .*", "http-proxy-port = 3128")]

            for searchP, subP in searchPatterns:
                for lineNum in range(len(lines)):
                    m = re.search(searchP, lines[lineNum])
                    if m is not None:
                        lines[lineNum] = re.sub(searchP, subP, lines[lineNum])
                        break
                else:
                    lines.append(subP)
        except:
            print("SVN servers file: '%s' doesn't exist" % svnservers)
            lines = ["http-proxy-host = proxy.esrf.fr", "http-proxy-host = proxy.esrf.fr"]
        finally:
            fid = open(svnservers, "w+")
            fid.writelines(lines)
            fid.close()


    def checkGccVersion(self, min_ver = [0, 0, 0]):
        subobj = subprocess.Popen(['g++', '--version'], stdout=subprocess.PIPE)

        if subobj.poll() > 0:
            raise SystemError("g++ is not installed!")

        output = subobj.stdout.readline()

        regexp = re.compile("\d.\d.\d")
        match = regexp.search(output)

        version_txt = match.group()

        version = [int(piece) for piece in version_txt.split('.')]

        for indx in range(len(version)):
            if (version[indx] < min_ver[indx]):
                raise SystemError("g++ version: %s is too old, upgrade to at least %s" % (output[2], "%d.%d.%d" % min_ver))

        return version_txt


    def checkMatlabGccVersion(self, searchPatterns, matlabVersion, \
                              matlabPath = ""):
        import stat

        mexoptsfile = self._getMatlabMexoptsPath(matlabVersion)

        if os.path.exists(mexoptsfile) is not True:
            if matlabPath is "":
                # Try ESRF Paths
                matlabPath = self._getMatlabPath(matlabVersion)
            self._createMatlabMexopts(matlabPath)

        stats = os.stat(mexoptsfile)
        os.chmod(mexoptsfile, stats.st_mode | stat.S_IWRITE)

        fid = open(mexoptsfile, "r")
        lines = fid.readlines()
        fid.close()

        for searchP, subP in searchPatterns:
            for lineNum in range(len(lines)):
                m = re.search(searchP, lines[lineNum])
                if m is not None:
                    lines[lineNum] = re.sub(searchP, subP, lines[lineNum])

        fid = open(mexoptsfile, "w+")
        fid.writelines(lines)
        fid.close()

    def scpFile(self, filename, destination):
        return False

    def _getSvnServersPath(self):
        return ""

    def _getMatlabMexoptsPath(self, matlabVersion):
        return ""

    def _createMatlabMexopts(self, matlabVersion):
        return ""

    def _getMatlabPath(self, matlabVersion):
        return ""

class UtilsLinux(UtilsInterface):

    def __init__(self, machine, hostname, distro):
        UtilsInterface.__init__(self, machine = machine, hostname = hostname)
        self.distro = distro

    def getUserConfDir(self, dct_version):
        return os.path.join(os.getenv("HOME"), ".dct", dct_version)

    def getUserConfFile(self, dct_version, file_name):
        return os.path.join(os.getenv("HOME"), ".dct", dct_version, file_name)

    def getSystemDescription(self):
        return " ".join([self.distro, self.machine])

    def _getSvnServersPath(self):
        userpath = os.getenv("HOME", "")
        return os.path.join(userpath, ".subversion", "servers")

    def _getMatlabMexoptsPath(self, matlabVersion):
        userpath = os.getenv("HOME", "")
        return os.path.join(userpath, ".matlab", ("R%s" % matlabVersion),  "mexopts.sh")

    def _createMatlabMexopts(self, matlabPath):
        cmd =  [os.path.join(matlabPath, "bin", "mex"), "-setup"]
        try:
            subobj = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
            subobj.stdin.write("1\n")
            subobj.wait()
        except OSError as ex:
            print(ex.args)
            raise ValueError("Error with location: %s\nCheck if it exists!" % cmd[0])

    def _getMatlabPath(self, matlabVersion):
        return os.path.join("/sware", "com", "matlab_%s" % matlabVersion)

    def checkMatlabGccVersion(self, matlabVersion, matlabPath = ""):
        searchPatterns = [("COPTIMFLAGS='-O -DNDEBUG'", "COPTIMFLAGS='-O -DNDEBUG -fopenmp'"), \
                          ("CXXOPTIMFLAGS='-O -DNDEBUG'", "CXXOPTIMFLAGS='-O -DNDEBUG -fopenmp'"), \
                          ('(CLIBS="\$RPATH \$MLIBS -lm)"', '\g<1> -fopenmp"'), \
                          ('(CXXLIBS="\$RPATH \$MLIBS -lm)"', '\g<1> -fopenmp"')]

        if self.distro == "CentOS5":
            searchPatterns.append(("CC='gcc'", "CC='gcc44'"))
            searchPatterns.append(("CXX='g\+\+'", "CXX='g++44'"))

        UtilsInterface.checkMatlabGccVersion(self, \
                                             searchPatterns = searchPatterns, \
                                             matlabVersion = matlabVersion, \
                                             matlabPath = matlabPath)

    def guessUserRealName(self):
        username = os.getenv("USER")
        cmd = ["grep", "^%s:" % username, "/etc/passwd"]
        subobj = subprocess.Popen(cmd, stdout = subprocess.PIPE)
        subobj.wait()
        cmd = [ "awk", "-F:", "{print $5}"]
        subobj1 = subprocess.Popen(cmd, stdout = subprocess.PIPE, stdin = subobj.stdout)
        (name, err) = subobj1.communicate()

        if name == "":
            # Try ESRF
            possibilies = ("".join([username[0], "*", username[1:]]), username)
            for poss in possibilies:
                cmd = ["td", poss]
                subobj = subprocess.Popen(cmd, stdout = subprocess.PIPE)
                cmd = ["awk", '--field-separator= ', '{print $2 " " $1}']
                subobj1 = subprocess.Popen(cmd, stdout = subprocess.PIPE, stdin = subobj.stdout)
                (name, err) = subobj1.communicate()
                if name[0:10] != 'The string':
                    name = name[:-1].lower()
                    name = name.split(" ")
                    name[0] = name[0].capitalize()
                    name[1] = name[1].capitalize()
                    return " ".join(name)
            else:
                raise SystemError("Couldn't determine user real name")
        else:
            return name[:-1]

    def guessUserEmail(self):
        username = os.getenv("USER")
        # Try ESRF
        possibilies = ("".join([username[0], "*", username[1:]]), username)
        for poss in possibilies:
            cmd = ["td", poss]
            subobj = subprocess.Popen(cmd, stdout = subprocess.PIPE)
            subobj.wait()
            name = subobj.stdout.read()
            if name[0:10] != 'The string':
                name = name[:-1].lower()
                name = name.split(" ")
                name = "".join([name[-1], "@esrf.fr"])
                return name
        else:
            raise SystemError("Couldn't determine user real name")

    def scpFile(self, filename, destination):
        cmd = ["scp", filename, destination]
        return subprocess.call(cmd) == 0