Exemplo n.º 1
0
def watch_skills():
    global ws, loaded_skills, last_modified_skill, skills_directories, \
        id_counter, prioritary_skills
    # load prioritary skills first
    for p_skill in prioritary_skills:
        if p_skill not in loaded_skills:
            loaded_skills[p_skill] = {}
            skill = loaded_skills.get(p_skill)
            skill["path"] = os.path.join(os.path.dirname(__file__), p_skill)
            if not MainModule + ".py" in os.listdir(skill["path"]):
                logger.error(p_skill + " does not appear to be a skill")
                sys.exit(1)
            skill["loaded"] = True
            skill["instance"] = load_skill(
                create_skill_descriptor(skill["path"]), ws)

    while True:
        for dir in skills_directories:
            if exists(dir):
                list = sorted(
                    filter(lambda x: os.path.isdir(os.path.join(dir, x)),
                           os.listdir(dir)))
                for skill_folder in list:
                    if skill_folder not in loaded_skills:
                        loaded_skills[skill_folder] = {}
                    skill = loaded_skills.get(skill_folder)
                    skill["path"] = os.path.join(dir, skill_folder)
                    if not MainModule + ".py" in os.listdir(skill["path"]):
                        continue
                    skill["last_modified"] = max(
                        os.path.getmtime(root)
                        for root, _, _ in os.walk(skill["path"]))
                    modified = skill.get("last_modified", 0)
                    if skill.get("loaded") and modified <= last_modified_skill:
                        continue
                    elif skill.get(
                            "instance") and modified > last_modified_skill:
                        if not skill["instance"].reload_skill:
                            continue
                        logger.debug("Reloading Skill: " + skill_folder)
                        skill["instance"].shutdown()
                        clear_skill_events(skill["instance"])
                        del skill["instance"]
                    skill["loaded"] = True
                    skill["instance"] = load_skill(
                        create_skill_descriptor(skill["path"]), ws)
        last_modified_skill = max(
            map(lambda x: x.get("last_modified"), loaded_skills.values()))
        time.sleep(2)
Exemplo n.º 2
0
 def try_load_skill(self):
     if self.enable_intent_skill:
         intent_skill = create_intent_skill()
         intent_skill.bind(self.ws)
         intent_skill.initialize()
     skill_descriptor = create_skill_descriptor(self.dir)
     load_skill(skill_descriptor, self.ws)
Exemplo n.º 3
0
 def test_load_skill(self):
     """ Verify skill load function. """
     e_path = join(dirname(__file__), 'test_skill')
     s = load_skill(create_skill_descriptor(e_path), MockEmitter(), 847)
     self.assertEquals(s._dir, e_path)
     self.assertEquals(s.skill_id, 847)
     self.assertEquals(s.name, 'LoadTestSkill')
Exemplo n.º 4
0
 def try_load_skill(self):
     if self.enable_intent_skill:
         intent_skill = create_intent_skill()
         intent_skill.bind(self.client)
         intent_skill.initialize()
     skill_descriptor = create_skill_descriptor(self.skill_directory)
     load_skill(skill_descriptor, self.client)
Exemplo n.º 5
0
 def test_load_skill(self):
     """ Verify skill load function. """
     e_path = join(dirname(__file__), 'test_skill')
     s = load_skill(create_skill_descriptor(e_path), MockEmitter(), 847)
     self.assertEquals(s._dir, e_path)
     self.assertEquals(s.skill_id, 847)
     self.assertEquals(s.name, 'LoadTestSkill')
Exemplo n.º 6
0
 def try_load_skill(self):
     if self.enable_intent_skill:
         intent_skill = create_intent_skill()
         intent_skill.bind(self.client)
         intent_skill.initialize()
     skill_descriptor = create_skill_descriptor(self.skill_directory)
     load_skill(skill_descriptor, self.client)
Exemplo n.º 7
0
 def try_load_skill(self):
     if self.enable_intent_skill:
         intent_skill = create_intent_skill()
         intent_skill.bind(self.ws)
         intent_skill.initialize()
     skill_descriptor = create_skill_descriptor(self.dir)
     load_skill(skill_descriptor, self.ws)
Exemplo n.º 8
0
def load_skill_list(skills_to_load):
    """
        load list of specific skills.

        Args:
            skills_to_load (list): list of skill directories to load
    """
    if exists(SKILLS_DIR):
        # checking skills dir and getting all priority skills there
        skill_list = [folder for folder in filter(
            lambda x: os.path.isdir(os.path.join(SKILLS_DIR, x)),
            os.listdir(SKILLS_DIR)) if folder in skills_to_load]
        for skill_folder in skill_list:
            skill = {"id": hash(os.path.join(SKILLS_DIR, skill_folder))}
            skill["path"] = os.path.join(SKILLS_DIR, skill_folder)
            # checking if is a skill
            if not MainModule + ".py" in os.listdir(skill["path"]):
                continue
            # getting the newest modified date of skill
            last_mod = _get_last_modified_date(skill["path"])
            skill["last_modified"] = last_mod
            # loading skill
            skill["loaded"] = True
            skill["instance"] = load_skill(
                create_skill_descriptor(skill["path"]),
                ws, skill["id"])
            loaded_skills[skill_folder] = skill
Exemplo n.º 9
0
    def _load_or_reload_skill(self, skill_folder):
        """
            Check if unloaded skill or changed skill needs reloading
            and perform loading if necessary.
        """
        if skill_folder not in self.loaded_skills:
            self.loaded_skills[skill_folder] = {
                "id": hash(os.path.join(SKILLS_DIR, skill_folder))
            }
        skill = self.loaded_skills.get(skill_folder)
        skill["path"] = os.path.join(SKILLS_DIR, skill_folder)

        # check if folder is a skill (must have __init__.py)
        if not MainModule + ".py" in os.listdir(skill["path"]):
            return

        # getting the newest modified date of skill
        modified = _get_last_modified_date(skill["path"])
        last_mod = skill.get("last_modified", 0)

        # checking if skill is loaded and hasn't been modified on disk
        if skill.get("loaded") and modified <= last_mod:
            return  # Nothing to do!

        # check if skill was modified
        elif skill.get("instance") and modified > last_mod:
            # check if skill has been blocked from reloading
            if not skill["instance"].reload_skill:
                return

            LOG.debug("Reloading Skill: " + skill_folder)
            # removing listeners and stopping threads
            skill["instance"].shutdown()

            if DEBUG:
                gc.collect()  # Collect garbage to remove false references
                # Remove two local references that are known
                refs = sys.getrefcount(skill["instance"]) - 2
                if refs > 0:
                    LOG.warning("After shutdown of {} there are still "
                                "{} references remaining. The skill "
                                "won't be cleaned from memory.".format(
                                    skill['instance'].name, refs))
            del skill["instance"]

        # (Re)load the skill from disk
        with self.__msm_lock:  # Make sure msm isn't running
            skill["loaded"] = True
            desc = create_skill_descriptor(skill["path"])
            skill["instance"] = load_skill(desc, self.ws, skill["id"],
                                           BLACKLISTED_SKILLS)
            skill["last_modified"] = modified
            if skill and skill['instance']:
                ws.emit(
                    Message('mycroft.skills.loaded', {
                        'id': skill['id'],
                        'name': skill['instance'].name
                    }))
Exemplo n.º 10
0
    def _get_skill_descriptor(skills_folder):
        if not isdir(skills_folder):
            return
        if MainModule + ".py" in os.listdir(skills_folder):
            skills.append(create_skill_descriptor(skills_folder))
            return

        possible_skills = os.listdir(skills_folder)
        for i in possible_skills:
            _get_skill_descriptor(join(skills_folder, i))
Exemplo n.º 11
0
    def _get_skill_descriptor(skills_folder):
        if not isdir(skills_folder):
            return
        if MainModule + ".py" in os.listdir(skills_folder):
            skills.append(create_skill_descriptor(skills_folder))
            return

        possible_skills = os.listdir(skills_folder)
        for i in possible_skills:
            _get_skill_descriptor(join(skills_folder, i))
Exemplo n.º 12
0
def get_skills(skills_folder):
    skills = []
    possible_skills = os.listdir(skills_folder)
    for i in possible_skills:
        location = join(skills_folder, i)
        if (isdir(location)
                and not MainModule + ".py" in os.listdir(location)):
            for j in os.listdir(location):
                name = join(location, j)
                if (not isdir(name)
                        or not MainModule + ".py" in os.listdir(name)):
                    continue
                skills.append(create_skill_descriptor(name))
        if (not isdir(location)
                or not MainModule + ".py" in os.listdir(location)):
            continue

        skills.append(create_skill_descriptor(location))
    skills = sorted(skills, key=lambda p: p.get('name'))
    return skills
Exemplo n.º 13
0
def get_skills(skills_folder):
    skills = []
    possible_skills = os.listdir(skills_folder)
    for i in possible_skills:
        location = join(skills_folder, i)
        if (isdir(location) and
                not MainModule + ".py" in os.listdir(location)):
            for j in os.listdir(location):
                name = join(location, j)
                if (not isdir(name) or
                        not MainModule + ".py" in os.listdir(name)):
                    continue
                skills.append(create_skill_descriptor(name))
        if (not isdir(location) or
                not MainModule + ".py" in os.listdir(location)):
            continue

        skills.append(create_skill_descriptor(location))
    skills = sorted(skills, key=lambda p: p.get('name'))
    return skills
Exemplo n.º 14
0
    def _load_or_reload_skill(self, skill_folder):
        """
            Check if unloaded skill or changed skill needs reloading
            and perform loading if necessary.
        """
        if skill_folder not in self.loaded_skills:
            self.loaded_skills[skill_folder] = {
                "id": hash(os.path.join(SKILLS_DIR, skill_folder))
            }
        skill = self.loaded_skills.get(skill_folder)
        skill["path"] = os.path.join(SKILLS_DIR, skill_folder)

        # check if folder is a skill (must have __init__.py)
        if not MainModule + ".py" in os.listdir(skill["path"]):
            return

        # getting the newest modified date of skill
        modified = _get_last_modified_date(skill["path"])
        last_mod = skill.get("last_modified", 0)

        # checking if skill is loaded and wasn't modified
        if skill.get("loaded") and modified <= last_mod:
            return

        # check if skill was modified
        elif skill.get("instance") and modified > last_mod:
            # check if skill is allowed to reloaded
            if not skill["instance"].reload_skill:
                return
            LOG.debug("Reloading Skill: " + skill_folder)
            # removing listeners and stopping threads
            skill["instance"].shutdown()

            # Remove two local references that are known
            refs = sys.getrefcount(skill["instance"]) - 2
            if refs > 0:
                LOG.warning(
                    "After shutdown of {} there are still "
                    "{} references remaining. The skill "
                    "won't be cleaned from memory."
                    .format(skill['instance'].name, refs))
            del skill["instance"]

        # (Re)load the skill from disk
        with self.__msm_lock:  # Make sure msm isn't running
            skill["loaded"] = True
            desc = create_skill_descriptor(skill["path"])
            skill["instance"] = load_skill(desc,
                                           self.ws, skill["id"],
                                           BLACKLISTED_SKILLS)
            skill["last_modified"] = modified
Exemplo n.º 15
0
def _watch_skills():
    global ws, loaded_skills, last_modified_skill, \
        id_counter

    # Scan the file folder that contains Skills.  If a Skill is updated,
    # unload the existing version from memory and reload from the disk.
    while True:
        if exists(SKILLS_DIR):
            # checking skills dir and getting all skills there
            list = filter(lambda x: os.path.isdir(
                os.path.join(SKILLS_DIR, x)), os.listdir(SKILLS_DIR))

            for skill_folder in list:
                if skill_folder not in loaded_skills:
                    loaded_skills[skill_folder] = {}
                skill = loaded_skills.get(skill_folder)
                skill["path"] = os.path.join(SKILLS_DIR, skill_folder)
                # checking if is a skill
                if not MainModule + ".py" in os.listdir(skill["path"]):
                    continue
                # getting the newest modified date of skill
                skill["last_modified"] = _get_last_modified_date(skill["path"])
                modified = skill.get("last_modified", 0)
                # checking if skill is loaded and wasn't modified
                if skill.get(
                        "loaded") and modified <= last_modified_skill:
                    continue
                # checking if skill was modified
                elif skill.get(
                        "instance") and modified > last_modified_skill:
                    # checking if skill should be reloaded
                    if not skill["instance"].reload_skill:
                        continue
                    logger.debug("Reloading Skill: " + skill_folder)
                    # removing listeners and stopping threads
                    skill["instance"].shutdown()
                    del skill["instance"]
                skill["loaded"] = True
                skill["instance"] = load_skill(
                    create_skill_descriptor(skill["path"]), ws)
        # get the last modified skill
        modified_dates = map(lambda x: x.get("last_modified"),
                             loaded_skills.values())
        if len(modified_dates) > 0:
            last_modified_skill = max(modified_dates)

        # Pause briefly before beginning next scan
        time.sleep(2)
Exemplo n.º 16
0
def _watch_skills():
    global ws, loaded_skills, last_modified_skill, \
        id_counter

    # Scan the file folder that contains Skills.  If a Skill is updated,
    # unload the existing version from memory and reload from the disk.
    while True:
        if exists(SKILLS_DIR):
            # checking skills dir and getting all skills there
            list = filter(lambda x: os.path.isdir(
                os.path.join(SKILLS_DIR, x)), os.listdir(SKILLS_DIR))

            for skill_folder in list:
                if skill_folder not in loaded_skills:
                    loaded_skills[skill_folder] = {}
                skill = loaded_skills.get(skill_folder)
                skill["path"] = os.path.join(SKILLS_DIR, skill_folder)
                # checking if is a skill
                if not MainModule + ".py" in os.listdir(skill["path"]):
                    continue
                # getting the newest modified date of skill
                skill["last_modified"] = _get_last_modified_date(skill["path"])
                modified = skill.get("last_modified", 0)
                # checking if skill is loaded and wasn't modified
                if skill.get(
                        "loaded") and modified <= last_modified_skill:
                    continue
                # checking if skill was modified
                elif skill.get(
                        "instance") and modified > last_modified_skill:
                    # checking if skill should be reloaded
                    if not skill["instance"].reload_skill:
                        continue
                    logger.debug("Reloading Skill: " + skill_folder)
                    # removing listeners and stopping threads
                    skill["instance"].shutdown()
                    del skill["instance"]
                skill["loaded"] = True
                skill["instance"] = load_skill(
                    create_skill_descriptor(skill["path"]), ws)
        # get the last modified skill
        modified_dates = map(lambda x: x.get("last_modified"),
                             loaded_skills.values())
        if len(modified_dates) > 0:
            last_modified_skill = max(modified_dates)

        # Pause briefly before beginning next scan
        time.sleep(2)
Exemplo n.º 17
0
    def _load_or_reload_skill(self, skill_path):
        """
            Check if unloaded skill or changed skill needs reloading
            and perform loading if necessary.

            Returns True if the skill was loaded/reloaded
        """
        skill_path = skill_path.rstrip('/')
        skill = self.loaded_skills.setdefault(skill_path, {})
        skill.update({"id": basename(skill_path), "path": skill_path})

        # check if folder is a skill (must have __init__.py)
        if not MainModule + ".py" in os.listdir(skill_path):
            return False

        # getting the newest modified date of skill
        modified = _get_last_modified_date(skill_path)
        last_mod = skill.get("last_modified", 0)

        # checking if skill is loaded and hasn't been modified on disk
        if skill.get("loaded") and modified <= last_mod:
            return False  # Nothing to do!

        # check if skill was modified
        elif skill.get("instance") and modified > last_mod:
            # check if skill has been blocked from reloading
            if not skill["instance"].reload_skill:
                return False

            LOG.debug("Reloading Skill: " + basename(skill_path))
            # removing listeners and stopping threads
            try:
                skill["instance"]._shutdown()
            except Exception:
                LOG.exception("An error occured while shutting down {}".format(
                    skill["instance"].name))

            if DEBUG:
                gc.collect()  # Collect garbage to remove false references
                # Remove two local references that are known
                refs = sys.getrefcount(skill["instance"]) - 2
                if refs > 0:
                    msg = ("After shutdown of {} there are still "
                           "{} references remaining. The skill "
                           "won't be cleaned from memory.")
                    LOG.warning(msg.format(skill['instance'].name, refs))
            del skill["instance"]
            self.ws.emit(
                Message("mycroft.skills.shutdown", {
                    "path": skill_path,
                    "id": skill["id"]
                }))

        skill["loaded"] = True
        desc = create_skill_descriptor(skill_path)
        skill["instance"] = load_skill(desc, self.ws, skill["id"],
                                       BLACKLISTED_SKILLS)
        skill["last_modified"] = modified
        if skill['instance'] is not None:
            self.ws.emit(
                Message(
                    'mycroft.skills.loaded', {
                        'path': skill_path,
                        'id': skill['id'],
                        'name': skill['instance'].name,
                        'modified': modified
                    }))
            return True
        else:
            self.ws.emit(
                Message('mycroft.skills.loading_failure', {
                    'path': skill_path,
                    'id': skill['id']
                }))
        return False
Exemplo n.º 18
0
    def load_skill(self):
        if self.enable_intent:
            IntentService(self.ws)

        skill_descriptor = create_skill_descriptor(self.dir)
        self.skill = load_skill(skill_descriptor, self.ws, hash(self.dir))
Exemplo n.º 19
0
    def load_skill(self):
        if self.enable_intent:
            IntentService(self.ws)

        skill_descriptor = create_skill_descriptor(self.dir)
        self.skill = load_skill(skill_descriptor, self.ws, hash(self.dir))
Exemplo n.º 20
0
    def _load_or_reload_skill(self, skill_folder):
        """
            Check if unloaded skill or changed skill needs reloading
            and perform loading if necessary.
        """
        if skill_folder not in self.loaded_skills:
            self.loaded_skills[skill_folder] = {
                "id": hash(os.path.join(SKILLS_DIR, skill_folder))
            }
        skill = self.loaded_skills.get(skill_folder)
        skill["path"] = os.path.join(SKILLS_DIR, skill_folder)

        # check if folder is a skill (must have __init__.py)
        if not MainModule + ".py" in os.listdir(skill["path"]):
            return

        # getting the newest modified date of skill
        modified = _get_last_modified_date(skill["path"])
        last_mod = skill.get("last_modified", 0)

        # checking if skill is loaded and hasn't been modified on disk
        if skill.get("loaded") and modified <= last_mod:
            return  # Nothing to do!

        # check if skill was modified
        elif skill.get("instance") and modified > last_mod:
            # check if skill has been blocked from reloading
            if not skill["instance"].reload_skill:
                return

            LOG.debug("Reloading Skill: " + skill_folder)
            # removing listeners and stopping threads
            skill["instance"].shutdown()

            if DEBUG:
                gc.collect()  # Collect garbage to remove false references
                # Remove two local references that are known
                refs = sys.getrefcount(skill["instance"]) - 2
                if refs > 0:
                    LOG.warning(
                        "After shutdown of {} there are still "
                        "{} references remaining. The skill "
                        "won't be cleaned from memory."
                        .format(skill['instance'].name, refs))
            del skill["instance"]
            self.ws.emit(Message("mycroft.skills.shutdown",
                                 {"folder": skill_folder,
                                  "id": skill["id"]}))

        # (Re)load the skill from disk
        with self.__msm_lock:  # Make sure msm isn't running
            skill["loaded"] = True
            desc = create_skill_descriptor(skill["path"])
            skill["instance"] = load_skill(desc,
                                           self.ws, skill["id"],
                                           BLACKLISTED_SKILLS)
            skill["last_modified"] = modified
            if skill['instance'] is not None:
                self.ws.emit(Message('mycroft.skills.loaded',
                                     {'folder': skill_folder,
                                      'id': skill['id'],
                                      'name': skill['instance'].name,
                                      'modified': modified}))
            else:
                self.ws.emit(Message('mycroft.skills.loading_failure',
                                     {'folder': skill_folder,
                                      'id': skill['id']}))
Exemplo n.º 21
0
    def run(self):
        global ws, loaded_skills, last_modified_skill

        # Load priority skills first by order
        load_skill_list(PRIORITY_SKILLS)
        self._loaded_priority.set()

        # Scan the file folder that contains Skills.  If a Skill is updated,
        # unload the existing version from memory and reload from the disk.
        while not self._stop_event.is_set():
            if exists(SKILLS_DIR):
                # checking skills dir and getting all skills there
                list = filter(lambda x: os.path.isdir(
                    os.path.join(SKILLS_DIR, x)), os.listdir(SKILLS_DIR))

                for skill_folder in list:
                    if skill_folder not in loaded_skills:
                        loaded_skills[skill_folder] = {
                            "id": hash(os.path.join(SKILLS_DIR, skill_folder))
                        }
                    skill = loaded_skills.get(skill_folder)
                    skill["path"] = os.path.join(SKILLS_DIR, skill_folder)
                    # checking if is a skill
                    if not MainModule + ".py" in os.listdir(skill["path"]):
                        continue
                    # getting the newest modified date of skill
                    last_mod = _get_last_modified_date(skill["path"])
                    skill["last_modified"] = last_mod
                    modified = skill.get("last_modified", 0)
                    # checking if skill is loaded and wasn't modified
                    if skill.get(
                            "loaded") and modified <= last_modified_skill:
                        continue
                    # checking if skill was modified
                    elif (skill.get("instance") and modified >
                            last_modified_skill):
                        # checking if skill should be reloaded
                        if not skill["instance"].reload_skill:
                            continue
                        LOG.debug("Reloading Skill: " + skill_folder)
                        # removing listeners and stopping threads
                        skill["instance"].shutdown()

                        # -2 since two local references that are known
                        refs = sys.getrefcount(skill["instance"]) - 2
                        if refs > 0:
                            LOG.warning(
                                "After shutdown of {} there are still "
                                "{} references remaining. The skill "
                                "won't be cleaned from memory."
                                .format(skill['instance'].name, refs))
                        del skill["instance"]
                    skill["loaded"] = True
                    skill["instance"] = load_skill(
                        create_skill_descriptor(skill["path"]),
                        ws, skill["id"],
                        BLACKLISTED_SKILLS)
            # get the last modified skill
            modified_dates = map(lambda x: x.get("last_modified"),
                                 loaded_skills.values())
            if len(modified_dates) > 0:
                last_modified_skill = max(modified_dates)

            if not self._loaded_once.is_set():
                self._loaded_once.set()
            # Pause briefly before beginning next scan
            time.sleep(2)