diff --git a/plasmoid/contents/code/msm.sh b/plasmoid/contents/code/msm.sh index a21d863..cb60c16 100755 --- a/plasmoid/contents/code/msm.sh +++ b/plasmoid/contents/code/msm.sh @@ -1,122 +1,744 @@ #!/bin/bash -# Copyright 2016 Mycroft AI, Inc. +# Copyright 2017 Mycroft AI Inc. # -# This file is part of Mycroft Core. +# 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 # -# Mycroft Core is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. +# http://www.apache.org/licenses/LICENSE-2.0 # -# Mycroft Core is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Mycroft Core. If not, see . - +# 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. -# @author Augusto Monteiro -# -# This script assists in the installation and management of -# skills loaded from Github. +RED='\033[0;31m' +NOCOLOR='\033[0m' +GREEN='\033[0;32m' -mycroft_skill_folder="/opt/mycroft/skills" -mycroft_virtualenv=~/.virtualenvs/mycroft/bin/activate -echo "####### Mycroft Skill Manager #######" +script=${0} +script=${script##*/} function help() { - echo "msm: Mycroft Skill Manager" - echo -e " Copyright (c) 2017 Mycroft AI, Inc. All rights reserved.\n" - echo "usage: msm install or " - echo " Installs the given Skill into the /opt/mycroft/skills directory" - echo " where is the address of the skill in Github." - echo -e "example: msm install https://github.com/ethanaward/demo_skill.git\n" + echo "${script}: Mycroft Skill Manager" + echo "usage: ${script} [option] [repo | name]" + echo + echo "Options:" + echo " default installs the default skills, updates all others" + echo " install installs from the specified github repo" + echo " install [name...] installs the mycroft-skill matching " + echo " remove [name...] removes the specified github repo" + echo " list list all mycroft-skills" + echo " update update all installed skills" + echo " search search mycroft-skills for match for " + echo " info shows information about the skill matching " + echo " info shows information about the skill in the specified repo" + echo + echo "Params:" + echo " full URL to a Github repo" + echo " one or more substrings to match against submodule names" + echo " in the https://github.com/MycroftAI/mycroft-skills repo" + echo + echo "Examples:" + echo " ${script} search twitter" + echo " ${script} search date-time-skill" + echo " ${script} install \"daily meditation\"" + echo " ${script} remove \"daily meditation\"" + echo " ${script} install https://github.com/penrods/Wink.git" + + exit 1 +} + +# Determine the platform +mycroft_platform="null" +if [[ -r /etc/mycroft/mycroft.conf ]] ; then + mycroft_platform=$( jq -r '.enclosure.platform' /etc/mycroft/mycroft.conf ) +else + if [[ "$(hostname)" == "picroft" ]] ; then + mycroft_platform="picroft" + elif [[ "$(hostname)" =~ "mark_1" ]] ; then + mycroft_platform="mycroft_mark_1" + fi +fi + +# Get the location of the Skill folder +mycroft_skill_folder="null" +if [[ -r /etc/mycroft/mycroft.conf ]] ; then + mycroft_skill_folder=$( jq -r '.enclosure.skill_folder' /etc/mycroft/mycroft.conf ) +fi +if [[ ${mycroft_skill_folder} == "null" ]] ; then + mycroft_skill_folder="/opt/mycroft/skills" +fi + +if [[ ! -d "${mycroft_skill_folder}" ]] ; then + echo "ERROR: Unable to find/access ${mycroft_skill_folder}!" + exit 101 +fi + +# Determine if on picroft/mk1? +picroft_mk1="false" +vwrap="true" +if [[ "${mycroft_platform}" == "picroft" ]] || [[ "${mycroft_platform}" == "mycroft_mark_1" ]] ; then + picroft_mk1="true" +else + if [[ -r /etc/bash_completion.d/virtualenvwrapper ]]; then + source /etc/bash_completion.d/virtualenvwrapper + elif [[ -r /usr/bin/virtualenvwrapper.sh ]]; then + source /usr/bin/virtualenvwrapper.sh + else + if locate virtualenvwrapper ; then + if ! source $(locate virtualenvwrapper) ; then + echo "WARNING: Unable to locate virtualenvwrapper.sh, not able to install skills!" + vwrap="false" + fi + fi + fi +fi + +# Cache to only retrieve list once per MSM invocation +LIST_CACHE='' + +function get_skill_list() { + if ! [[ ${LIST_CACHE} ]] ; then + echo "1" >> ~/count.txt + if hash curl ; then + # retrieve using curl + LIST_CACHE=$( curl -s "https://raw.githubusercontent.com/MycroftAI/mycroft-skills/master/.gitmodules" ) + if ! [[ "${LIST_CACHE}" ]] ; then + return 111 + fi + else + # retrieve using wget + LIST_CACHE=$( wget -qO- "https://raw.githubusercontent.com/MycroftAI/mycroft-skills/master/.gitmodules" ) + if ! [[ "${LIST_CACHE}" ]] ; then + return 112 + fi + fi + fi +} + +# Communicate with mycroft-core to inform it of install status +install_started="false" +update_started="false" +remove_started="false" +function send_start_install () { + if [[ "${install_started}" == "false" ]] ; then + python -m mycroft.messagebus.send msm.installing + install_started="true" + fi +} +function send_start_update () { + if [[ "${update_started}" == "false" ]] ; then + python -m mycroft.messagebus.send msm.updating + update_started="true" + fi +} +function send_start_remove () { + if [[ "${remove_started}" == "false" ]] ; then + python -m mycroft.messagebus.send msm.removing + remove_started="true" + fi +} +function send_install_success () { + python -m mycroft.messagebus.send msm.install.succeeded "{\"skill\": \"${1}\" }" +} +function send_install_fail () { + python -m mycroft.messagebus.send msm.install.failed "{\"skill\": \"${1}\", \"error\" : ${2} }" +} +function send_remove_success () { + python -m mycroft.messagebus.send msm.remove.succeeded "{\"skill\": \"${1}\" }" +} +function send_remove_fail () { + python -m mycroft.messagebus.send msm.remove.failed "{\"skill\": \"${1}\", \"error\" : ${2} }" +} +function send_end_install () { + if [[ "${install_started}" == "true" ]] ; then + python -m mycroft.messagebus.send msm.installed + fi +} +function send_end_update () { + if [[ "${update_started}" == "true" ]] ; then + python -m mycroft.messagebus.send msm.updated + fi +} +function send_end_remove () { + if [[ "${remove_started}" == "true" ]] ; then + python -m mycroft.messagebus.send msm.removed + fi +} + + +function remove() { + str=$* + echo "Searching for '$str'..." + + cd "${mycroft_skill_folder}" + + # NOTE: Using the same process that was used in the install. + # So you can install and remove with partial names. + + # Search for the given word(s) as the submodule + skills=$(echo "${LIST_CACHE}" | grep -n 'submodule' | sed 's/[[:space:]]//g' | sed 's/\[submodule"//g' | sed 's/"\]//g') + + # Test for exact name match + exact_match=$(echo "$skills" | grep -i ".*:${str}$") + if [[ ! -z "${exact_match}" ]]; then + # Found a perfect match! + skill=${exact_match} + else + # Test for match of all supplied words/subwords + skill=$(echo "$skills") # start with all skills + for s in ${str} + do + # whittle list down with each word in the search string + skill=$(echo "$skill" | grep -i ".*:.*${s}.*") + done + fi + + git_line=$(echo "$skill" | sed 's/\:.*//') + if [[ "${skill}" == *$'\n'* ]]; then + # The str matches multiple skill repos, don't install + # due to ambiguity. + # + echo "Multiple matches for '${str}', be more specific." + echo "------------------------------------------------------------" + echo "$skill" | sed 's/.*://g' | sort + echo "------------------------------------------------------------" + return 251 + else + if [[ -z "${git_line}" ]]; then + echo "'${str}' was not found in the mycroft-skills repo" + return 252 + fi + repo_line=$(($git_line + 2)) + repo=$(echo "${LIST_CACHE}" | sed -n $repo_line'{p;q;}' | sed 's/[[:space:]]//g' | sed 's/[[:space:]]//g' | sed 's/url=//g') + fi + + git_name=$(echo "${repo}" | sed 's/.*\///') + name=$(echo "$git_name" | sed 's/.git//') + if [[ -d "${mycroft_skill_folder}/${name}" ]] ; then + # TODO: Build mechanism for removing all requirements.txt + # that are no longer used (e.g. via a master Mycroft list). + + # Delete the skill folder + echo -n "Removing '${name}'..." + send_start_remove + rm -rf "${name}" + if [[ -d "${mycroft_skill_folder}/${name}" ]] ; then + # Failed to remove the skill directory + send_remove_fail "${name}" 249 + return 249 + else + echo "done" + echo "Removed: ${name}" + send_remove_success + return 0 + fi + else + echo "Skill '${name}' has not been installed, nothing to remove." + return 253 + fi } function install() { - cd $mycroft_skill_folder - if [ -z "$2" ]; then - echo "You must pass the git url or skill name" - exit 1 - fi - if [[ "$2" == "git@"* || "$2" == "https://"* || "$2" == "http://"* ]]; then - repo=$2 - else - skill_list="`curl -s "https://raw.githubusercontent.com/MycroftAI/mycroft-skills/master/.gitmodules"`" - skills=`echo "$skill_list" | grep -n 'submodule' | sed 's/[[:space:]]//g' | sed 's/\[submodule"//g' | sed 's/"\]//g'` - exact_match=`echo "$skills" | grep -i ".*:$2$"` - skill=`echo "$skills" | grep -i ".*:.*$2.*"` - if [ ! -z $exact_match ]; then - skill=$exact_match - fi - git_line=`echo "$skill" | sed 's/\:.*//'` - - if [[ $skill == *$'\n'* ]]; then - echo -e "Your search has multiple choices\n\n$skill" | sed 's/.*://g' - exit 2 - else - if [ -z $git_line ]; then - echo "Skill not found" - exit 3 - fi - repo_line=$(($git_line + 2)) - repo=`echo "$skill_list" | sed -n $repo_line'{p;q;}' | sed 's/[[:space:]]//g' | sed 's/url=//g'` - fi - fi - git_name=`echo "$repo" | sed 's/.*\///'` - name=`echo "$git_name" | sed 's/.git//'` - echo "Cloning repository" - git clone $repo >> /dev/null - cd $name - if [ -f "requirements.txt" ]; then - echo "Installing libraries requirements" - pip install -r requirements.txt - fi - echo "Skill installed!" + # This could be either a string or a URL + str=$* + if [[ "${INSTALLING_DEFAULTS}" == "false" ]] ; then + echo "Searching for for '$str'..." + else + echo -n "Searching for for '$str'..." + fi + + # TODO: Allow skipping virtualwrapper with an option? + if [[ "$vwrap" = "false" ]] ; then + echo "ERROR: Missing virtualwrapper, cowardly refusing to install skills" + return 5 + fi + + cd "${mycroft_skill_folder}" + + if [[ "${str}" == "git@"* || "${str}" == "https://"* || "${str}" == "http://"* ]]; then + # Repo was given + repo="${str}" + else + # Search for the given word(s) as the submodule + skills=$(echo "${LIST_CACHE}" | grep -n 'submodule' | sed 's/[[:space:]]//g' | sed 's/\[submodule"//g' | sed 's/"\]//g') + + # Test for exact name match + exact_match=$(echo "$skills" | grep -i ".*:${str}$") + if [[ ! -z "${exact_match}" ]]; then + # Found a perfect match! + skill=${exact_match} + else + # Test for match of all supplied words/subwords + skill=$(echo "$skills") # start with all skills + for s in ${str} + do + # whittle list down with each word in the search string + skill=$(echo "$skill" | grep -i ".*:.*${s}.*") + done + fi + + git_line=$(echo "$skill" | sed 's/\:.*//') + + if [[ "${skill}" == *$'\n'* ]]; then + # The str matches multiple skill repos, don't install + # due to ambiguity. + echo "Multiple matches for '${str}', be more specfic." + echo "------------------------------------------------------------" + echo "$skill" | sed 's/.*://g' | sort + echo "------------------------------------------------------------" + return 201 + else + if [[ -z "${git_line}" ]]; then + echo "'${str}' skill was not found" + return 202 + fi + repo_line=$(($git_line + 2)) + repo=$(echo "${LIST_CACHE}" | sed -n $repo_line'{p;q;}' | sed 's/[[:space:]]//g' | sed 's/[[:space:]]//g' | sed 's/url=//g') + fi + fi + + git_name=$(echo "${repo}" | sed 's/.*\///') + name=$(echo "$git_name" | sed 's/.git//') + if [[ -d "${mycroft_skill_folder}/${name}" ]] ; then + # Don't show message when verify default skills + if [[ "${INSTALLING_DEFAULTS}" == "false" ]] ; then + echo "Skill already installed. Perhaps you meant to use update?" + else + echo "exists" + fi + return 20 + else + echo "installing" + fi + + echo "Installing from: ${repo}" + send_start_install + git clone "${repo}" >> /dev/null + if ! cd "${name}" ; then + echo "ERROR: Unable to access directory ${name}!" + send_install_fail "${name}" 102 + return 102 + fi + if [[ "${picroft_mk1}" == "true" ]] ; then + # Verify skill folder is accessible to the 'mycroft' user + owner=$( stat -c %U "${mycroft_skill_folder}/${name}" ) + group=$( stat -c %G "${mycroft_skill_folder}/${name}" ) + if [[ "${group}" != "mycroft" ]] || [[ "${owner}" != "mycroft" ]] ; then + if ! sudo chown -R mycroft:mycroft "${mycroft_skill_folder}/${name}" ; then + echo "ERROR: Unable to chown install directory ${name}!" + send_install_fail "${name}" 123 + return 123 + fi + fi + fi + + # If the skill has a requirements.txt, pip install them + run_pip "${name}" + rc=$? + if [[ ${rc} -gt 0 ]] ; then + return ${rc} + fi + + # If the skill has a requirements.sh, then run that using bash + if [[ -f "requirements.sh" ]]; then + echo " Setting up native environment..." + if ! bash requirements.sh; then + echo "Running requirements.sh failed!" + send_install_fail "${name}" 122 + return 122 + fi + fi + + echo "Installed: ${name}" + send_install_success "${name}" + return 0 +} + +function run_pip() { + # NOTE: Must be in the skill directory already... + name=$* + if [[ -f "requirements.txt" ]]; then + echo " Installing requirements..." + if [[ "${picroft_mk1}" == "false" ]]; then + if [[ "${VIRTUAL_ENV}" =~ .mycroft$ ]] ; then + if ! pip install -r requirements.txt ; then + echo "ERROR: Unable to install requirements for skill '${name}'" + send_install_fail "${name}" 121 + return 121 + fi + else + if workon mycroft ; then + if ! pip install -r requirements.txt ; then + echo "ERROR: Unable to install requirements for skill '${name}'" + deactivate mycroft + send_install_fail "${name}" 121 + return 121 + fi + else + echo "ERROR: Unable to activate 'mycroft' virtualenv, requirements not installed." + send_install_fail "${name}" 120 + return 120 + fi + fi + else + if ! sudo pip install -r requirements.txt ; then + echo "ERROR: Unable to install requirements for '${name}', it may not work" + send_install_fail "${name}" 121 + return 121 + fi + fi + fi + + return 0 # no problem encountered +} + +function install_from_url_list() { + exit_code=0 + skill_list=$( curl -s "${*}" ) + if [[ $? -gt 0 || $skill_list =~ ^404 ]] ; then + # This is fine, just no list found + return 0 + fi + + # Tell 'for' to only break on newlines, not spaces. The # comment lines + # inside the list can contain spaces in them. + IFS=$'\n' + for name in ${skill_list} + do + if [[ ! $name =~ ^# ]] ; then # ignore comment lines + install $name + rc=$? + if [[ ${rc} -gt 0 ]] ; then + if [[ ${rc} -gt ${exit_code} ]] ; then + # keep the highest exit code + exit_code=${rc} + fi + fi + fi + done + + return ${exit_code} +} + +function search() { + # Find the search string among the skills in the Skill repo + search_list=$(echo "${LIST_CACHE}" | grep 'submodule "' | sed 's/\[submodule "//g'| sed 's/"\]//g') + search_string="$*" + shift + while read -r matches; do + if [[ "${search_string}" == "${matches}" ]] ; then + echo "Exact match found: ${matches}" + else + echo "Possible match: ${matches}" + fi + done < <(grep -i "${search_string}" <<< "${search_list}") } function update() { - cd $mycroft_skill_folder - for d in *; do - if git -C "$d" rev-parse --git-dir > /dev/null 2>&1; then - cd $d - git fetch - git reset --hard origin/master - cd .. - fi - done -} - -function install_defaults() { - skills=( "alarm" "audio-record" "configuration" "date-time" "desktop-launcher" "ip" "joke" "hello-world" "media" "npr-news" "naptime" "pairing" "personal" "reminder" "installer" "speak" "spelling" "stop" "stock" "volume" "weather" "wiki" "wolfram-alpha" ) - for i in "${skills[@]}" - do - if [ ! -d "$mycroft_skill_folder/skill-$i" ]; then - install "" "https://github.com/MycroftAI/skill-$i.git" - fi - done - update - echo "Installed!" -} - -function list() { - curl -s "https://raw.githubusercontent.com/MycroftAI/mycroft-skills/master/.gitmodules" | grep 'submodule "' | sed 's/\[submodule "//g'| sed 's/"\]//g' -} - -if [ "$1" = "install" ]; then - install $* -elif [ "$1" = "list" ]; then - echo -e "Searching...\n" - list -elif [ "$1" = "update" ]; then - update -elif [ "$1" = "default" ]; then - install_defaults -else - help -fi + echo "Updating installed skills..." + cd "${mycroft_skill_folder}" + + # Loop through all of the current Skill folders + for d in $(find "${mycroft_skill_folder}" -mindepth 1 -maxdepth 1 -type d |grep -v '.git'$ ); do + # Go in to all folders that are git checkouts + if git -C "$d" rev-parse --git-dir > /dev/null 2>&1; then + cd "${d}" + UPSTREAM=${1:-'@{u}'} + LOCAL=$(git rev-parse @) + REMOTE=$(git rev-parse "$UPSTREAM") + BASE=$(git merge-base @ "$UPSTREAM") + + # Force ignoring the generated .pyc files + if ! grep -q '.pyc'$ .git/info/exclude; then + echo "*.pyc" >> .git/info/exclude + fi + + BRANCH="$(git symbolic-ref HEAD 2>/dev/null)" + BRANCH="${BRANCH##refs/heads/}" + + # Only update checkouts that have not been modified at all + if [[ (-z $(git status --porcelain --untracked-files=no)) && # No Modified files + !($LOCAL != $REMOTE && $REMOTE = $BASE) && # No new commits + "$BRANCH" = "master" ]] # On master branch + then + echo "Updating ${d}..." + echo -n " " + send_start_update + git fetch + git reset --hard origin/master + rm -f *.pyc + else + echo "Ignoring ${d}, skill has been modified." + fi + + # TODO: Remove this for 18.02 + # HACK: Re-run PIP, because Mycroft-core removed some of its required, + # which broke previously-installed packages on a Picroft/Mark1 + # that was satisfied by packages that previously came along with + # mycroft-core. + if [ ! -f /tmp/mycroft_has_re-PIPed ] ; then + run_pip "${d}" + echo "Re-running PIP on requirements.txt" + fi + fi + done + + # TODO: Remove this for 18.02 + # HACK: Only do the re-PIP once per boot + if [ ! -f /tmp/mycroft_has_re-PIPed ] ; then + echo "1" > /tmp/mycroft_has_re-PIPed + fi +} +function print_info() { + str=$* + if [[ "${str}" == "git@"* || "${str}" == "https://"* || "${str}" == "http://"* ]]; then + # Repo was given + repo="${str}" + else + # Search for the given word(s) as the submodule + skills=$(echo "${LIST_CACHE}" | grep -n 'submodule' | sed 's/[[:space:]]//g' | sed 's/\[submodule"//g' | sed 's/"\]//g') + + # Test for exact name match + exact_match=$(echo "$skills" | grep -i ".*:${str}$") + if [[ ! -z "${exact_match}" ]]; then + # Found a perfect match! + skill=${exact_match} + else + # Test for match of all supplied words/subwords + skill=$(echo "$skills") # start with all skills + for s in ${str} + do + # whittle list down with each word in the search string + skill=$(echo "$skill" | grep -i ".*:.*${s}.*") + done + fi + + git_line=$(echo "$skill" | sed 's/\:.*//') + + if [[ "${skill}" == *$'\n'* ]]; then + # The str matches multiple skill repos, don't install + # due to ambiguity. + echo "Multiple matches for '${str}', be more specfic." + echo "------------------------------------------------------------" + echo "$skill" | sed 's/.*://g' | sort + echo "------------------------------------------------------------" + return 201 + else + if [[ -z "${git_line}" ]]; then + echo "'${str}' skill was not found" + return 202 + fi + repo_line=$(($git_line + 2)) + repo=$(echo "${LIST_CACHE}" | sed -n $repo_line'{p;q;}' | sed 's/[[:space:]]//g' | sed 's/[[:space:]]//g' | sed 's/url=//g') + fi + fi + + local baseUrl=$(echo "${repo}" | sed -e 's/github.com/raw.githubusercontent.com/g' | sed -e 's/\.git$//g')/master + ### debugging output: + # echo git line is: "$git_line" + # echo repo line is: "$repo_line" + # echo repo is: "$repo" + # echo base url is "$baseUrl" + local readmeUrl="$baseUrl/readme.md" + local stat="$(curl -I -s $readmeUrl | sed -n '1p')" + local readme="" + if [[ $stat == *"200"* ]] ; then + readme="$(curl -s $readmeUrl)" + else + readmeUrl="$baseUrl/Readme.md" + stat=$(curl -I -s ${readmeUrl} | sed -n '1p') + if [[ $stat == *"200"* ]] ; then + readme="$(curl -s $readmeUrl)" + else + readmeUrl="$baseUrl/README.md" + stat=$(curl -I -s ${readmeUrl} | sed -n '1p') + if [[ $stat == *"200"* ]] ; then + readme="$(curl -s $readmeUrl)" + else + echo "Didn't find any information to display." + exit 0 + fi + fi + fi + + echo "$readme" + exit 0 +} + +OPT=$1 +shift + + +case ${OPT} in + "install") + if [[ $# -gt 0 ]] ; then + get_skill_list + exit_code=$? + if [[ ${exit_code} -gt 0 ]] ; then + echo "${script}: error ${exit_code}" + exit ${exit_code} + fi + + for str in "$@" + do + install $str + rc=$? + + if [[ ${rc} -gt 0 ]] ; then + if [[ ${rc} -gt ${exit_code} ]] ; then + exit_code=${rc} + fi + fi + done + send_end_install + else + # install requires a parameter, show help + help + exit_code=1 + fi + ;; + "remove") + if [[ $# -gt 0 ]] ; then + get_skill_list + exit_code=$? + if [[ ${exit_code} -gt 0 ]] ; then + echo "${script}: error ${exit_code}" + exit ${exit_code} + fi + + for str in "$@" + do + remove $str + rc=$? + + if [[ ${rc} -gt 0 ]] ; then + if [[ ${rc} -gt ${exit_code} ]] ; then + exit_code=${rc} + fi + fi + done + send_end_remove + else + # remove requires a parameter, show help + help + exit_code=1 + fi + ;; + "list") + get_skill_list + exit_code=$? + if [[ ${exit_code} -gt 0 ]] ; then + echo "${script}: error ${exit_code}" + exit ${exit_code} + fi + + submodules=$(echo "${LIST_CACHE}" | grep 'submodule "' | sed 's/\[submodule "//g'| sed 's/"\]//g' | sort) + while read -r submod + do + if [[ -d "$mycroft_skill_folder/$submod" ]] ; then + printf "$submod ${RED}[${GREEN}installed${RED}]${NOCOLOR}\n\r" + else + printf "$submod\n\r" + fi + done <<< "$submodules" + exit_code=$? + ;; + "update") + get_skill_list + exit_code=$? + if [[ ${exit_code} -gt 0 ]] ; then + echo "${script}: error ${exit_code}" + exit ${exit_code} + fi + + update + send_end_update + exit_code=$? + ;; + "default") + echo "=== Checking for default skills" + INSTALLING_DEFAULTS="true" + get_skill_list + exit_code=$? + if [[ ${exit_code} -gt 0 ]] ; then + echo "${script}: error ${exit_code}" + exit ${exit_code} + fi + + # These skills are automatically installed on all mycroft-core + # installations. + install_from_url_list "https://raw.githubusercontent.com/MycroftAI/mycroft-skills/master/DEFAULT-SKILLS" + exit_code=$? + + # Grab any platform-specific skills + if [[ ${mycroft_platform} != 'null' ]] ; then + if [[ ${exit_code} -eq 0 || ${exit_code} -eq 20 ]] ; then + install_from_url_list "https://raw.githubusercontent.com/MycroftAI/mycroft-skills/master/DEFAULT-SKILLS.${mycroft_platform}" + exit_code=$? + fi + fi + + # exit code 20 == skills already installed, which is OK here + if [[ ${exit_code} -eq 0 || ${exit_code} -eq 20 ]] ; then + update + send_end_update + exit_code=$? + fi + ;; + "search") + if [[ $# -gt 0 ]] ; then + get_skill_list + exit_code=$? + if [[ ${exit_code} -gt 0 ]] ; then + echo "${script}: error ${exit_code}" + exit ${exit_code} + fi + + res="" + for str in "$@" + do + out=$( search ${str} ) + res=$( printf "${out}\n${res}" ) + done + echo "$res" | sort | uniq + exit_code=$? + else + # search requires a parameter, show help + help + exit_code=1 + fi + ;; + "info") + get_skill_list + exit_code=$? + if [[ ${exit_code} -gt 0 ]] ; then + echo "${script}: error ${exit_code}" + exit ${exit_code} + fi + print_info $1 + rc=$? + if [[ ${rc} -gt 0 ]] ; then + if [[ ${rc} -gt ${exit_code} ]] ; then + echo "${script}: error ${exit_code}" + exit_code=${rc} + fi + fi + exit_code=0 + ;; + *) + help + exit_code=0 + ;; +esac + + +if [[ ${exit_code} -gt 0 ]] ; then + echo "${script}: error ${exit_code}" +fi +exit ${exit_code}