def download(self, folder=None): folder = folder or get_skills_folder() if self.download_url.endswith(".tar.gz"): ext = "tar.gz" elif "zipball" in self.download_url: ext = "zip" else: ext = self.download_url.split(".")[-1] file = self.skill_folder + "." + ext url = self.download_url return install_skill(url, folder, file, session=requests, skill_folder_name=self.uuid)
def get_local_skills(parse_github: bool = False, skiplist: Optional[list] = None): try: skills = get_skills_folder() except FileNotFoundError: return except KeyError: # TODO: Patching config error in ovos_utils return skiplist = skiplist or [] folders = listdir(skills) for fold in folders: path = join(skills, fold) if not isdir(path) or fold in skiplist: continue skill_dir = join(skills, fold) skill = get_skill_data_from_directory(skill_dir) yield SkillEntry.from_json(skill, parse_github=parse_github)
def download(self, folder: str = None) -> bool: folder = folder or get_skills_folder() if self.download_url.endswith(".tar.gz"): ext = "tar.gz" elif "zipball" in self.download_url: ext = "zip" else: ext = self.download_url.split(".")[-1] file = self.skill_folder + "." + ext url = self.download_url skill_dirname = self.uuid if not skill_dirname: raise SkillEntryError( f"OSM installation of {self.skill_name or 'unknown skill'} failed!" f" uuid was not defined.") return install_skill(url, folder, file, session=requests, skill_folder_name=skill_dirname)
def __init__(self, platform='default', old_skills_dir=None, skills_dir=None, repo=None, versioned=True): self.platform = platform # Keep this variable alive for a while, is used to move skills from the # old config based location to XDG self.old_skills_dir = path.expanduser(old_skills_dir or '') or None self.skills_dir = (skills_dir or get_skills_folder()) self.repo = repo or SkillRepo() self.versioned = versioned self.lock = MsmProcessLock() # Property placeholders self._all_skills = None self._default_skills = None self._local_skills = None self._device_skill_state = None self.saving_handled = False self.device_skill_state_hash = '' with self.lock: self._init_skills_data()
def get_local_skills(parse_github=False, skiplist=None): skills = get_skills_folder() skiplist = skiplist or [] folders = listdir(skills) for fold in folders: path = join(skills, fold) if not isdir(path) or fold in skiplist: continue skill = { "appstore": "InstalledSkills", "appstore_url": skills, "skill_id": fold, "foldername": fold, "requirements": { "python": [], "system": [], "skill": [] } } # if installed by msm/osm will obey this convention if "." in fold: try: repo, author = fold.split(".") skill["skillname"] = repo skill["authorname"] = author skill["url"] = f'https://github.com/{author}/{repo}' except: # TODO replace with some clever check ? pass # parse git info gitinfo = join(path, ".git/config") if isfile(gitinfo): with open(gitinfo) as f: for l in f.readlines(): if l.strip().startswith("url ="): skill["url"] = l.split("url =")[-1].strip() skill["authorname"], skill["skillname"] = \ author_repo_from_github_url(skill["url"]) if l.strip().startswith("[branch "): skill["branch"] = l.split("branch")[-1]\ .replace('"', "").strip() for rtdir, foldrs, files in walk(join(skills, fold)): for f in files: if f in GITHUB_JSON_FILES: with open(join(rtdir, f)) as fi: skill_meta = json.load(fi) skill = merge_dict(skill, skill_meta, merge_lists=True) elif f in GITHUB_README_FILES: with open(join(rtdir, f)) as fi: readme = readme_to_json(fi.read()) skill = merge_dict(skill, readme, new_only=True, merge_lists=True) elif f in GITHUB_DESKTOP_FILES: skill['desktopFile'] = True elif f in GITHUB_ICON_FILES: skill["icon"] = join(rtdir, f) elif f in GITHUB_LICENSE_FILES: with open(join(rtdir, f)) as fi: lic = fi.read() skill["license"] = parse_license_type(lic) elif f in GITHUB_LOGO_FILES: skill["logo"] = join(rtdir, f) elif f in GITHUB_MANIFEST_FILES: with open(join(rtdir, f)) as fi: manifest = validate_manifest(fi.read()) skill["requirements"]["python"] += manifest.get( "python") or [] skill["requirements"]["system"] += manifest.get( "system") or [] skill["requirements"]["skill"] += manifest.get( "skill") or [] elif f in GITHUB_REQUIREMENTS_FILES: with open(join(rtdir, f)) as fi: reqs = [r for r in fi.read().split("\n") if r.strip()] skill["requirements"]["python"] += reqs elif f in GITHUB_SKILL_REQUIREMENTS_FILES: with open(join(rtdir, f)) as fi: reqs = [r for r in fi.read().split("\n") if r.strip()] skill["requirements"]["skill"] += reqs yield SkillEntry.from_json(skill, parse_github=parse_github)
def is_previously_installed(self, folder=None): folder = folder or get_skills_folder() return isdir(join(folder, self.uuid))
def is_previously_installed(self, folder=None): folder = folder or get_skills_folder() # TODO If self.uuid is None, this skill entry is somehow malformed, # probably because it was created manually with partial input. # Something should happen in this case, but what? return isdir(join(folder, self.uuid)) if self.uuid else False
def install(self, folder: Optional[str] = None, default_branch: str = "master", platform: Optional[str] = None, update: bool = True) -> bool: if not folder: folder = get_skills_folder() if not update and self.is_previously_installed(folder): return False if self.branch_overrides: try: platform = platform or detect_enclosure() except Exception as e: LOG.error("Failed to detect platform") raise e if platform in self.branch_overrides: branch = self.branch_overrides[platform] if branch != self.branch: LOG.info("Detected platform specific branch:" + branch) skill = SkillEntry.from_github_url(self.url, branch) return skill.install(folder, default_branch) LOG.info("Installing skill: {url} from branch: {branch}".format( url=self.url, branch=self.branch)) skills = self.requirements.get("skill", []) if skills: LOG.info('Installing required skills') for s in skills: skill = SkillEntry.from_github_url(s) skill.install(folder, default_branch) system = self.requirements.get("system") if system: LOG.info('Installing system requirements') install_system_deps(system) pyth = self.requirements.get("python") if pyth: LOG.info('Running pip install') pip_install(pyth) LOG.info("Downloading " + self.url) updated = self.download(folder) # TODO: desktop file generation has been disabled for the time being ''' if self.json.get("desktopFile"): LOG.info("Creating desktop entry") # TODO support system wide? /usr/local/XXX ? desktop_dir = expanduser("~/.local/share/applications") icon_dir = expanduser("~/.local/share/icons") # ensure directories exist if not exists(desktop_dir): mkdir(desktop_dir) if not exists(icon_dir): mkdir(icon_dir) # copy the files to a unique path, this way duplicate file names # dont overwrite each other, eg, several skills with "icon.png" base_name = ".".join([self.skill_folder, self.skill_author]).lower() # copy icon file icon_file = join(icon_dir, base_name + "." + self.skill_icon.split(".")[-1]) if self.skill_icon.startswith("http"): content = requests.get(self.skill_icon).content with open(icon_file, "wb") as f: f.write(content) elif isfile(self.skill_icon): shutil.copyfile(self.skill_icon, icon_file) # copy .desktop file desktop_file = join(desktop_dir, base_name + ".desktop") with open(desktop_file, "w") as f: f.write(self.desktop_file) ''' return updated