Пример #1
0
 def __init__(self):
     super().__init__('Installed')
     self.coreModDir = Path(get_freecad_resource_path(), 'Mod')
     self.userModDir = get_mod_path()
     self.userMacroDir = get_macro_path()
     self.workbenches = Gui.listWorkbenches()
     self.updates = {}
     self.showCorePackages = True
Пример #2
0
    def getMacroList(self):

        macros = []
        install_dir = get_macro_path()
        default_icon = utils.path_to_url(
            get_resource_path('html', 'img', 'package_macro.svg'))

        try:
            content = http_get(self.url, timeout=45)
            if content:
                data = json.loads(content)
                wiki = get_page_content_from_json(data)

                for m_link in MACRO_LINK.finditer(wiki):

                    name = m_link.group('name').replace(' ', '_')
                    label = m_link.group('label')
                    description = m_link.group('description')

                    icon = m_link.group('icon')
                    if icon:
                        icon = self.wiki + '/Special:Redirect/file/' + icon.replace(
                            ' ', '_')
                    else:
                        icon = default_icon

                    pkg = PackageInfo(
                        key=name,
                        installDir=install_dir,
                        installFile=Path(install_dir, name + '.FCMacro'),
                        name=name,
                        title=label,
                        description=description,
                        icon=icon,
                        isCore=False,
                        type='Macro',
                        isGit=False,
                        isWiki=True,
                        markedAsSafe=False,
                        categories=[tr('Uncategorized')],
                        date=None,
                        version=None,
                        readmeUrl='{0}/Macro_{1}?origin=*'.format(
                            self.wiki, name),
                        readmeFormat='html')
                    flags.apply_predefined_flags(pkg)
                    macros.append(pkg)

        except:
            traceback.print_exc(file=sys.stderr)

        return macros
Пример #3
0
def uninstall_macro(path):
    dirs = set()  
    macros = get_macro_path()
    for file in get_macro_files(path):
        if file.exists():
            if file.is_file():
                os.remove(file)
                dirs.add(Path(file.parent))
            elif file.is_dir():
                dirs.append(file)
    for d in dirs:
        if not os.listdir(d) and d != macros:
            os.rmdir(d)
Пример #4
0
    def linkMacrosFromMod(self, pkg):

        # Ensure macro dir
        macros = get_macro_path()
        if not macros.exists():
            macros.mkdir(parents=True)

        # Search and link
        if pkg.installDir.exists():
            for f in pkg.installDir.iterdir():
                if f.name.lower().endswith(".fcmacro"):
                    Path(macros, f.name).symlink_to(f)
                    pref.set_plugin_parameter(pkg.name, 'destination',
                                              str(pkg.installDir))
Пример #5
0
def restore_absolute_paths(content):
    """Replace placeholders with current absolute paths."""

    core_res_dir = get_freecad_resource_path()
    content = content.replace(_CORE_RES_DIR_, str(core_res_dir))
    content = content.replace(_CORE_RES_URL_, core_res_dir.as_uri())

    user_data_dir = get_app_data_path()
    content = content.replace(_USER_DATA_DIR_, str(user_data_dir))
    content = content.replace(_USER_DATA_URL_, user_data_dir.as_uri())

    user_macro_dir = get_macro_path()
    content = content.replace(_USER_MACRO_DIR_, str(user_macro_dir))
    content = content.replace(_USER_MACRO_URL_, user_macro_dir.as_uri())

    return content
Пример #6
0
    def installMod(self, pkg):

        # Get Git info
        git_available, _, git_version, git_python, git_version_ok = install_info(
        )

        # Get zip info
        zip_available = zlib.is_zip_available()

        # Initialize result
        result = InstallResult(gitAvailable=git_available,
                               gitPythonAvailable=git_python is not None,
                               zipAvailable=zip_available,
                               gitVersionOk=git_version_ok,
                               gitVersion=git_version)

        # Check valid install dir
        in_mods = get_mod_path() == pkg.installDir.parent
        in_macros = pkg.installFile and get_macro_path(
        ) in pkg.installFile.parents
        if not in_mods and not in_macros:
            log('Invalid install dir: {0}'.format(pkg.installDir))
            result.ok = False
            result.invalidInstallDir = True
            return result

        # Try Git install
        if git_available and git_version_ok and git_python:
            result = self.installModFromGit(pkg, result)

        # Try zip/http install
        elif zip_available:
            result = self.installModFromHttpZip(pkg, result)

        if result.ok:
            try:
                self.linkMacrosFromMod(pkg)
            except:
                # ! TODO: Rollback everything if macro links fail?
                pass

        return result
Пример #7
0
 def getMacroList(self):
     install_dir = get_macro_path()
     macros = []
     path = self.downloadMacroList()
     if path:
         workers = []
         for entry in path.glob('**/*'):
             if '.git' in entry.name.lower():
                 continue
             if entry.name.lower().endswith('.fcmacro'):
                 worker = Worker(build_macro_package,
                                 entry,
                                 entry.stem,
                                 is_git=True,
                                 install_path=Path(install_dir, entry.name),
                                 base_path=entry.relative_to(path).parent)
                 worker.start()
                 workers.append(worker)
         macros = [flags.apply_predefined_flags(w.get()) for w in workers]
     return macros
Пример #8
0
def remove_absolute_paths(content):
    """Replace absolute paths to placeholders."""

    # ! I don't like this code, improve later
    # This is used to store data in files as cache without hard references to
    # FreeCAD directories because directories can be different at restore time
    # ie. AppImage

    core_res_dir = get_freecad_resource_path()
    content = content.replace(core_res_dir.as_uri(), _CORE_RES_URL_)
    content = content.replace(str(core_res_dir), _CORE_RES_DIR_)

    user_data_dir = get_app_data_path()
    content = content.replace(user_data_dir.as_uri(), _USER_DATA_URL_)
    content = content.replace(str(user_data_dir), _USER_DATA_DIR_)

    user_macro_dir = get_macro_path()
    content = content.replace(user_macro_dir.as_uri(), _USER_MACRO_URL_)
    content = content.replace(str(user_macro_dir), _USER_MACRO_DIR_)

    return content
Пример #9
0
def build_macro_package(path,
                        macro_name,
                        is_core=False,
                        is_git=False,
                        is_wiki=False,
                        install_path=None,
                        base_path=""):

    with open(path, 'r', encoding='utf-8') as f:

        try:
            tags = get_macro_tags(f.read(), path)
        except:  # !TODO: Handle encoding problems in old windows platforms
            tags = {k: None for k in MACRO_TAG_FILTER}
            log_err(tr('Macro {0} contains invalid characters').format(path))

        install_dir = get_macro_path()
        base = dict(key=str(install_path) if install_path else str(path),
                    type='Macro',
                    isCore=is_core,
                    installDir=install_dir,
                    installFile=Path(install_dir, path.name),
                    isGit=is_git,
                    isWiki=is_wiki,
                    basePath=base_path)
        tags.update(base)

        if not tags['title']:
            tags['title'] = tags['name'] or macro_name

        tags['name'] = macro_name  # Always override name with actual file name

        if not tags['icon']:
            tags['icon'] = get_resource_path('html', 'img',
                                             'package_macro.svg')

        try:
            if not Path(tags['icon']).exists():
                tags['icon'] = get_resource_path('html', 'img',
                                                 'package_macro.svg')
        except:
            tags['icon'] = get_resource_path('html', 'img',
                                             'package_macro.svg')

        tags['icon'] = utils.path_to_url(tags['icon'])

        if tags['comment']:
            tags['description'] = tags['comment']

        if not tags['description']:
            tags['description'] = tr('Warning! No description')

        if tags['categories']:
            cats = COMMA_SEP_LIST_PATTERN.split(tags['categories'])
            tags['categories'] = [tr(c) for c in cats]
        else:
            tags['categories'] = [tr('Uncategorized')]

        if tags['files']:
            tags['files'] = COMMA_SEP_LIST_PATTERN.split(tags['files'])

        if tags['readme']:
            tags['readmeUrl'] = tags['readme']
            tags['readmeFormat'] = 'html'
        elif tags['wiki']:
            tags['readmeUrl'] = tags['wiki']
            tags['readmeFormat'] = 'html'
        elif tags['web']:
            tags['readmeUrl'] = tags['web']
            tags['readmeFormat'] = 'html'

        return PackageInfo(**tags)
Пример #10
0
    def installMacro(self, pkg):

        (git_available, _, git_version, git_python,
         git_version_ok) = install_info()

        # Initialize result
        result = InstallResult(gitAvailable=git_available,
                               gitPythonAvailable=git_python is not None,
                               zipAvailable=zlib.is_zip_available(),
                               gitVersionOk=git_version_ok,
                               gitVersion=git_version)

        # Ensure last version if available locally
        src_dir = self.downloadMacroList()

        # Get path of source macro file
        src_file = Path(src_dir, pkg.basePath, pkg.installFile.name)

        # Copy Macro
        files = []
        try:

            macros_dir = get_macro_path()
            if not macros_dir.exists():
                macros_dir.mkdir(parents=True)

            log('Installing', pkg.installFile)

            shutil.copy2(src_file, pkg.installFile)
            files.append(pkg.installFile)

            # Copy files
            if pkg.files:
                for f in pkg.files:

                    file_base_path = utils.path_relative(f)
                    dst = Path(pkg.installDir, file_base_path).absolute()
                    src = Path(src_dir, pkg.basePath,
                               file_base_path).absolute()

                    log('Installing ', dst)

                    if pkg.installDir not in dst.parents:
                        result.message = tr(
                            'Macro package attempts to install files outside of permitted path'
                        )
                        raise Exception()

                    if src_dir not in src.parents:
                        result.message = tr(
                            'Macro package attempts to access files outside of permitted path'
                        )
                        raise Exception()

                    dst_dir = dst.parent
                    if dst_dir != pkg.installDir and dst_dir not in files and not dst_dir.exists(
                    ):
                        dst_dir.mkdir(parents=True)
                        files.append(dst_dir)

                    shutil.copy2(src, dst)
                    files.append(dst)

            result.ok = True

        except:

            log(traceback.format_exc())

            result.ok = False
            if not result.message:
                result.message = tr(
                    'Macro was not installed, please contact the maintainer.')

            # Rollback
            files.sort(reverse=True)
            for f in files:
                try:
                    log("Rollback ", f)
                    if f.is_file():
                        f.unlink()
                    elif f.is_dir():
                        shutil.rmtree(f, ignore_errors=True)
                except:
                    log(traceback.format_exc())

        return result