def install_from_giturl(self, message):
        git_link = message.data["skillurl"]
        git_branch = message.data["skillbranch"]
        if git_link:
            LOG.info("installing skill" + git_link)
            repo_name = SkillEntry.extract_repo_name(git_link)
            try:
                self.gui['process'] = True
                self.gui['processmessage'] = "installing skill"
                self.msm.install(git_link)
                self.update_home_screen()
                hashomepage = self.check_skill_for_home(git_link)
                if hashomepage:
                    self.check_android_entry_exist_with_home(git_link, message)
                else:
                    self.check_android_entry_exist_without_home(
                        git_link, message)

            except MsmException as e:
                self.gui['process'] = False
                self.gui['processmessage'] = ""
                LOG.info('msm failed: ' + repr(e))

        if git_branch:
            repo_name = SkillEntry.extract_repo_name(git_link)
            repo_author = SkillEntry.extract_author(git_link)
            skill_path = "/opt/mycroft/skills/" + repo_name + "." + repo_author.lower(
            )
            process = subprocess.popen(["git", "checkout", git_branch],
                                       stdout=subprocess.pipe,
                                       cwd=skill_path)
            output = process.communicate()[0]
            LOG.info(output)
Exemple #2
0
    def install_from_giturl(self, message):
        gitLink = message.data["downloadLink"]
        gitBranch = message.data["branch"]
        if gitLink:
            LOG.info("installing skill" + gitLink)
            repo_name = SkillEntry.extract_repo_name(gitLink)
            try:
                self.gui['process'] = True
                self.gui['processMessage'] = "Installing Skill"
                self.msm.install(gitLink)
                self.update_home_screen()
            except MsmException as e:
                self.gui['process'] = False
                self.gui['processMessage'] = ""
                LOG.info('MSM failed: ' + repr(e))

        if gitBranch:
            repo_name = SkillEntry.extract_repo_name(gitLink)
            repo_author = SkillEntry.extract_author(gitLink)
            skill_path = "/opt/mycroft/skills/" + repo_name + "." + repo_author.lower(
            )
            process = subprocess.Popen(["git", "checkout", gitBranch],
                                       stdout=subprocess.PIPE,
                                       cwd=skill_path)
            output = process.communicate()[0]
            LOG.info(output)
Exemple #3
0
def generate_summary(github: Github, skill_entry: SkillEntry):
    author = skill_entry.extract_author(skill_entry.url)
    repo_name = skill_entry.extract_repo_name(skill_entry.url)
    repo_id = '/'.join([author, repo_name])
    repo = github.get_repo(repo_id)  # type: Repository
    readme_file = repo.get_readme()  # type: ContentFile
    readme = readme_file.decoded_content.decode()
    sections = extract_sections(readme)
    title, short_desc = find_title_info(sections, skill_entry.name)

    return {
        'repo':
        repo.html_url,
        'title':
        title,
        'name':
        skill_entry.name,
        'author':
        (find_section('credits', sections, 0.9)
         or find_section('author', sections, 0.9) or caps(skill_entry.author)),
        'github_username':
        skill_entry.author,
        'short_desc':
        format_sent(short_desc.replace('\n', ' ')).rstrip('.'),
        'description':
        format_sent(find_section('description', sections) or ''),
        'examples': [parse_example(i) for i in find_examples(sections)],
        'requires': (find_section('require', sections, 0.9) or '').split(),
        'excludes': (find_section('exclude', sections, 0.9) or '').split()
    }
 def check_android_entry_exist_without_home(self, url, message):
     repo_name = SkillEntry.extract_repo_name(url)
     repo_author = SkillEntry.extract_author(url)
     android_json = "android.json"
     android_path = "/opt/mycroft/skills/" + repo_name + "." + repo_author.lower(
     ) + "/" + android_json
     if not path.exists(android_path) and not path.isfile(android_path):
         LOG.info("Android File Not Exist")
 def check_android_entry_exist_with_home(self, url, message):
     repo_name = SkillEntry.extract_repo_name(url)
     repo_author = SkillEntry.extract_author(url)
     android_json = "android.json"
     android_path = "/opt/mycroft/skills/" + repo_name + "." + repo_author.lower(
     ) + "/" + android_json
     if not path.exists(android_path) and not path.isfile(android_path):
         LOG.info("Android File Does Not Exist Creating Android With Home")
         self.build_android_json_with_home(message.data["skillImage"],
                                           message.data["skillName"],
                                           repo_name, repo_author)
Exemple #6
0
 def checkInstalled(self, url):
     repo_name = SkillEntry.extract_repo_name(url)
     repo_author = SkillEntry.extract_author(url)
     skill_path = "/opt/mycroft/skills/" + repo_name + "." + repo_author.lower(
     )
     LOG.info(skill_path)
     if path.exists(skill_path):
         LOG.info("Found Skill Installed")
         return True
     else:
         LOG.info("Skill Not Installed")
         return False
Exemple #7
0
 def uninstall_from_giturl(self, message):
     gitLink = message.data["downloadLink"]
     if gitLink:
         repo_name = SkillEntry.extract_repo_name(gitLink)
         try:
             self.gui['process'] = True
             self.gui['processMessage'] = "Removing Skill"
             self.msm.remove(gitLink)
             self.update_home_screen()
         except MsmException as e:
             self.gui['process'] = False
             self.gui['processMessage'] = ""
             LOG.info('MSM failed: ' + repr(e))
 def check_skill_for_home(self, url):
     repo_name = SkillEntry.extract_repo_name(url)
     repo_author = SkillEntry.extract_author(url)
     check_file = "/opt/mycroft/skills/" + repo_name + "." + repo_author.lower(
     ) + "/__init__.py"
     LOG.info(check_file)
     home_string = [".home"]
     with open(check_file) as f:
         results = {word: [] for word in home_string}
         for num, line in enumerate(f, start=1):
             for word in home_string:
                 if word in line:
                     LOG.info("Home Entry Found")
                     return True
Exemple #9
0
    def on_web_settings_change(self):
        s = self.settings
        link = s.get('installer_link')
        prev_link = s.get('previous_link')
        auto_install = s.get('auto_install')

        # Check if we should auto-install a skill due to web setting change
        if link and prev_link != link and auto_install:
            s['previous_link'] = link

            self.log.info('Installing from the web...')
            action = self.translate_list('action')[0]
            name = SkillEntry.extract_repo_name(link)
            with self.handle_msm_errors(name, action):
                self.msm.install(link)

        to_install = s.get('to_install', [])
        if isinstance(to_install, str):
            to_install = json.loads(to_install)
        to_remove = s.get('to_remove', [])
        if isinstance(to_remove, str):
            to_remove = json.loads(to_remove)
        self.handle_marketplace(to_install, to_remove)
Exemple #10
0
def skill_repo_name(url: str):
    return '{}/{}'.format(SkillEntry.extract_author(url),
                          SkillEntry.extract_repo_name(url))
 def test_extract_repo_name(self):
     assert SkillEntry.extract_repo_name(self.url) == 'testrepo'
Exemple #12
0
 def install_custom(self, message):
     link = self.settings.get('installer_link')
     if link:
         repo_name = SkillEntry.extract_repo_name(link)
         with self.handle_msm_errors(repo_name, self.install_word):
             self.msm.install(link, origin='')
Exemple #13
0
def generate_summary(github: Github, skill_entry: SkillEntry):
    """
    Generate an entry for a Skill that has been accepted to the
    Mycroft Skills repo (https://github.com/mycroft-skills).

    {
       "mycroft-reminder": {
            # repo url
            "repo": "https://github.com/MycroftAI/skill-reminder",
            # branch of the repo
            "branch": "18.08",
            # Exact commit accepted
            "tree": "https://github.com/MycroftAI/skill-reminder/tree/afb9d3387e782de19fdf2ae9ec6d2e6c83fee48c",
            # name for the folder on disk, e.g. /opt/mycroft/skills/mycroft-reminder.mycroftai
            "name": "mycroft-reminder",
            "github_username": "******",

            # Used in titles and for 'Hey Mycroft, install ...'
            "title": "Set reminders",

            # One of the following two entries
            "icon" : {"name": "info", "color": "#22a7f0" },
            "icon_img" : "https://somewhere.org/picture.png",

            # List of credited contributors.  Some might not have a github_id
            # such as when crediting a song.
            "credits" : [
                {"name": "Mycroft AI", "github_id": "MycroftAI"},
                {"name": "Reminder tone from Tony of Tony's Sounds"}
            ],

            # The tagline description
            "short_desc": "Set single and repeating reminders for tasks",

            # The detailed description.  Can contain markdown
            "description": "Flexible reminder Skill, allowing you to set single and repeating reminders for tasks. The reminders are set on the Device, and have no external dependencies. ",

            # Example phrases.  Order counts, first is most representative.
            "examples": [
                "Set a reminder every day to take my vitamin pill.",
                "Remind me to put the garbage out at 8pm.",
                "Remind me to walk the dog in an hour.",
                "Set a reminder every Friday at 2pm.",
                "Remind me to stretch in 10 minutes."
            ],

            # Categories.  Order counts, first is the primary category.
            "categories": ["Daily","Productivity"],

            # Tags are arbitrary and order has no meaning.
            "tags": ["reminder", "reminders"],

            # Supported platforms by name, or "all"
            "platforms": ["platform_mark1"]
        }
    }
    """
    if github:
        author = skill_entry.extract_author(skill_entry.url)
        repo_name = skill_entry.extract_repo_name(skill_entry.url)
        repo_id = '/'.join([author, repo_name])
        repo = github.get_repo(repo_id)  # type: Repository
        repo_url = repo.html_url
        readme_file = repo.get_readme()  # type: ContentFile
        readme = readme_file.decoded_content.decode()
    else:
        readme = skill_entry.readme
        repo_url = "http://dummy.url"
    sections = extract_sections(readme)
    title, short_desc = find_title_info(sections, skill_entry.name)

    entry = {
        'repo': repo_url,
        # 'branch': "18.08",              # TODO: repo.branch,
        'tree': skill_entry.sha,
        'name': skill_entry.name,
        'github_username': skill_entry.author,

        'title': title,
        'short_desc': format_sentence(short_desc.replace('\n',
                                                         ' ')).rstrip('.'),
        'description': format_sentence(find_section('About', sections) or
                                       find_section('Description', sections) or
                                       ''),

        'examples': [parse_example(i) for i in find_examples(sections)],

        'credits': make_credits((find_section('Credits',
                                              sections, 0.9) or
                                 caps(skill_entry.author))),
        'categories': [
            cat.replace('*', '') for cat in sorted((find_section('Category',
                                                    sections,
                                                    0.9) or '').split())],
        'platforms': (find_section('Supported Devices',
                                   sections, 0.9) or 'all').split(),
        'tags': (find_section('Tags',
                              sections) or '').replace('#', '').split()
    }

    icon_url, icon_name, icon_color = find_icon(sections, repo_url,
                                                skill_entry.sha)
    if icon_url:
        entry["icon_img"] = icon_url
    elif icon_name:
        entry["icon"] = {"icon": icon_name, "color": icon_color}

    return entry