Source code for aiscalator.core.utils

# -*- coding: utf-8 -*-
# Apache Software License 2.0
#
# Copyright (c) 2018, Christophe Duong
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Various Utility functions
"""
import os
import re
from logging import info
from subprocess import PIPE  # nosec
from subprocess import STDOUT
from subprocess import Popen
from threading import Thread


[docs]def data_file(path): """ Utility function to find resources data file packaged along with code Parameters ---------- path : path path to the resource file in the package Returns ------- absolute path to the resource data file """ return os.path.join(os.path.abspath(os.path.dirname(__file__)), path)
[docs]def find(collection, item, field='name'): """ Finds an element in a collection which has a field equal to particular item value Parameters ---------- collection : Set Collection of objects item value of the item that we are looking for field : string Name of the field from the object to inspect Returns ------- object Corresponding element that has a field matching item in the collection """ for element in collection: if element[field] == item: return element return None
[docs]def copy_replace(src, dst, pattern='', replace_value=''): """ Copies a file from src to dst replacing pattern by replace_value Parameters ---------- src : string Path to the source filename to copy from dst : string Path to the output filename to copy to pattern : string Pattern to replace inside the src file replace_value Value to replace by in the dst file """ if isinstance(src, str): file1 = open(src, 'r') else: file1 = src if isinstance(dst, str): file2 = open(dst, 'w') else: file2 = dst regex = re.compile(pattern, re.IGNORECASE) for line in file1: # file2.write(line.replace(pattern, replace_value)) file2.write(re.sub(regex, replace_value, line)) if isinstance(src, str): file1.close() if isinstance(dst, str): file2.close()
[docs]def log_info(pipe): """ Default logging function """ for line in iter(pipe.readline, b''): info(line) return True
[docs]class BackgroundThreadRunner(): """ Worker Thread to run logging output in the background ... Attributes ---------- _process : Process object of the command running in the background _log_function : function(stream -> bool) callback function to log the output of the command _no_redirect : bool whether the subprocess STDOUT and STDERR should be redirected to logs _worker : Thread Thread object """ def __init__(self, command, log_function, no_redirect=False): self._no_redirect = no_redirect if no_redirect: self._process = Popen(command) # nosec else: self._process = Popen(command, stdout=PIPE, stderr=STDOUT) # nosec self._log_function = log_function self._worker = Thread(name='worker', target=self.run) self._worker.start()
[docs] def run(self): """ Starts the Thread, process the output of the process. """ if not self._no_redirect: self._log_function(self._process.stdout)
[docs] def process(self): """Returns the process object.""" return self._process
[docs]def subprocess_run(command, log_function=log_info, no_redirect=False, wait=True): """ Run command in a subprocess while redirecting output to log_function. The subprocess either runs synchroneoulsy or in the background depending on the wait parameter. Parameters ---------- command : List Command to run in the subprocess log_function : function Callback function to log the output of the subprocess no_redirect : bool whether the subprocess STDOUT and STDERR should be redirected to logs wait : bool Whether the subprocess should be run synchroneously or in the background Returns ------- int return code of the subprocess BackgroundThreadRunner the thread running in the background """ if wait: if no_redirect: process = Popen(command, shell=False) # nosec else: process = Popen(command, stdout=PIPE, stderr=STDOUT, shell=False) # nosec with process.stdout: log_function(process.stdout) return process.wait() else: return BackgroundThreadRunner(command, log_function, no_redirect)