222 lines
7.0 KiB
Bash
Executable File
222 lines
7.0 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Copyright 2016 Mycroft AI, Inc.
|
|
#
|
|
# This file is part of Mycroft Core.
|
|
#
|
|
# 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.
|
|
#
|
|
# 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 <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
# @author Augusto Monteiro
|
|
#
|
|
# This script assists in the installation and management of
|
|
# skills loaded from Github.
|
|
|
|
mycroft_skill_folder=${mycroft_skill_folder:-"/opt/mycroft/skills"}
|
|
if [[ ! -d "${mycroft_skill_folder}" ]] ; then
|
|
echo "Unable to access ${mycroft_skill_folder}!"
|
|
exit 101
|
|
fi
|
|
|
|
# picroft?
|
|
if [[ "$(hostname)" == 'picroft' ]] || [[ -x /home/pi/bin/cli ]] ; then
|
|
picroft='true'
|
|
else
|
|
picroft='false'
|
|
if [[ -r /etc/bash_completion.d/virtualenvwrapper ]]; then
|
|
source /etc/bash_completion.d/virtualenvwrapper
|
|
else
|
|
if locate virtualenvwrapper ; then
|
|
if ! source $(locate virtualenvwrapper) ; then
|
|
echo "Unable to locate virtualenvwrapper.sh, will not be able to install skills!"
|
|
vwrap='false'
|
|
fi
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
default_skills="skill-alarm skill-audio-record skill-configuration skill-date-time skill-desktop-launcher skill-ip skill-joke skill-hello-world skill-media skill-npr-news skill-naptime skill-pairing skill-personal skill-reminder skill-installer skill-singing skill-speak skill-spelling skill-stop skill-stock skill-volume skill-weather skill-wiki skill-wolfram-alpha skill-mark1-demo"
|
|
|
|
echo "####### Mycroft Skill Manager #######"
|
|
|
|
function help() {
|
|
echo "msm: Mycroft Skill Manager"
|
|
echo -e " Copyright (c) 2017 Mycroft AI, Inc. All rights reserved.\n"
|
|
echo "usage: msm install <repository> or <name>"
|
|
echo " Installs the given Skill into the ${mycroft_skill_folder}"
|
|
echo " where <repository> is the address of the skill in Github."
|
|
echo "example: msm search rss-skill"
|
|
echo -e "example: msm install https://github.com/ethanaward/demo_skill.git\n"
|
|
exit 1
|
|
}
|
|
|
|
function list() {
|
|
if hash curl ; then
|
|
if ! curl -s "https://raw.githubusercontent.com/MycroftAI/mycroft-skills/master/.gitmodules" ; then
|
|
echo "Unable to pull master skills list!"
|
|
exit 111
|
|
fi
|
|
else
|
|
if ! wget -qO- "https://raw.githubusercontent.com/MycroftAI/mycroft-skills/master/.gitmodules" ; then
|
|
echo "Unable to pull master skills list!"
|
|
exit 112
|
|
fi
|
|
fi
|
|
}
|
|
|
|
function install() {
|
|
cd "${mycroft_skill_folder}"
|
|
if [[ "${vwrap}" == 'false' ]] ; then
|
|
echo "Missing virtualwrapper, cowardly refusing to install skills."
|
|
return 5
|
|
fi
|
|
# loop through list of arguments
|
|
while [[ $# -gt 0 ]] ; do
|
|
cd "${mycroft_skill_folder}"
|
|
iskill="${1}";
|
|
shift;
|
|
echo "Attempting to install ${iskill}..."
|
|
if [[ "${iskill}" == "git@"* || "${iskill}" == "https://"* || "${iskill}" == "http://"* ]]; then
|
|
repo="${iskill}"
|
|
else
|
|
skills=$(list | grep -n 'submodule' | sed 's/[[:space:]]//g' | sed 's/\[submodule"//g' | sed 's/"\]//g')
|
|
exact_match=$(echo "$skills" | grep -i ".*:${iskill}$")
|
|
skill=$(echo "$skills" | grep -i ".*:.*${iskill}.*")
|
|
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'
|
|
return 3
|
|
else
|
|
if [[ -z "${git_line}" ]]; then
|
|
echo "A ${iskill} skill was not found"
|
|
return 3
|
|
fi
|
|
repo_line=$(($git_line + 2))
|
|
repo=$(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//')
|
|
if [[ -d "${mycroft_skill_folder}/${name}" ]] ; then
|
|
echo "Skill appears to exist already. Perhaps you meant to use update?"
|
|
continue 169
|
|
fi
|
|
echo "Cloning repository"
|
|
git clone "${repo}" >> /dev/null
|
|
if ! cd "${name}" ; then
|
|
echo "Unable to access directory ${name}!"
|
|
return 102
|
|
fi
|
|
if [[ "${picroft}" == "true" ]] ; then
|
|
if ! sudo chown -R mycroft:mycroft "${mycroft_skill_folder}/${name}" ; then
|
|
echo "Unable to chown install directory ${name}!"
|
|
return 123
|
|
fi
|
|
fi
|
|
if [[ -f "requirements.txt" ]]; then
|
|
echo "Installing libraries requirements"
|
|
if [[ "${picroft}" == 'false' ]]; then
|
|
if [[ "${VIRTUAL_ENV}" =~ .mycroft$ ]] ; then
|
|
if ! pip install -r requirements.txt ; then
|
|
echo "Unable to install requirements for skill ${iskill}!"
|
|
return 121
|
|
fi
|
|
else
|
|
if workon mycroft ; then
|
|
if ! pip install -r requirements.txt ; then
|
|
echo "Unable to install requirements for skill ${iskill}!"
|
|
deactivate mycroft
|
|
return 121
|
|
fi
|
|
else
|
|
echo "Unable to activate mycroft virtualenv!"
|
|
deactivate
|
|
return 120
|
|
fi
|
|
fi
|
|
else
|
|
if ! sudo pip install -r requirements.txt ; then
|
|
echo "Unable to install requirements for skill ${iskill}!"
|
|
return 121
|
|
fi
|
|
fi
|
|
fi
|
|
echo "The ${iskill} skill has been installed!"
|
|
done
|
|
|
|
}
|
|
|
|
function update() {
|
|
cd "${mycroft_skill_folder}"
|
|
for d in $(find "${mycroft_skill_folder}" -mindepth 1 -maxdepth 1 -type d |grep -v '.git'$ ); do
|
|
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")
|
|
|
|
if ! grep -q '.pyc'$ .git/info/exclude; then
|
|
echo "*.pyc" >> .git/info/exclude
|
|
fi
|
|
|
|
# Checking if the repo isn't dirty or have commits to push
|
|
if [[ (-z $(git status --porcelain --untracked-files=no)) && !($LOCAL != $REMOTE && $REMOTE = $BASE) ]]; then
|
|
git fetch
|
|
git reset --hard origin/master
|
|
rm -f *.pyc
|
|
fi
|
|
fi
|
|
done
|
|
}
|
|
|
|
function search() {
|
|
search_list=$(list | grep 'submodule "' | sed 's/\[submodule "//g'| sed 's/"\]//g')
|
|
while [[ $# -gt 0 ]] ; do
|
|
search_string=$1
|
|
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}")
|
|
done
|
|
}
|
|
|
|
|
|
#### Main
|
|
|
|
OPT=$1
|
|
shift
|
|
case ${OPT} in
|
|
"install") if [[ $# -gt 0 ]] ; then install $(echo "$*") ; else help ; fi;;
|
|
"list") list | grep 'submodule "' | sed 's/\[submodule "//g'| sed 's/"\]//g' ;;
|
|
"update") update ;;
|
|
"default") install $(echo ${default_skills}) ;;
|
|
"search") if [[ $# -gt 0 ]] ; then search $(echo "$*") ; else help ; fi;;
|
|
*) help ;;
|
|
esac
|
|
|
|
exit_code=$?
|
|
if [[ ${exit_code} -gt 0 ]] ; then
|
|
echo "Sorry I'm unable to complete the request! Check the error messages above for why. Err ${exit_code}"
|
|
fi
|
|
exit 0
|