<commit_before>import os.path
import socket
import subprocess
import shutil
import datetime
from subprocess import check_output
import logging
from arteria.web.state import State

""" Simple wrapper for the Sisyphus tools suite.
"""


class ProcessInfo(object):
    """Information about a process.

        State can be:
            none: Not ready for processing or invalid
            ready: Ready for processing by Arteria
            started: Arteria started processing the runfolder
            done: Arteria is done processing the runfolder
            error: Arteria started processing the runfolder but there was an
                   error; see property msg for details

        Also keeps track of other meta data for the process.
    """

    def __init__(self, runfolder=None, host=None, state=State.NONE,
                 proc=None, msg=None, pid=None):
        self.runfolder = runfolder
        self.host = host
        self.state = state
        self.proc = proc
        self.msg = msg
        self.pid = pid
        self.link = None

    def __str__(self):
        return "{0} {3}: {1}@{2}".format(self.state, self.runfolder,
                                         self.host, self.pid)

    def set_started(self, process):
        """ Update the appropriate meta data for the process when it has been started.
        """
        self.host = ProcessService._host()
        self.state = State.STARTED
        self.proc = process
        self.msg = "Process has been started"
        self.pid = process.pid

    @staticmethod
    def none_process(pid):
        """  Return an empty process information container if a non valid PID
             was requested.
        """
        return ProcessInfo(host=ProcessService._host(), pid=pid,
                           state=State.NONE,
                           msg="No such process exists")


class ExecString(object):
    """ Object for storing the string that will be executed. Content is semi
        standardised, as the called Perl scripts almost looks the same. It will
        vary somewhat depending on which wrapper is creating the object.

         Args:
            wrapper: the object creating ExecString
            conf_svc: the ConfigurationService serving our config lookups
            runfolder: which runfolder to use

         Returns:
            Sets its property 'text' to the string that will be executed
            in a subprocess.
     """
    def __init__(self, wrapper, conf_svc, runfolder):
        self.text = None
        bin_lookup = wrapper.binary_conf_lookup
        conf = conf_svc.get_app_config()
        self.text = [conf["perl"], conf[bin_lookup], "-runfolder", runfolder,
                     "-mail", conf["receiver"], "-sender", conf["sender"]]


class Wrapper(object):
    """ Our main wrapper for the Sisyphus scripts (QuickReport and
        QualityControl at the moment).

        Args:
            params: Dict of parameters to the wrapper. Must contain the name of
                    the runfolder to use (not full path). Can contain a YAML
                    object containing the Sisyphus config to use, and a XML
                    object cotaining the QC config to use.
            configuration_svc: The ConfigurationService for our config lookups
            logger: Logger object for printouts

        Raises:
            OSError: If the given runfolder doesn't exist.
    """

    QC_TYPE = "qc"
    REPORT_TYPE = "report"

    def __init__(self, params, configuration_svc, logger=None):
        self.conf_svc = configuration_svc
        self.logger = logger or logging.getLogger(__name__)

        conf = configuration_svc.get_app_config()
        runpath = conf["runfolder_root"] + "/" + params["runfolder"]

        if not os.path.isdir(runpath):
            raise OSError("No runfolder {0} exists.".format(runpath))

        self.info = ProcessInfo(runpath)

        if "sisyphus_config" in params:
            path = runpath + "/sisyphus.yml"
            self.write_new_config_file(path, params["sisyphus_config"])


    def __get_attr__(self, attr):
        return getattr(self.info, attr)

    @staticmethod
    def write_new_config_file(path, content):
        """ Writes new config file (especially used for Sisyphus YAML and QC XML).
            If the file already exists a backup copy will be created.

            Args:
                - path: The path to the config file that should be written.
                - content: The content of the new config file.
        """
        try:
            logger = logging.getLogger(__name__)

            logger.debug("Writing new config file " + path)

            now = datetime.datetime.now().isoformat()

            if os.path.isfile(path):
                logger.debug("Config file already existed. Making backup copy.")
                shutil.move(path, path + "." + now)

            with open(path, "w") as f:
                f.write(content)

        except OSError, err:
            logger.error("Error writing new config file {0}: {1}".
                              format(path, err))


    def sisyphus_version(self):
        """
        Use Sisyphus own script to check which version is used.
        :return: the sisyphus version used.
        """
        conf = self.conf_svc.get_app_config()
        cmd = [conf["perl"], conf["version_bin"]]
        sisphus_version = check_output(cmd)<commit_msg>Smb-shares don't like : in file names<commit_after>import os.path
import socket
import subprocess
import shutil
import time
from subprocess import check_output
import logging
from arteria.web.state import State

""" Simple wrapper for the Sisyphus tools suite.
"""


class ProcessInfo(object):
    """Information about a process.

        State can be:
            none: Not ready for processing or invalid
            ready: Ready for processing by Arteria
            started: Arteria started processing the runfolder
            done: Arteria is done processing the runfolder
            error: Arteria started processing the runfolder but there was an
                   error; see property msg for details

        Also keeps track of other meta data for the process.
    """

    def __init__(self, runfolder=None, host=None, state=State.NONE,
                 proc=None, msg=None, pid=None):
        self.runfolder = runfolder
        self.host = host
        self.state = state
        self.proc = proc
        self.msg = msg
        self.pid = pid
        self.link = None

    def __str__(self):
        return "{0} {3}: {1}@{2}".format(self.state, self.runfolder,
                                         self.host, self.pid)

    def set_started(self, process):
        """ Update the appropriate meta data for the process when it has been started.
        """
        self.host = ProcessService._host()
        self.state = State.STARTED
        self.proc = process
        self.msg = "Process has been started"
        self.pid = process.pid

    @staticmethod
    def none_process(pid):
        """  Return an empty process information container if a non valid PID
             was requested.
        """
        return ProcessInfo(host=ProcessService._host(), pid=pid,
                           state=State.NONE,
                           msg="No such process exists")


class ExecString(object):
    """ Object for storing the string that will be executed. Content is semi
        standardised, as the called Perl scripts almost looks the same. It will
        vary somewhat depending on which wrapper is creating the object.

         Args:
            wrapper: the object creating ExecString
            conf_svc: the ConfigurationService serving our config lookups
            runfolder: which runfolder to use

         Returns:
            Sets its property 'text' to the string that will be executed
            in a subprocess.
     """
    def __init__(self, wrapper, conf_svc, runfolder):
        self.text = None
        bin_lookup = wrapper.binary_conf_lookup
        conf = conf_svc.get_app_config()
        self.text = [conf["perl"], conf[bin_lookup], "-runfolder", runfolder,
                     "-mail", conf["receiver"], "-sender", conf["sender"]]


class Wrapper(object):
    """ Our main wrapper for the Sisyphus scripts (QuickReport and
        QualityControl at the moment).

        Args:
            params: Dict of parameters to the wrapper. Must contain the name of
                    the runfolder to use (not full path). Can contain a YAML
                    object containing the Sisyphus config to use, and a XML
                    object cotaining the QC config to use.
            configuration_svc: The ConfigurationService for our config lookups
            logger: Logger object for printouts

        Raises:
            OSError: If the given runfolder doesn't exist.
    """

    QC_TYPE = "qc"
    REPORT_TYPE = "report"

    def __init__(self, params, configuration_svc, logger=None):
        self.conf_svc = configuration_svc
        self.logger = logger or logging.getLogger(__name__)

        conf = configuration_svc.get_app_config()
        runpath = conf["runfolder_root"] + "/" + params["runfolder"]

        if not os.path.isdir(runpath):
            raise OSError("No runfolder {0} exists.".format(runpath))

        self.info = ProcessInfo(runpath)

        if "sisyphus_config" in params:
            path = runpath + "/sisyphus.yml"
            self.write_new_config_file(path, params["sisyphus_config"])


    def __get_attr__(self, attr):
        return getattr(self.info, attr)

    @staticmethod
    def write_new_config_file(path, content):
        """ Writes new config file (especially used for Sisyphus YAML and QC XML).
            If the file already exists a backup copy will be created.

            Args:
                - path: The path to the config file that should be written.
                - content: The content of the new config file.
        """
        try:
            logger = logging.getLogger(__name__)

            logger.debug("Writing new config file " + path)

            now = time.strftime("%Y%m%d-%H%M%S")

            if os.path.isfile(path):
                logger.debug("Config file already existed. Making backup copy.")
                shutil.move(path, path + "." + now)

            with open(path, "w") as f:
                f.write(content)

        except OSError, err:
            logger.error("Error writing new config file {0}: {1}".
                              format(path, err))


    def sisyphus_version(self):
        """
        Use Sisyphus own script to check which version is used.
        :return: the sisyphus version used.
        """
        conf = self.conf_svc.get_app_config()
        cmd = [conf["perl"], conf["version_bin"]]
        sisphus_version = check_output(cmd)
{'fraction_non_alphanumeric': 0.08164398778117189, 'fraction_numerical': 0.0012959363139868555, 'mean_word_length': 2.025483057966956, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6510857', 'n_tokens_mistral': 2890, 'n_tokens_neox': 2758, 'n_words': 990}