예제 #1
0
 def __init__(self):
     super().__init__()
     self.log = ConsoleLogger()
     self.inventory_collection = None
     self.inventory_collection_name = None
     self.collections = {}
     self.monitoring_setup_manager = None
예제 #2
0
class AndroidAudioUtils():

    def __init__(self):
        self._logger = ConsoleLogger()

        self._droid = sl4a.Android()

    def speak(self, text):
        self._droid.ttsSpeak(text)

    def stop_listening(self):
        self._listening = False

    def listen(self, callback):
        self._listening = True
        self._run_listening_loop(callback)

    def _run_listening_loop(self, callback):

        while self._listening:
            if self._droid.ttsIsSpeaking()[1]:
                sleep(1)
                continue

            try:
                result = self._droid.recognizeSpeech()[1]
                callback(result)
                sleep(1)
            except Exception as e:
                self._logger.error(e)
예제 #3
0
    def __init__(self):
        self._logger = ConsoleLogger()

        self._recognizer = sr.Recognizer()
        self._microphone = sr.Microphone()

        with self._microphone as source:
            self._recognizer.adjust_for_ambient_noise(source)
예제 #4
0
    def __init__(self, messenger):
        super(MusicAgent,
              self).__init__(messenger=messenger,
                             name=NAME,
                             comparison_commands=COMPARISON_COMMANDS)

        self._logger = ConsoleLogger()
        self._player = None

        self._messenger.register_callback(self.process)
예제 #5
0
    def __init__(self, platform="osx"):
        self._logger = ConsoleLogger()

        self._similarity_utils = SimilarityUtilsFactory().get_similarity_utils(
        )

        self._audio_utils = AudioUtilsFactory(
            platform=platform).get_audio_utils()

        self._topic_agents = []
        self._default_agent = None
        self._messenger_dict = {}

        self._init_agents()
예제 #6
0
    def setUp(self):
        self.log = ConsoleLogger()
        self.env = ENV_CONFIG
        self.collection = COLLECTION_CONFIG
        self.item_ids = []

        self.inv_patcher = patch('discover.events.event_base.InventoryMgr')
        self.inv_class = self.inv_patcher.start()
        self.inv = self.inv_class.return_value

        self.log_patcher = patch('discover.fetcher.FullLogger')
        self.log_patcher.start()
예제 #7
0
class PcAudioUtils():

    def __init__(self):
        self._logger = ConsoleLogger()

        self._recognizer = sr.Recognizer()
        self._microphone = sr.Microphone()

        with self._microphone as source:
            self._recognizer.adjust_for_ambient_noise(source)

    def speak(self, text, language="en"):
        if text is not None:
            call(['python3', 'utils/audio/pc_text_to_voice.py', text, language])

    def stop_listening(self):
        raise NotImplementedError("listen has to be called first!")

    def listen(self, callback):
        listener_callback = partial(
            self._listen_for_command, callback)

        stop_recognizer = self._recognizer.listen_in_background(
            self._microphone, listener_callback)

        self.stop_listening = stop_recognizer

    def _listen_for_command(self, callback, _, audio):
        try:

            command = self._recognizer.recognize_google(audio)
            callback(command)

        except sr.UnknownValueError:
            self._logger.warning("A Value error occurred. Please repeat!")
        except sr.RequestError as e:
            self._logger.error(
                "Could not request results from Google Speech Recognition service; {0}".format(e))
예제 #8
0
class CalipsoApiException(Exception):
    log = ConsoleLogger()

    def __init__(self, status, body="", message=""):
        super().__init__(message)
        self.message = message
        self.status = status
        self.body = body

    @staticmethod
    def handle(ex, req, resp, params):
        CalipsoApiException.log.error(ex.message)
        resp.status = ex.status
        resp.body = ex.body
예제 #9
0
    def __init__(self):
        super().__init__()
        self.log_file = os.path.join(FileLogger.LOG_DIRECTORY,
                                     MongoAccess.LOG_FILENAME)

        try:
            self.log = FileLogger(self.log_file)
        except OSError as e:
            ConsoleLogger().warning("Couldn't use file {} for logging. "
                                    "Using default location: {}.\n"
                                    "Error: {}".format(self.log_file,
                                                       self.DEFAULT_LOG_FILE,
                                                       e))

            self.log_file = self.DEFAULT_LOG_FILE
            self.log = FileLogger(self.log_file)

        self.connect_params = {}
        self.mongo_connect(self.config_file)
예제 #10
0
class MoneyPenny():
    def __init__(self, platform="osx"):
        self._logger = ConsoleLogger()

        self._similarity_utils = SimilarityUtilsFactory().get_similarity_utils(
        )

        self._audio_utils = AudioUtilsFactory(
            platform=platform).get_audio_utils()

        self._topic_agents = []
        self._default_agent = None
        self._messenger_dict = {}

        self._init_agents()

    def _init_agents(self):
        self._init_topic_agents()
        self._init_default_agent()

    def _init_topic_agents(self):
        for AgentClass in TOPIC_AGENTS:
            messenger = QueueMessenger()
            agent = AgentClass(messenger)
            self._topic_agents.append(agent)
            self._messenger_dict[agent.name] = messenger

    def _init_default_agent(self):
        messenger = QueueMessenger()
        agent = DEFAULT_AGENT(messenger)
        self._default_agent = agent
        self._messenger_dict[agent.name] = messenger

    def _listen(self, command):
        self._logger.info(f"Understood '{command}'")

        valid = self._evaluate_command(command)
        if not valid:
            return

        command = self._preprocess_command(command)

        agent = self._get_most_probable_agent(command, threshold=0.5)
        self._send_command_to_agent(agent, command)

    def _evaluate_command(self, command):
        command = command.lower()

        if 'moneypenny' in command or 'money penny' in command:
            return True
        else:
            self._logger.warning('The command has to include "moneypenny"!')
            return False

    def _preprocess_command(self, command):
        command = command.lower()

        if 'moneypenny' in command:
            command = command.split("moneypenny")[-1]
        elif 'money penny' in command:
            command = command.split("money penny")[-1]

        return command

    def _get_most_probable_agent(self, command, threshold=0):
        highest_similarities = []
        for agent in self._topic_agents:
            highest_similarity = 0
            for comparison_command in agent.comparison_commands:
                similarity = self._similarity_utils.get_similarity(
                    command, comparison_command)
                if similarity > highest_similarity:
                    highest_similarity = similarity
            highest_similarities.append(highest_similarity)

        if len([
                similarity for similarity in highest_similarities
                if similarity > threshold
        ]) > 0:
            agent_index = np.argmax(highest_similarities)
            return self._topic_agents[agent_index]
        else:
            return self._default_agent

    def _send_command_to_agent(self, agent, command):
        messenger = self._messenger_dict[agent.name]
        messenger.send(command)

    def start(self):
        self._audio_utils.listen(self._listen)

        self._audio_utils.speak("I am ready to listen to you.")

        self._default_agent.start()
        for agent in self._topic_agents:
            agent.start()

    def stop(self):
        self._audio_utils.stop_listening()

        self._default_agent.stop()
        for agent in self._topic_agents:
            agent.stop()

        self._logger.info('stopped moneypenny')
예제 #11
0
 def __init__(self):
     super().__init__()
     self.log = ConsoleLogger()
예제 #12
0
class CliAccess(BinaryConverter, Fetcher):
    connections = {}
    ssh_cmd = "ssh -q -o StrictHostKeyChecking=no "
    call_count_per_con = {}
    max_call_count_per_con = 100
    cache_lifetime = 60  # no. of seconds to cache results
    cached_commands = {}

    def __init__(self):
        super().__init__()
        self.log = ConsoleLogger()

    @staticmethod
    def is_gateway_host(ssh_to_host):
        ssh_conn = SshConn(ssh_to_host)
        return ssh_conn.is_gateway_host(ssh_to_host)

    def run_on_gateway(self, cmd, ssh_to_host="", enable_cache=True,
                       use_sudo=True):
        self.run(cmd, ssh_to_host=ssh_to_host, enable_cache=enable_cache,
                 on_gateway=True, use_sudo=use_sudo)

    def run(self, cmd, ssh_to_host="", enable_cache=True, on_gateway=False,
            ssh=None, use_sudo=True):
        ssh_conn = ssh if ssh else SshConn(ssh_to_host)
        commands = self.adapt_cmd_to_env(ssh_conn, cmd, use_sudo, on_gateway,
                                         ssh_to_host)
        out = ''
        for c in commands:
            out += self.run_single_command(c, ssh_conn, ssh_to_host,
                                           enable_cache=enable_cache)
        return out

    def run_single_command(self, cmd, ssh_conn, ssh_to_host="",
                           enable_cache=True):
        curr_time = time.time()
        cmd_path = ssh_to_host + ',' + cmd
        if enable_cache and cmd_path in self.cached_commands:
            # try to re-use output from last call
            cached = self.cached_commands[cmd_path]
            if cached["timestamp"] + self.cache_lifetime < curr_time:
                # result expired
                self.cached_commands.pop(cmd_path, None)
            else:
                # result is good to use - skip the SSH call
                self.log.info('CliAccess: ****** using cached result, ' +
                              'host: ' + ssh_to_host + ', cmd: %s ******', cmd)
                return cached["result"]

        self.log.info('CliAccess: host: %s, cmd: %s', ssh_to_host, cmd)
        ret = ssh_conn.exec(cmd)
        self.cached_commands[cmd_path] = {"timestamp": curr_time, "result": ret}
        return ret

    def run_fetch_lines(self, cmd, ssh_to_host="", enable_cache=True):
        out = self.run(cmd, ssh_to_host, enable_cache)
        if not out:
            return []
        # first try to split lines by whitespace
        ret = out.splitlines()
        # if split by whitespace did not work, try splitting by "\\n"
        if len(ret) == 1:
            ret = [line for line in out.split("\\n") if line != ""]
        return ret

    MULTI_COMMAND_SEPARATOR = ';;;'

    @staticmethod
    def handle_split_cmd(cmd: str):
        if CliAccess.MULTI_COMMAND_SEPARATOR in cmd:
            return cmd.split(CliAccess.MULTI_COMMAND_SEPARATOR)
        return [cmd]

    def adapt_cmd_to_env(self, ssh_conn, cmd, use_sudo, on_gateway,
                         ssh_to_host):
        cmd = self.adapt_cmd_to_dist(cmd)
        commands = self.handle_split_cmd(cmd)
        return [self.adapt_cmd_to_environment(c, use_sudo, on_gateway,
                                              ssh_to_host, ssh_conn)
                for c in commands]

    def adapt_cmd_to_environment(self, cmd, use_sudo, on_gateway, ssh_to_host,
                                 ssh_conn):
        if self.configuration.environment["distribution"] == "Mercury":
            use_sudo = False
        if use_sudo and not cmd.strip().startswith("sudo "):
            cmd = "sudo " + cmd
        if not on_gateway and ssh_to_host \
                and not ssh_conn.is_gateway_host(ssh_to_host):
            cmd = self.ssh_cmd + ssh_to_host + " " + cmd
        return cmd

    def adapt_cmd_to_dist(self, cmd):
        env_conf = self.configuration.get_env_config()
        dist = env_conf.get('distribution')
        dist_version = env_conf.get('distribution_version')
        translator = CliDistTranslator(dist, dist_version=dist_version)
        cmd = translator.translate(cmd)
        return cmd

    # parse command output columns separated by whitespace
    # since headers can contain whitespace themselves,
    # it is the caller's responsibility to provide the headers
    def parse_cmd_result_with_whitespace(self, lines, headers, remove_first):
        if remove_first:
            # remove headers line
            del lines[:1]
        results = [self.parse_line_with_ws(line, headers)
                   for line in lines]
        return results

    # parse command output with "|" column separators and "-" row separators
    def parse_cmd_result_with_separators(self, lines):
        headers = self.parse_headers_line_with_separators(lines[1])
        # remove line with headers and formatting lines above it and below it
        del lines[:3]
        # remove formatting line in the end
        lines.pop()
        results = [self.parse_content_line_with_separators(line, headers)
                   for line in lines]
        return results

    # parse a line with columns separated by whitespace
    def parse_line_with_ws(self, line, headers):
        s = line if isinstance(line, str) else self.binary2str(line)
        parts = [word.strip() for word in s.split() if word.strip()]
        ret = {}
        for i, p in enumerate(parts):
            header = headers[i]
            ret[header] = p
        return ret

    # parse a line with "|" column separators
    def parse_line_with_separators(self, line):
        s = self.binary2str(line)
        parts = [word.strip() for word in s.split("|") if word.strip()]
        # remove the ID field
        del parts[:1]
        return parts

    def parse_headers_line_with_separators(self, line):
        return self.parse_line_with_separators(line)

    def parse_content_line_with_separators(self, line, headers):
        content_parts = self.parse_line_with_separators(line)
        content = {}
        for i in range(0, len(content_parts)):
            content[headers[i]] = content_parts[i]
        return content

    @staticmethod
    def merge_ws_spillover_lines(lines):
        # with WS-separated output, extra output sometimes spills to next line
        # detect that and add to the end of the previous line for our procesing
        pending_line = None
        fixed_lines = []
        # remove headers line
        for l in lines:
            if l[0] == '\t':
                # this is a spill-over line
                if pending_line:
                    # add this line to the end of the previous line
                    pending_line = pending_line.strip() + "," + l.strip()
            else:
                # add the previous pending line to the fixed lines list
                if pending_line:
                    fixed_lines.append(pending_line)
                # make current line the pending line
                pending_line = l
        if pending_line:
            fixed_lines.append(pending_line)
        return fixed_lines

    """
    given output lines from CLI command like 'ip -d link show',
    find lines belonging to section describing a specific interface
    parameters:
    - lines: list of strings, output of command
    - header_regexp: regexp marking the start of the section
    - end_regexp: regexp marking the end of the section
    """
    @staticmethod
    def get_section_lines(lines, header_regexp, end_regexp):
        if not lines:
            return []
        header_re = re.compile(header_regexp)
        start_pos = None
        # find start_pos of section
        line_count = len(lines)
        for line_num in range(0, line_count-1):
            matches = header_re.match(lines[line_num])
            if matches:
                start_pos = line_num
                break
        if not start_pos:
            return []
        # find end of section
        end_pos = line_count
        end_re = re.compile(end_regexp)
        for line_num in range(start_pos+1, end_pos-1):
            matches = end_re.match(lines[line_num])
            if matches:
                end_pos = line_num
                break
        return lines[start_pos:end_pos]

    def get_object_data(self, o, lines, regexps):
        """
        find object data in output lines from CLI command
        parameters:
        - o: object (dict), to which we'll add attributes with the data found
        - lines: list of strings
        - regexps: dict, keys are attribute names, values are regexp to match
                    for finding the value of the attribute
        """
        for line in lines:
            self.find_matching_regexps(o, line, regexps)
        for regexp_tuple in regexps:
            name = regexp_tuple['name']
            if 'name' not in o and 'default' in regexp_tuple:
                o[name] = regexp_tuple['default']

    @staticmethod
    def find_matching_regexps(o, line, regexps):
        for regexp_tuple in regexps:
            name = regexp_tuple['name']
            regex = regexp_tuple['re']
            regex = re.compile(regex)
            matches = regex.search(line)
            if matches and name not in o:
                o[name] = matches.group(1)
예제 #13
0
class InventoryMgr(MongoAccess, metaclass=Singleton):
    def __init__(self):
        super().__init__()
        self.log = ConsoleLogger()
        self.inventory_collection = None
        self.inventory_collection_name = None
        self.collections = {}
        self.monitoring_setup_manager = None

    def set_collection(self,
                       collection_type: str = None,
                       use_default_name: bool = False):
        # do not allow setting the collection more than once
        if not self.collections.get(collection_type):
            collection_name = collection_type \
                              if use_default_name \
                              else self.get_coll_name(collection_type)

            self.log.info("Using {} collection: {}".format(
                collection_type, collection_name))

            self.collections[collection_type] = MongoAccess.db[collection_name]

    def set_inventory_collection(self, collection_name: str = None):
        if not self.inventory_collection:
            if not collection_name:
                collection_name = "inventory"

            self.log.info(
                "Using inventory collection: {}".format(collection_name))

            collection = MongoAccess.db[collection_name]
            self.collections["inventory"] = collection
            self.inventory_collection = collection
            self.inventory_collection_name = collection_name

    def get_coll_name(self, coll_name):
        if not self.inventory_collection_name:
            raise TypeError("inventory_collection_name is not set")

        return self.inventory_collection_name.replace("inventory", coll_name) \
            if self.inventory_collection_name.startswith("inventory") \
            else self.inventory_collection_name + "_" + coll_name

    def set_collections(self, inventory_collection: str = None):
        self.set_inventory_collection(inventory_collection)
        self.set_collection("links")
        self.set_collection("link_types")
        self.set_collection("clique_types")
        self.set_collection("clique_constraints")
        self.set_collection("cliques")
        self.set_collection("monitoring_config")
        self.set_collection("scans")
        self.set_collection("messages")
        self.set_collection("environments_config")
        self.set_collection("supported_environments")
        self.set_collection("connection_tests")
        self.set_collection("constants", use_default_name=True)
        self.set_collection("monitoring_config_templates",
                            use_default_name=True)
        self.set_collection("api_tokens", use_default_name=True)

    def clear(self, scan_plan):
        if scan_plan.inventory_only:
            collections = {"inventory"}
        elif scan_plan.links_only:
            collections = {"links"}
        elif scan_plan.cliques_only:
            collections = {"cliques"}
        else:
            collections = {
                "inventory", "links", "cliques", "monitoring_config"
            }

        env_cond = {} if scan_plan.clear_all else {
            "environment": scan_plan.env
        }

        for collection_name in collections:
            collection = self.collections[collection_name]
            self.log.info("clearing collection: " + collection.full_name)
            # delete docs from the collection,
            # either all or just for the specified environment
            collection.delete_many(env_cond)

    # return single match
    def get_by_id(self, environment, item_id):
        return self.find({
            "environment": environment,
            "id": item_id
        },
                         get_single=True)

    # return matches for ID in list of values
    def get_by_ids(self, environment, ids_list):
        return self.find({"environment": environment, "id": {"$in": ids_list}})

    def get_by_field(self,
                     environment,
                     item_type,
                     field_name,
                     field_value,
                     get_single=False):
        if field_value:
            return self.find(
                {
                    "environment": environment,
                    "type": item_type,
                    field_name: field_value
                },
                get_single=get_single)
        else:
            return self.find({
                "environment": environment,
                "type": item_type
            },
                             get_single=get_single)

    def get(self, environment, item_type, item_id, get_single=False):
        return self.get_by_field(environment,
                                 item_type,
                                 "id",
                                 item_id,
                                 get_single=get_single)

    def get_children(self, environment, item_type, parent_id):
        if parent_id:
            if not item_type:
                return self.find({
                    "environment": environment,
                    "parent_id": parent_id
                })
            else:
                return self.find({
                    "environment": environment,
                    "type": item_type,
                    "parent_id": parent_id
                })
        else:
            return self.find({"environment": environment, "type": item_type})

    def get_single(self, environment, item_type, item_id):
        matches = self.find({
            "environment": environment,
            "type": item_type,
            "id": item_id
        })
        if len(matches) > 1:
            raise ValueError("Found multiple matches for item: " + "type=" +
                             item_type + ", id=" + item_id)
        if len(matches) == 0:
            raise ValueError("No matches for item: " + "type=" + item_type +
                             ", id=" + item_id)
        return matches[0]

    # item must contain properties 'environment', 'type' and 'id'
    def set(self, item, collection=None):
        col = collection
        mongo_id = None
        projects = None
        if "_id" in item:
            mongo_id = item.pop("_id", None)

        if not collection or collection == self.collections['inventory']:
            # make sure we have environment, type & id
            self.check(item, "environment")
            self.check(item, "type")
            self.check(item, "id")

            item["last_scanned"] = datetime.now()
            item.pop("projects", [])

            obj_name = item["name_path"]
            obj_name = obj_name[obj_name.rindex('/') + 1:]

            if 'object_name' not in item:
                item['object_name'] = obj_name

            self.set_collections()  # make sure we have all collections set
            if not col:
                col = self.collections['inventory']

            find_tuple = {
                "environment": item["environment"],
                "type": item["type"],
                "id": item["id"]
            }
        else:
            find_tuple = {'_id': bson.ObjectId(mongo_id)}
            doc = col.find_one(find_tuple)
            if not doc:
                raise ValueError('set(): could not find document with _id=' +
                                 mongo_id)

        col.update_one(find_tuple, {'$set': self.encode_mongo_keys(item)},
                       upsert=True)
        if mongo_id:
            # restore original mongo ID of document, in case we need to use it
            item['_id'] = mongo_id
        if projects:
            col.update_one(find_tuple,
                           {'$addToSet': {
                               "projects": {
                                   '$each': projects
                               }
                           }},
                           upsert=True)

    @staticmethod
    def check(obj, field_name):
        arg = obj[field_name]
        if not arg or not str(arg).rstrip():
            raise ValueError("Inventory item - " +
                             "the following field is not defined: " +
                             field_name)

    # note: to use general find, call find_items(),
    # which also does process_results
    @inv_initialization_required
    def find(self, search, projection=None, collection=None, get_single=False):
        coll = self.inventory_collection if not collection \
            else self.collections[collection]
        if get_single is True:
            return self.decode_object_id(
                self.decode_mongo_keys(
                    coll.find_one(search, projection=projection)))
        else:
            return list(
                map(
                    self.decode_object_id,
                    map(self.decode_mongo_keys,
                        coll.find(search, projection=projection))))

    def find_one(self, search, projection=None, collection=None) -> dict:
        return self.find(search, projection, collection, True)

    def find_items(self,
                   search,
                   projection=None,
                   get_single=False,
                   collection=None):
        return self.find(search, projection, collection, get_single)

    # record a link between objects in the inventory, to be used in graphs
    # returns - the new link document
    # parameters -
    # environment: name of environment
    # host: name of host
    # source: node mongo _id
    # source_id: node id value of source node
    # target: node mongo _id
    # target_id: node id value of target node
    # link_type: string showing types of connected objects, e.g. "instance-vnic"
    # link_name: label for the link itself
    # state: up/down
    # link_weight: integer, position/priority for graph placement
    # source_label, target_label: labels for the ends of the link (optional)
    def create_link(self,
                    env,
                    src,
                    source_id,
                    target,
                    target_id,
                    link_type,
                    link_name,
                    state,
                    link_weight,
                    source_label="",
                    target_label="",
                    host=None,
                    switch=None,
                    extra_attributes=None):
        s = bson.ObjectId(src)
        t = bson.ObjectId(target)
        link = {
            "environment": env,
            "source": s,
            "source_id": source_id,
            "target": t,
            "target_id": target_id,
            "link_type": link_type,
            "link_name": link_name,
            "state": state,
            "link_weight": link_weight,
            "source_label": source_label,
            "target_label": target_label,
            "attributes": extra_attributes if extra_attributes else {}
        }
        if host:
            link['host'] = host
        if switch:
            link['switch'] = switch
        return self.write_link(link)

    def write_link(self, link):
        find_tuple = {
            'environment': link['environment'],
            'source_id': link['source_id'],
            'target_id': link['target_id']
        }
        if "_id" in link:
            link.pop("_id", None)
        link_encoded = self.encode_mongo_keys(link)
        links_col = self.collections["links"]
        result = links_col.update_one(find_tuple, {'$set': link_encoded},
                                      upsert=True)
        link['_id'] = result.upserted_id
        return link

    def values_replace_in_object(self, o, values_replacement):
        for k in values_replacement.keys():
            if k not in o:
                continue
            repl = values_replacement[k]
            if 'from' not in repl or 'to' not in repl:
                continue
            o[k] = o[k].replace(repl['from'], repl['to'])
            self.set(o)

    # perform replacement of substring in values of objects in the inventory
    # input:
    # - search: dict with search parameters
    # - values_replacement: dict,
    #     - keys: names of keys for which to replace the values
    #     - values: dict with "from" (value to be replaced) and "to" (new value)
    @inv_initialization_required
    def values_replace(self, search, values_replacement):
        for doc in self.inventory_collection.find(search):
            self.values_replace_in_object(doc, values_replacement)

    def delete(self, coll, query_filter):
        collection = self.collections[coll]
        if not collection:
            self.log.warn('delete(): collection not found - ' + coll)
            return
        result = collection.delete_many(query_filter)
        count = result.deleted_count
        self.log.info('delete(): ' +
                      ('deleted ' + str(count) +
                       ' documents' if count else 'no matching documents'))
        return count

    def get_env_config(self, env: str):
        return self.find_one(search={'name': env},
                             collection='environments_config')

    def is_feature_supported(self, env: str, feature: EnvironmentFeatures)\
            -> bool:
        env_config = self.get_env_config(env)
        if not env_config:
            return False

        # Workaround for mechanism_drivers field type
        mechanism_driver = env_config['mechanism_drivers'][0] \
            if isinstance(env_config['mechanism_drivers'], list) \
            else env_config['mechanism_drivers']

        full_env = {
            'environment.distribution': env_config['distribution'],
            'environment.distribution_version': {
                "$in": [env_config['distribution_version']]
            },
            'environment.type_drivers': env_config['type_drivers'],
            'environment.mechanism_drivers': mechanism_driver
        }
        return self.is_feature_supported_in_env(full_env, feature)

    def is_feature_supported_in_env(self, env_def: dict,
                                    feature: EnvironmentFeatures) -> bool:

        result = self.collections['supported_environments'].find_one(env_def)
        if not result:
            return False
        features_in_env = result.get('features', {})
        return features_in_env.get(feature.value) is True

    def save_inventory_object(self, o: dict, parent: dict,
                              environment: str, type_to_fetch: dict = None) \
            -> bool:
        if not type_to_fetch:
            type_to_fetch = {}

        o["id"] = str(o["id"])
        o["environment"] = environment
        if type_to_fetch.get("type"):
            o["type"] = type_to_fetch["type"]
        o["show_in_tree"] = type_to_fetch.get("show_in_tree", True)

        parent_id_path = parent.get("id_path", "/{}".format(environment))
        parent_name_path = parent.get("name_path", "/{}".format(environment))

        try:
            # case of dynamic folder added by need
            master_parent_type = o["master_parent_type"]
            master_parent_id = o["master_parent_id"]
            master_parent = self.get_by_id(environment, master_parent_id)
            if not master_parent:
                self.log.error("failed to find master parent " +
                               master_parent_id)
                return False
            folder_id_path = "/".join(
                (master_parent["id_path"], o["parent_id"]))
            folder_name_path = "/".join(
                (master_parent["name_path"], o["parent_text"]))
            folder = {
                "environment": parent["environment"],
                "parent_id": master_parent_id,
                "parent_type": master_parent_type,
                "id": o["parent_id"],
                "id_path": folder_id_path,
                "show_in_tree": True,
                "name_path": folder_name_path,
                "name": o["parent_id"],
                "type": o["parent_type"],
                "text": o["parent_text"]
            }
            # remove master_parent_type & master_parent_id after use,
            # as they're there just ro help create the dynamic folder
            o.pop("master_parent_type", True)
            o.pop("master_parent_id", True)
            self.set(folder)
        except KeyError:
            pass

        if o.get("text"):
            o["name"] = o["text"]
        elif not o.get("name"):
            o["name"] = o["id"]

        if "parent_id" not in o and parent:
            parent_id = parent["id"]
            o["parent_id"] = parent_id
            o["parent_type"] = parent["type"]
        elif "parent_id" in o and o["parent_id"] != parent["id"]:
            # using alternate parent - fetch parent path from inventory
            parent_obj = self.get_by_id(environment, o["parent_id"])
            if parent_obj:
                parent_id_path = parent_obj["id_path"]
                parent_name_path = parent_obj["name_path"]
        o["id_path"] = "/".join((parent_id_path, o["id"].strip()))
        o["name_path"] = "/".join((parent_name_path, o["name"]))

        # keep list of projects that an object is in
        associated_projects = []
        keys_to_remove = []
        for k in o:
            if k.startswith("in_project-"):
                proj_name = k[k.index('-') + 1:]
                associated_projects.append(proj_name)
                keys_to_remove.append(k)
        for k in keys_to_remove:
            o.pop(k)
        if len(associated_projects) > 0:
            projects = o["projects"] if "projects" in o.keys() else []
            projects.extend(associated_projects)
            if projects:
                o["projects"] = projects

        if "create_object" not in o or o["create_object"]:
            # add/update object in DB
            self.set(o)
            if self.is_feature_supported(environment,
                                         EnvironmentFeatures.MONITORING):
                self.monitoring_setup_manager.create_setup(o)
        return True
예제 #14
0
 def __init__(self):
     super().__init__()
     self.log_file = os.path.join(FileLogger.LOG_DIRECTORY,
                                  self.LOG_FILENAME)
     self.log = ConsoleLogger(level=Logger.INFO)
예제 #15
0
    def __init__(self):
        self._logger = ConsoleLogger()

        self._droid = sl4a.Android()
예제 #16
0
class MusicAgent(TopicAgent):
    def __init__(self, messenger):
        super(MusicAgent,
              self).__init__(messenger=messenger,
                             name=NAME,
                             comparison_commands=COMPARISON_COMMANDS)

        self._logger = ConsoleLogger()
        self._player = None

        self._messenger.register_callback(self.process)

    def _get_url(self, title):
        # based on https://github.com/dashvinsingh/YoutubeAudio-Python-Stream/blob/master/youtube_stream.py
        query = urllib.parse.quote(title)
        url = "https://www.youtube.com/results?search_query=" + query
        response = urllib.request.urlopen(url)
        sleep(1)
        html = response.read()

        try:
            soup = BeautifulSoup(html, 'lxml')
            video_urls = soup.findAll(attrs={'class': 'yt-uix-tile-link'})
            video_url = 'https://www.youtube.com' + video_urls[0]['href']
        except IndexError:
            return self._get_url(title)

        video = pafy.new(video_url)
        best = video.getbestaudio()
        playurl = best.url
        return playurl

    def _play_audio_from_url(self, url):
        Instance = vlc.Instance()
        self._player = Instance.media_player_new()
        Media = Instance.media_new(url)
        Media.get_mrl()
        self._player.set_media(Media)
        self._player.play()
        while self._player and not self._player.is_playing():
            sleep(0.2)
        while self._player is not None and self._player.is_playing():
            sleep(1)

    def _play_audio(self, title):
        self._logger.info('play entered')
        if self._player and self._player.is_playing():
            self._stop_audio()

        url = self._get_url(title)

        playing_thread = Thread(target=self._play_audio_from_url, args=[url])
        playing_thread.start()

    def _pause_audio(self):
        print('pause entered')
        if self._player is not None:
            self._player.pause()

    def _stop_audio(self):
        self._logger.info('stop entered')
        if self._player is not None:
            self._player.stop()
            self._player = None

    def _resume_audio(self):
        self._logger.info('resume entered')
        if self._player is not None:
            self._player.pause()

    def _raise_volume(self):
        self._logger.info('raise volume entered')
        if self._player is not None:
            volume = self._player.audio_get_volume()
            raised_volume = max(volume + 10, 100)
            self._player.audio_set_volume(raised_volume)

    def _lower_volume(self):
        self._logger.info('lower volume entered')
        if self._player is not None:
            volume = self._player.audio_get_volume()
            raised_volume = min(volume - 10, 0)
            self._player.audio_set_volume(raised_volume)

    def process(self, command):
        if 'play' in command:
            # TODO: Use more elaborate nlp
            title = command.split("play")[-1]
            self._play_audio(title)
        elif 'pause' in command:
            self._pause_audio()
        elif 'resume' in command:
            self._resume_audio()
        elif 'stop' in command:
            self._stop_audio()
        elif 'raise' in command:
            self._raise_volume()
        elif 'lower' in command:
            self._raise_volume()

        return ''

    def run(self):
        self._messenger.start_listening()

    def stop(self):
        self._messenger.stop_listening()