示例#1
0
    def retrieve_macros_from_git(self):
        """Retrieve macros from FreeCAD-macros.git

        Emits a signal for each macro in
        https://github.com/FreeCAD/FreeCAD-macros.git
        """

        if not have_git:
            self.info_label_signal.emit("GitPython not installed! Cannot retrieve macros from Git")
            FreeCAD.Console.PrintWarning(translate("AddonsInstaller",
                                                   "GitPython not installed! Cannot retrieve macros from git")+"\n")
            return

        self.info_label_signal.emit("Downloading list of macros from git...")
        try:
            git.Repo.clone_from("https://github.com/FreeCAD/FreeCAD-macros.git", self.repo_dir)
        except Exception:
            FreeCAD.Console.PrintWarning(translate("AddonsInstaller",
                                                   "Something went wrong with the Git Macro Retrieval, "
                                                   "possibly the Git executable is not in the path") + "\n")
        for dirpath, _, filenames in os.walk(self.repo_dir):
            if ".git" in dirpath:
                continue
            for filename in filenames:
                if filename.lower().endswith(".fcmacro"):
                    macro = Macro(filename[:-8])  # Remove ".FCMacro".
                    macro.on_git = True
                    macro.src_filename = os.path.join(dirpath, filename)
                    self.macros.append(macro)
    def retrieve_macros_from_git(self):
        """Retrieve macros from FreeCAD-macros.git

        Emits a signal for each macro in
        https://github.com/FreeCAD/FreeCAD-macros.git
        """

        try:
            import git
        except ImportError:
            self.info_label_signal.emit(
                "GitPython not installed! Cannot retrieve macros from Git")
            FreeCAD.Console.PrintWarning(
                translate(
                    'AddonsInstaller',
                    'GitPython not installed! Cannot retrieve macros from git')
                + "\n")
            return

        self.info_label_signal.emit('Downloading list of macros from git...')
        git.Repo.clone_from('https://github.com/FreeCAD/FreeCAD-macros.git',
                            self.repo_dir)
        for dirpath, _, filenames in os.walk(self.repo_dir):
            if '.git' in dirpath:
                continue
            for filename in filenames:
                if filename.lower().endswith('.fcmacro'):
                    macro = Macro(filename[:-8])  # Remove ".FCMacro".
                    macro.on_git = True
                    macro.src_filename = os.path.join(dirpath, filename)
                    self.macros.append(macro)
示例#3
0
    def retrieve_macros_from_wiki(self):
        """Retrieve macros from the wiki

        Read the wiki and emit a signal for each found macro.
        Reads only the page https://www.freecadweb.org/wiki/Macros_recipes
        """

        self.info_label_signal.emit(
            "Downloading list of macros from the FreeCAD wiki...")
        self.progressbar_show.emit(True)
        u = utils.urlopen("https://www.freecadweb.org/wiki/Macros_recipes")
        if not u:
            FreeCAD.Console.PrintWarning(
                translate(
                    "AddonsInstaller",
                    "Appears to be an issue connecting to the Wiki, "
                    "therefore cannot retrieve Wiki macro list at this time") +
                "\n")
            return
        p = u.read()
        u.close()
        if sys.version_info.major >= 3 and isinstance(p, bytes):
            p = p.decode("utf-8")
        macros = re.findall('title="(Macro.*?)"', p)
        macros = [mac for mac in macros if ("translated" not in mac)]
        for mac in macros:
            macname = mac[6:]  # Remove "Macro ".
            macname = macname.replace("&", "&")
            if (macname not in macros_blacklist) and ("recipes"
                                                      not in macname.lower()):
                macro = Macro(macname)
                macro.on_wiki = True
                self.macros.append(macro)
    def retrieve_macros_from_wiki(self):
        """Retrieve macros from the wiki

        Read the wiki and emit a signal for each found macro.
        Reads only the page https://www.freecadweb.org/wiki/Macros_recipes.
        """

        self.info_label_signal.emit(
            "Downloading list of macros from the FreeCAD wiki...")
        self.progressbar_show.emit(True)
        u = utils.urlopen("https://www.freecadweb.org/wiki/Macros_recipes")
        if not u:
            return
        p = u.read()
        u.close()
        if sys.version_info.major >= 3 and isinstance(p, bytes):
            p = p.decode("utf-8")
        macros = re.findall('title="(Macro.*?)"', p)
        macros = [mac for mac in macros if ('translated' not in mac)]
        for mac in macros:
            macname = mac[6:]  # Remove "Macro ".
            macname = macname.replace("&", "&")
            if (macname not in MACROS_BLACKLIST) and ('recipes'
                                                      not in macname.lower()):
                macro = Macro(macname)
                macro.on_wiki = True
                self.macros.append(macro)
    def _retrieve_macros_from_wiki(self):
        """Retrieve macros from the wiki

        Read the wiki and emit a signal for each found macro.
        Reads only the page https://wiki.freecad.org/Macros_recipes
        """

        p = NetworkManager.AM_NETWORK_MANAGER.blocking_get(
            "https://wiki.freecad.org/Macros_recipes"
        )
        if not p:
            # The Qt Python translation extractor doesn't support splitting this string (yet)
            # pylint: disable=line-too-long
            FreeCAD.Console.PrintWarning(
                translate(
                    "AddonsInstaller",
                    "Error connecting to the Wiki, FreeCAD cannot retrieve the Wiki macro list at this time",
                )
                + "\n"
            )
            return
        p = p.data().decode("utf8")
        macros = re.findall('title="(Macro.*?)"', p)
        macros = [mac for mac in macros if "translated" not in mac]
        macro_names = []
        for _, mac in enumerate(macros):
            if self.current_thread.isInterruptionRequested():
                return
            macname = mac[6:]  # Remove "Macro ".
            macname = macname.replace("&", "&")
            if not macname:
                continue
            if (
                (macname not in self.macros_reject_list)
                and ("recipes" not in macname.lower())
                and (macname not in macro_names)
            ):
                macro_names.append(macname)
                macro = Macro(macname)
                if macro.name in self.package_names:
                    FreeCAD.Console.PrintLog(
                        f"Ignoring second macro named {macro.name} (found on wiki)\n"
                    )
                    continue  # We already have a macro with this name
                self.package_names.append(macro.name)
                macro.on_wiki = True
                macro.parsed = False
                repo = Addon.from_macro(macro)
                repo.url = "https://wiki.freecad.org/Macros_recipes"
                utils.update_macro_installation_details(repo)
                self.addon_repo.emit(repo)
示例#6
0
 def test_version_from_int(self):
     outfile = self.generate_macro_file()
     with open(outfile) as f:
         lines = f.readlines()
         output_lines = []
         for line in lines:
             if "VERSION" in line:
                 line = "__Version__ = 1"
             output_lines.append(line)
     with open(outfile, "w") as f:
         f.write("\n".join(output_lines))
     m = Macro("Unit Test Macro")
     m.fill_details_from_file(outfile)
     self.assertEqual(m.version, "1")
示例#7
0
 def test_version_from_date(self):
     replacements = {
         "DATE": "2022-03-09",
     }
     outfile = self.generate_macro_file(replacements)
     with open(outfile) as f:
         lines = f.readlines()
         output_lines = []
         for line in lines:
             if "VERSION" in line:
                 line = "__Version__ = __Date__"
             output_lines.append(line)
     with open(outfile, "w") as f:
         f.write("\n".join(output_lines))
     m = Macro("Unit Test Macro")
     m.fill_details_from_file(outfile)
     self.assertEqual(m.version, "2022-03-09")
示例#8
0
    def test_create_from_macro(self):
        macro_file = os.path.join(self.test_dir, "DoNothing.FCMacro")
        macro = Macro("DoNothing")
        macro.fill_details_from_file(macro_file)
        addon = Addon.from_macro(macro)

        self.assertEqual(addon.repo_type, Addon.Kind.MACRO)
        self.assertEqual(addon.name, "DoNothing")
        self.assertEqual(
            addon.macro.comment,
            "Do absolutely nothing. For Addon Manager unit tests.")
        self.assertEqual(addon.url, "https://github.com/FreeCAD/FreeCAD")
        self.assertEqual(addon.macro.version, "1.0")
        self.assertEqual(len(addon.macro.other_files), 3)
        self.assertEqual(addon.macro.author, "Chris Hennes")
        self.assertEqual(addon.macro.date, "2022-02-28")
        self.assertEqual(addon.macro.icon, "not_real.png")
        self.assertEqual(addon.macro.xpm, "")
示例#9
0
 def from_macro(self, macro: Macro):
     if macro.is_installed():
         status = AddonManagerRepo.UpdateStatus.UNCHECKED
     else:
         status = AddonManagerRepo.UpdateStatus.NOT_INSTALLED
     instance = AddonManagerRepo(macro.name, macro.url, status, "master")
     instance.macro = macro
     instance.repo_type = AddonManagerRepo.RepoType.MACRO
     instance.description = macro.desc
     return instance
示例#10
0
    def from_macro(cls, macro: Macro):
        """Create an Addon object from a Macro wrapper object"""

        if macro.is_installed():
            status = Addon.Status.UNCHECKED
        else:
            status = Addon.Status.NOT_INSTALLED
        instance = Addon(macro.name, macro.url, status, "master")
        instance.macro = macro
        instance.repo_type = Addon.Kind.MACRO
        instance.description = macro.desc
        return instance
示例#11
0
    def retrieve_macros_from_wiki(self):
        """Retrieve macros from the wiki

        Read the wiki and emit a signal for each found macro.
        Reads only the page https://www.freecadweb.org/wiki/Macros_recipes.
        """
        self.info_label_signal.emit("Downloading list of macros...")
        self.progressbar_show.emit(True)
        u = urlopen("https://www.freecadweb.org/wiki/Macros_recipes")
        p = u.read()
        u.close()
        if sys.version_info.major >= 3 and isinstance(p, bytes):
            p = p.decode("utf-8")
        macros = re.findall('title="(Macro.*?)"', p)
        macros = [mac for mac in macros if ('translated' not in mac)]
        for mac in macros:
            macname = mac[6:]  # Remove "Macro ".
            macname = macname.replace("&","&")
            if (macname not in MACROS_BLACKLIST) and ('recipes' not in macname.lower()):
                macro = Macro(macname)
                macro.on_wiki = True
                self.macros.append(macro)
    def run(self):
        """Rarely called directly: create an instance and call start() on it instead to
        launch in a new thread"""

        with open(self.cache_file, "r", encoding="utf-8") as f:
            data = f.read()
            dict_data = json.loads(data)
            for item in dict_data:
                if QtCore.QThread.currentThread().isInterruptionRequested():
                    return
                new_macro = Macro.from_cache(item)
                repo = Addon.from_macro(new_macro)
                utils.update_macro_installation_details(repo)
                self.add_macro_signal.emit(repo)
示例#13
0
    def test_xpm(self):
        outfile = self.generate_macro_file()
        xpm_data = """/* XPM */
static char * blarg_xpm[] = {
"16 7 2 1",
"* c #000000",
". c #ffffff",
"**..*...........",
"*.*.*...........",
"**..*..**.**..**",
"*.*.*.*.*.*..*.*",
"**..*..**.*...**",
"...............*",
".............**."
};"""
        with open(outfile) as f:
            contents = f.read()
            contents += f"\n__xpm__ = \"\"\"{xpm_data}\"\"\"\n"

        with open(outfile, "w") as f:
            f.write(contents)
        m = Macro("Unit Test Macro")
        m.fill_details_from_file(outfile)
        self.assertEqual(m.xpm, xpm_data)
示例#14
0
    def retrieve_macros_from_git(self):
        """Retrieve macros from FreeCAD-macros.git

        Emits a signal for each macro in
        https://github.com/FreeCAD/FreeCAD-macros.git.
        """
        try:
            import git
        except ImportError:
            self.info_label_signal.emit("GitPython not installed! Cannot retrieve macros from git")
            FreeCAD.Console.PrintWarning('GitPython not installed! Cannot retrieve macros from git')
            return

        self.info_label_signal.emit('Downloading list of macros for git...')
        git.Repo.clone_from('https://github.com/FreeCAD/FreeCAD-macros.git', self.repo_dir)
        for dirpath, _, filenames in os.walk(self.repo_dir):
             if '.git' in dirpath:
                 continue
             for filename in filenames:
                 if filename.lower().endswith('.fcmacro'):
                    macro = Macro(filename[:-8])  # Remove ".FCMacro".
                    macro.on_git = True
                    macro.src_filename = os.path.join(dirpath, filename)
                    self.macros.append(macro)
    def _retrieve_macros_from_git(self):
        """Retrieve macros from FreeCAD-macros.git

        Emits a signal for each macro in
        https://github.com/FreeCAD/FreeCAD-macros.git
        """

        macro_cache_location = utils.get_cache_file_name("Macros")

        if not self.git_manager:
            message = translate(
                "AddonsInstaller",
                "Git is disabled, skipping git macros",
            )
            self.status_message.emit(message)
            FreeCAD.Console.PrintWarning(message + "\n")
            return

        update_succeeded = self._update_local_git_repo()
        if not update_succeeded:
            return

        n_files = 0
        for _, _, filenames in os.walk(macro_cache_location):
            n_files += len(filenames)
        counter = 0
        for dirpath, _, filenames in os.walk(macro_cache_location):
            counter += 1
            if self.current_thread.isInterruptionRequested():
                return
            if ".git" in dirpath:
                continue
            for filename in filenames:
                if self.current_thread.isInterruptionRequested():
                    return
                if filename.lower().endswith(".fcmacro"):
                    macro = Macro(filename[:-8])  # Remove ".FCMacro".
                    if macro.name in self.package_names:
                        FreeCAD.Console.PrintLog(
                            f"Ignoring second macro named {macro.name} (found on git)\n"
                        )
                        continue  # We already have a macro with this name
                    self.package_names.append(macro.name)
                    macro.on_git = True
                    macro.src_filename = os.path.join(dirpath, filename)
                    macro.fill_details_from_file(macro.src_filename)
                    repo = Addon.from_macro(macro)
                    FreeCAD.Console.PrintLog(f"Found macro {repo.name}\n")
                    repo.url = "https://github.com/FreeCAD/FreeCAD-macros.git"
                    utils.update_macro_installation_details(repo)
                    self.addon_repo.emit(repo)
示例#16
0
    def retrieve_macros_from_git(self):
        """Retrieve macros from FreeCAD-macros.git

        Emits a signal for each macro in
        https://github.com/FreeCAD/FreeCAD-macros.git
        """

        git = None
        import os
        try:
            import git
        except ImportError:
            self.info_label_signal.emit(
                "GitPython not installed! Cannot retrieve macros from Git")
            FreeCAD.Console.PrintWarning(
                translate(
                    'AddonsInstaller',
                    'GitPython not installed! Cannot retrieve macros from git, fallback to using the Wiki'
                ) + "\n")
        if git:
            git_exe = utils.checkGitBinary()
            try:
                out = os.popen(git_exe + ' --version', 'r')
            except:
                pass
            if 'out' in locals():
                out_string = out.read()
                out.close()
                result = re.search('(\d+\.\d+\.\d+)', out_string)
                from distutils.version import StrictVersion
                git_version = StrictVersion(result.group(1))
                git_version_min = StrictVersion(GITMACMIN)
                if git_version < git_version_min:
                    import platform
                    if platform.system() == 'Windows':
                        FreeCAD.Console.PrintWarning(
                            translate(
                                "AddonsInstaller",
                                "Outdated Git executable detected, consider upgrading or ensure the path to the most recent version is the first one to be found. Cannot retrieve macros from git, fallback to using the Wiki"
                            ) + "\n")
                    else:
                        FreeCAD.Console.PrintWarning(
                            translate(
                                "AddonsInstaller",
                                "Outdated Git binary detected, consider upgrading. Cannot retrieve macros from git, fallback to using the Wiki"
                            ) + "\n")
                    git = None
            else:
                self.info_label_signal.emit(
                    "Git binary not installed! Cannot retrieve macros from Git"
                )
                import platform
                if platform.system() == 'Windows':
                    FreeCAD.Console.PrintWarning(
                        translate(
                            'AddonsInstaller',
                            'Git executable not found. Cannot retrieve macros using git, fallback to using the Wiki'
                        ) + "\n")
                else:
                    FreeCAD.Console.PrintWarning(
                        translate(
                            'AddonsInstaller',
                            'Git binary not found.  Cannot retrieve macros using git, fallback to using the Wiki'
                        ) + "\n")
                git = None
        if git:
            self.info_label_signal.emit(
                'Downloading list of macros from git...')
            try:
                git.Repo.clone_from(
                    'https://github.com/FreeCAD/FreeCAD-macros.git',
                    self.repo_dir)
            except:
                FreeCAD.Console.PrintWarning(
                    translate(
                        'AddonsInstaller',
                        'Something went wrong with the Git Macro retrieval, fallback to using the Wiki'
                    ) + "\n")
                return
            for dirpath, _, filenames in os.walk(self.repo_dir):
                if '.git' in dirpath:
                    continue
                for filename in filenames:
                    if filename.lower().endswith('.fcmacro'):
                        macro = Macro(filename[:-8])  # Remove ".FCMacro".
                        macro.on_git = True
                        macro.src_filename = os.path.join(dirpath, filename)
                        self.macros.append(macro)
示例#17
0
 def generate_macro(self, replacements: Dict[str, str] = {}) -> Macro:
     outfile = self.generate_macro_file(replacements)
     m = Macro("Unit Test Macro")
     m.fill_details_from_file(outfile)
     os.unlink(outfile)
     return m