Example #1
0
 def install_skill(self, skill: SkillEntry, folder=None):
     """
     Installs a SkillEntry with any required auth_token
     :param skill: Skill to install
     :param folder: Skills directory to install to (skill unpacked to {folder}/{skill.uuid})
     """
     self.emit("osm.install.start", {"folder": folder, "skill": skill.json})
     store = None
     try:
         self.validate_appstore_name(skill.appstore)
         store = self.get_appstore(skill.appstore)
         store.authenticate(bootstrap=False)
     except Exception as e:
         LOG.error(e)
         self.emit("osm.install.error", {
             "folder": folder,
             "skill": skill.json,
             "error": str(e)
         })
     try:
         skill.install(folder)
     except Exception as e:
         LOG.error(e)
         self.emit("osm.install.error", {
             "folder": folder,
             "skill": skill.json,
             "error": str(e)
         })
     if store:
         store.clear_authentication()
     self.emit("osm.install.finish", {
         "folder": folder,
         "skill": skill.json
     })
Example #2
0
 def search_skills_by_tag(self,
                          tag,
                          as_json=False,
                          fuzzy=True,
                          thresh=0.85,
                          ignore_case=True):
     query = Query(self.db)
     query.contains_value('tags', tag, fuzzy, thresh, ignore_case)
     results = query.result
     for idx in range(0, len(results)):
         if "appstore" not in results[idx]:
             results[idx]["appstore"] = self.appstore_id
     if as_json:
         return query.result
     return [SkillEntry.from_json(s, False) for s in results]
 def search_skills_by_description(self,
                                  value,
                                  as_json: bool = False,
                                  fuzzy: bool = True,
                                  thresh=0.85,
                                  ignore_case: bool = True):
     query = Query(self.db)
     query.value_contains_token('description', value, fuzzy, thresh,
                                ignore_case)
     results = query.result
     for idx in range(0, len(results)):
         if "appstore" not in results[idx]:
             results[idx]["appstore"] = self.appstore_id
     if as_json:
         return query.result
     return [SkillEntry.from_json(s, False) for s in results]
 def search_skills_by_author(self,
                             authorname: str,
                             as_json=False,
                             fuzzy=True,
                             thresh: float = 0.85,
                             ignore_case=True):
     query = Query(self.db)
     query.value_contains_token('authorname', authorname, fuzzy, thresh,
                                ignore_case)
     results = query.result
     for idx in range(0, len(results)):
         if "appstore" not in results[idx]:
             results[idx]["appstore"] = self.appstore_id
     if as_json:
         return query.result
     return [SkillEntry.from_json(s, False) for s in results]
def install(method: str, skill: str, fuzzy: bool, no_ignore_case: bool,
            thresh: float, appstore: str, search: bool, branch: str,
            folder: str):
    if search:
        skills = search_skill(method, skill, fuzzy, no_ignore_case, thresh,
                              appstore)
    elif not skill.startswith("http"):
        click.confirm('{s} does not look like a valid skill url, do you '
                      'want to enable search?'.format(s=skill),
                      abort=True)
        skills = search_skill(method, skill, fuzzy, no_ignore_case, thresh,
                              appstore)
    else:
        skills = [SkillEntry.from_github_url(skill, branch)]

    if not len(skills):
        click.echo("NO RESULTS")
    else:
        # ask option
        prompt = "\nSearch Results:\n    appstore - branch - url \n"
        opts = {}
        for s in skills:
            idx = len(opts) + 1
            prompt += str(idx) + " - " + s.appstore + " - " + s.branch + " " +\
                      s.url + "\n"
            opts[idx] = s
        prompt += "0 - cancel installation\n"

        def ask_selection():
            click.echo(prompt)
            value = click.prompt('Select an option', type=int)
            if value < 0 or value > len(opts):
                click.echo("Invalid choice")
                return ask_selection()
            return value

        value = ask_selection()
        if value == 0:
            click.echo("Installation cancelled")
            return
        skill = opts[value]
        skill_str = skill.branch + " " + skill.url
        click.confirm('Do you want to install {s} ?'.format(s=skill_str),
                      abort=True)
        skill.install(folder)
Example #6
0
 def search_skills_by_url(self, url, as_json=False):
     query = Query(self.db)
     try:
         # if branch implicit in url, be sure to use it!
         branch = get_branch_from_github_url(url)
     except GithubInvalidBranch:
         branch = None
     url = normalize_github_url(url)
     query.equal("url", url, ignore_case=True)
     results = query.result
     for idx in range(0, len(results)):
         if "appstore" not in results[idx]:
             results[idx]["appstore"] = self.appstore_id
         if branch:
             # TODO what if branch does not exist? should throw exception
             results[idx]["branch"] = branch
     if as_json:
         return query.result
     return [SkillEntry.from_json(s, parse_github=False) for s in results]
Example #7
0
    def search_skills_by_id(self,
                            skill_id,
                            as_json=False,
                            fuzzy=False,
                            thresh=0.85,
                            ignore_case=True):
        """ skill_id is repo.author , case insensitive,
        searchs by name and filters results by author """
        name = ".".join(skill_id.split(".")[:-1])
        author = skill_id.rsplit('.', 1)[1]

        query = Query(self.db)
        query.contains_value('skillname', name, fuzzy, thresh, ignore_case)
        query.value_contains_token('authorname', author, fuzzy, thresh,
                                   ignore_case)
        results = query.result
        for idx in range(0, len(results)):
            if "appstore" not in results[idx]:
                results[idx]["appstore"] = self.appstore_id

        if as_json:
            return query.result
        return [SkillEntry.from_json(s, False) for s in results]
Example #8
0
def get_andlos_list_skills(parse_github: bool = False, skiplist=None):
    skiplist = skiplist or []
    url = "https://raw.githubusercontent.com/andlo/mycroft-skills-list-gitbook/master/_data/skills.json"
    andlos_list = requests.get(url).json()
    for idx, skill in enumerate(andlos_list):
        LOG.debug("Parsing skill {i} out of {n}".format(i=idx,
                                                        n=len(andlos_list)))
        s = skill['skill_info']
        if s['repo'] in skiplist:
            continue
        cats = [s for s in s['categories'] if len(s) > 2]
        cat = cats[0] if len(cats) else None
        tags = list(set(s['tags'] + cats))
        license = skill.get('license') or {}
        data = {
            "created": skill['created_at'],
            'archived': skill['archived'],
            "license": license.get("key"),
            'modified': skill['updated_at'],
            "authorname": s['github_username'],
            "skillname": s['name'],
            "foldername": s['id'],
            "name": s['name'],
            "url": s['repo'],
            'category': cat,
            "description": s['description'],
            "short_description": s['short_desc'],
            "branch": s['branch'],
            "examples": s['examples'],
            'tags': tags,
            'platforms': s['platforms'],
            'stars': skill['stargazers_count']
        }
        try:
            yield SkillEntry.from_json(data, parse_github)
        except GithubInvalidUrl:
            LOG.error("this skill does not seem to be valid! " + s['repo'])
Example #9
0
 def skill_entry_from_url(url: str):
     """
     Builds a minimal SkillEntry object from the passed GitHub URL to use for skill installation
     :param url: URL of skill to install
     :return: SkillEntry object with url, branch, requirements, and authorname populated
     """
     from ovos_skills_manager.exceptions import GithubInvalidBranch, GithubFileNotFound
     from ovos_skills_manager.github import get_branch_from_github_url, normalize_github_url, get_requirements_json,\
         get_skill_json
     from ovos_skills_manager.skill_entry import SkillEntry
     try:
         branch = get_branch_from_github_url(url)
     except GithubInvalidBranch:
         branch = None
     url = normalize_github_url(url)
     requirements = get_requirements_json(url, branch)
     requirements["system"] = {
         k: v.split()
         for k, v in requirements.get("system", {}).items()
     }
     try:
         json = get_skill_json(url, branch)
         requirements = merge_dict(requirements,
                                   json.get("requirements", {}),
                                   merge_lists=True,
                                   skip_empty=True,
                                   no_dupes=True)
     except GithubFileNotFound:
         json = {"authorname": author_repo_from_github_url(url)[0]}
     return SkillEntry.from_json(
         {
             "url": url,
             "branch": branch,
             "requirements": requirements,
             "authorname": json.get("authorname")
         }, False)
Example #10
0
 def __iter__(self):
     for s in self.db:
         yield SkillEntry.from_json(s, parse_github=False)
from ovos_skills_manager import SkillEntry

# from github url with json available  (all urls work)
url = "https://github.com/JarbasSkills/skill-wolfie/blob/master/__init__.py"
url = "https://github.com/JarbasSkills/skill-wolfie/blob/v0.1/res/desktop/skill.json"
url = "https://raw.githubusercontent.com/JarbasSkills/skill-wolfie/v0.1/res/desktop/skill.json"
url = "https://github.com/JarbasSkills/skill-wolfie"
s = SkillEntry.from_github_url(url)
print(s.json)

# from github url with no .json available
url = "https://github.com/MycroftAI/skill-hello-world"
s = SkillEntry.from_github_url(url)
print(s.json)

# from github url + implicit branch with json available
url = "https://github.com/MycroftAI/skill-hello-world/tree/20.08"
s = SkillEntry.from_github_url(url)
print(s.json)

# parse .json from github url to file (all urls work assuming json in standard location)
url = "https://github.com/JarbasSkills/skill-wolfie/blob/master/__init__.py"
url = "https://github.com/JarbasSkills/skill-wolfie"
url = "https://raw.githubusercontent.com/JarbasSkills/skill-wolfie/v0.1/res/desktop/skill.json"
url = "https://github.com/JarbasSkills/skill-wolfie/blob/v0.1/res/desktop/skill.json"
s = SkillEntry.from_json(url)
print(s.json)

# parse .json from github url to file (json not available)
url = "https://github.com/AIIX/youtube-skill"
s = SkillEntry.from_json(url)
from ovos_skills_manager import SkillEntry

# from github url + implicit branch with json available
url = "https://github.com/MycroftAI/skill-hello-world/tree/20.08"
s = SkillEntry.from_github_url(url)

print(s.generate_readme())

print(s.generate_desktop_file())
Example #13
0
from ovos_skills_manager import SkillEntry

skills_folder = "installed_skills"

# skill requirements, branch not specified  c
url = "https://github.com/JarbasSkills/mycroft-node-red"
s = SkillEntry.from_github_url(url, "master")
updated = s.install(skills_folder)
print("skill updated:", updated)

# from github url + implicit branch with json available
url = "https://github.com/MycroftAI/skill-hello-world/tree/20.08"
s = SkillEntry.from_github_url(url)
updated = s.install(skills_folder)
print("skill updated:", updated)

updated = s.update(skills_folder)
print("skill updated:", updated)

# test requirements.txt
url = "https://github.com/JarbasSkills/skill-wolfie"
s = SkillEntry.from_github_url(url)
updated = s.install(skills_folder)
print("skill updated:", updated)

# test manifest.yml
# NOTE most likely baresip install will fail because it needs sudo
url = "https://github.com/JarbasSkills/skill-voip"
s = SkillEntry.from_github_url(url)
updated = s.install(skills_folder)
print("skill updated:", updated)