Esempio n. 1
0
    def CreateDEB(self, bundle_id, recorded_version):
        """
        Creates a DEB from information stored in the "temp" folder.

        String bundle_id: The bundle id of the package to compress.
        """
        # TODO: Find a Python-based method to safely delete all DS_Store files.
        call(["find", ".", "-name", ".DS_Store", "-delete"],
             cwd=self.root + "temp/" +
             bundle_id)  # Remove .DS_Store. Kinda finicky.
        for file_name in os.listdir(self.root + "temp/" + bundle_id):
            if file_name.endswith(".deb"):
                # Check if the DEB is a newer version
                deb = Dpkg(self.root + "temp/" + bundle_id + "/" + file_name)
                if Dpkg.compare_versions(recorded_version, deb.version) == -1:
                    # Update package stuff
                    package_name = PackageLister.BundleIdToDirName(
                        self, bundle_id)
                    with open(
                            self.root + "Packages/" + package_name +
                            "/silica_data/index.json", "r") as content_file:
                        update_json = json.load(content_file)
                        update_json['version'] = deb.version
                        changelog_entry = input(
                            "The DEB provided for \"" + update_json['name'] +
                            "\" has a new version available (" +
                            recorded_version + " -> " + deb.version +
                            "). What changed in this version?\n(Add multiple lines"
                            +
                            " by using a newline character [\\n] and use valid Markdown syntax.): "
                        )
                        try:
                            update_json['changelog'].append({
                                "version":
                                deb.version,
                                "changes":
                                changelog_entry
                            })
                        except Exception:
                            update_json['changelog'] = {
                                "version": deb.version,
                                "changes": changelog_entry
                            }
                        return_str = json.dumps(update_json)
                        print("Updating package index.json...")
                        PackageLister.CreateFile(
                            self, "Packages/" + package_name +
                            "/silica_data/index.json", return_str)
                    pass
                DpkgPy.extract(
                    self, self.root + "temp/" + bundle_id + "/" + file_name,
                    self.root + "temp/" + bundle_id)
                os.remove(self.root + "temp/" + bundle_id + "/" + file_name)
                os.remove(self.root + "temp/" + bundle_id + "/control")
        else:
            # TODO: Update DpkgPy to generate DEB files without dependencies (for improved win32 support)
            call(["dpkg-deb", "-b", "-Zgzip", self.root + "temp/" + bundle_id],
                 cwd=self.root + "temp/")  # Compile DEB
Esempio n. 2
0
    def CheckForSilicaData(self):
        """
        Ensures that a silica_data file exists and if it doesn't, try to create one with as much data as we have.
        If there is a DEB file, it will take data from its CONTROL file. It will also auto-update the version number.
        If there is no DEB file, it will use the name of the folder, version 1.0.0, try to guess some dependencies,
            and add some placeholder data.
        :return:
        """
        for folder in os.listdir(self.root + "Packages"):
            if folder.lower() != ".ds_store":
                if not os.path.isdir(self.root + "Packages/" + folder + "/silica_data"):
                    print("It seems like the package \"" + folder + "\" is not configured. Let's set it up!")
                    is_deb = False
                    deb_path = ""
                    try:
                        for file_name in os.listdir(self.root + "Packages/" + folder):
                            if file_name.endswith(".deb"):
                                is_deb = True
                                deb_path = self.root + "Packages/" + folder + "/" + file_name
                    except Exception:
                        PackageLister.ErrorReporter(self, "Configuration Error!", "Please put your .deb file inside of "
                            "its own folder. The \"Packages\" directory should be made of multiple folders that each "
                            "contain data for a single package.\n Please fix this issue and try again.")

                    # This will be the default scaffolding for our package. Eventually I'll neuter it to only be the
                    # essential elements; it's also kinda a reference to me.
                    output = {
                        "bundle_id": "co.shuga.silica.unknown",
                        "name": "Unknown Package",
                        "version": "1.0.0",
                        "tagline": "An unknown package.",
                        "homepage": "https://shuga.co/",
                        "developer": {
                            "name": "Unknown",
                            "email": "*****@*****.**"
                        },
                        "maintainer": {
                            "name": "Unknown",
                            "email": "*****@*****.**"
                        },
                        "section": "Themes",

                        "works_min": "8.0",
                        "works_max": "13.0",
                        "featured": "false"
                    }

                    if is_deb:
                        print("Extracting data from DEB...")
                        deb = Dpkg(deb_path)
                        output['name'] = deb.headers['Name']
                        output['bundle_id'] = deb.headers['Package']
                        try:
                            output['tagline'] = deb.headers['Description']
                        except Exception:
                            output['tagline'] = input("What is a brief description of the package? ")
                        try:
                            output['homepage'] = deb.headers['Homepage']
                        except Exception:
                            pass
                        try:
                            remove_email_regex = re.compile('<.*?>')
                            output['developer']['name'] = remove_email_regex.sub("", deb.headers['Author'])
                        except Exception:
                            output['developer']['name'] = input("Who originally made this package? This may be"
                                                                " your name. ")
                        output['developer']['email'] = input("What is the original author's email address? ")
                        try:
                            remove_email_regex = re.compile('<.*?>')
                            output['maintainer']['name'] = remove_email_regex.sub("", deb.headers['Maintainer'])
                        except Exception:
                            output['maintainer']['name'] = input("Who maintains this package now?"
                                                                 " This is likely your name. ")
                        output['maintainer']['email'] = input("What is the maintainer's email address? ")
                        try:
                            output['sponsor']['name'] = remove_email_regex.sub("", deb.headers['Sponsor'])
                        except Exception:
                            pass
                        try:
                            output['dependencies'] = deb.headers['Depends']
                        except Exception:
                            pass
                        try:
                            output['section'] = deb.headers['Section']
                        except Exception:
                            pass
                        try:
                            output['version'] = deb.headers['Version']
                        except Exception:
                            output['version'] = "1.0.0"
                        try:
                            output['conflicts'] = deb.headers['Conflicts']
                        except Exception:
                            pass
                        try:
                            output['replaces'] = deb.headers['Replaces']
                        except Exception:
                            pass
                        try:
                            output['provides'] = deb.headers['Provides']
                        except Exception:
                            pass
                        try:
                            output['build_depends'] = deb.headers['Build-Depends']
                        except Exception:
                            pass
                        try:
                            output['recommends'] = deb.headers['Recommends']
                        except Exception:
                            pass
                        try:
                            output['suggests'] = deb.headers['Suggests']
                        except Exception:
                            pass
                        try:
                            output['enhances'] = deb.headers['Enhances']
                        except Exception:
                            pass
                        try:
                            output['breaks'] = deb.headers['Breaks']
                        except Exception:
                            pass
                        try:
                            output['tags'] = deb.headers['Tag']
                        except Exception:
                            pass
                        try:
                            output['suggests'] = deb.headers['Suggests']
                        except Exception:
                            pass
                        # These still need data.
                        output['works_min'] = input("What is the lowest iOS version the package works on? ")
                        output['works_max'] = input("What is the highest iOS version the package works on? ")
                        output['featured'] = input("Should this package be featured on your repo? (true/false) ")
                        set_tint = input("What would you like this package's tint color to be? To keep it at"
                                         " the default, leave this blank: ")
                        if set_tint != "":
                            output['tint'] = set_tint
                        print("All done! Please look over the generated \"index.json\" file and consider populating the"
                              " \"silica_data\" folder with a description, screenshots, and an icon.")
                        # Extract Control file and scripts from DEB
                        DpkgPy.control_extract(self, deb_path, self.root + "Packages/" + folder +
                                               "/silica_data/scripts/")
                        # Remove the Control; it's not needed.
                        os.remove(self.root + "Packages/" + folder + "/silica_data/scripts/Control")
                        if not os.listdir(self.root + "Packages/" + folder + "/silica_data/scripts/"):
                            os.rmdir(self.root + "Packages/" + folder + "/silica_data/scripts/")
                    else:
                        print("Estimating dependencies...")
                        # Use the filesystem to see if Zeppelin, Anemone, LockGlyph, XenHTML, and similar.
                        # If one of these are found, set it as a dependency.
                        # If multiple of these are found, use a hierarchy system, with Anemone as the highest priority,
                        # for determining the category.
                        output['dependencies'] = ""
                        output['section'] = "Themes"

                        if os.path.isdir(self.root + "Packages/" + folder + "/Library/Zeppelin"):
                            output['section'] = "Themes (Zeppelin)"
                            output['dependencies'] += "com.alexzielenski.zeppelin, "

                        if os.path.isdir(self.root + "Packages/" + folder + "/Library/Application Support/LockGlyph"):
                            output['section'] = "Themes (LockGlyph)"
                            output['dependencies'] += "com.evilgoldfish.lockglypgh, "

                        if os.path.isdir(self.root + "Packages/" + folder + "/var/mobile/Library/iWidgets"):
                            output['section'] = "Widgets"
                            output['dependencies'] += "com.matchstic.xenhtml, "

                        if os.path.isdir(self.root + "Packages/" + folder + "/Library/Wallpaper"):
                            output['section'] = "Wallpapers"

                        if os.path.isdir(self.root + "Packages/" + folder + "/Library/Themes"):
                            output['section'] = "Themes"
                            output['dependencies'] += "com.anemonetheming.anemone, "

                        if output['dependencies'] != "":
                            output['dependencies'] = output['dependencies'][:-2]

                        repo_settings = PackageLister.GetRepoSettings(self)
                        # Ask for name
                        output['name'] = input("What should we name this package? ")
                        # Automatically generate a bundle ID from the package name.
                        domain_breakup = repo_settings['cname'].split(".")[::-1]
                        only_alpha_regex = re.compile('[^a-zA-Z]')
                        machine_safe_name = only_alpha_regex.sub("", output['name']).lower()
                        output['bundle_id'] = ".".join(str(x) for x in domain_breakup) + "." + machine_safe_name
                        output['tagline'] = input("What is a brief description of the package? ")
                        output['homepage'] = "https://" + repo_settings['cname']
                        # I could potentially default this to what is in settings.json but attribution may be an issue.
                        output['developer']['name'] = input("Who made this package? This is likely your name. ")
                        output['developer']['email'] = input("What is the author's email address? ")
                        output['works_min'] = input("What is the lowest iOS version the package works on? ")
                        output['works_max'] = input("What is the highest iOS version the package works on? ")
                        output['featured'] = input("Should this package be featured on your repo? (true/false) ")
                    PackageLister.CreateFolder(self, "Packages/" + folder + "/silica_data/")
                    PackageLister.CreateFile(self, "Packages/" + folder + "/silica_data/index.json", json.dumps(output))
Esempio n. 3
0
    def CreateDEB(self, bundle_id, recorded_version):
        """
        Creates a DEB from information stored in the "temp" folder.

        String bundle_id: The bundle id of the package to compress.
        String recorded_version: 
        Object tweak_release: A "tweak release" object.
        """
        # TODO: Find a Python-based method to safely delete all DS_Store files.
        call(["find", ".", "-name", ".DS_Store", "-delete"],
             cwd=self.root + "temp/" + bundle_id)  # Remove .DS_Store. Kinda finicky.
        for file_name in os.listdir(self.root + "temp/" + bundle_id):
            if file_name.endswith(".deb"):
                # Check if the DEB is a newer version
                deb = Dpkg(self.root + "temp/" + bundle_id + "/" + file_name)
                if Dpkg.compare_versions(recorded_version, deb.version) == -1:
                    # Update package stuff
                    package_name = PackageLister.BundleIdToDirName(self, bundle_id)
                    with open(self.root + "Packages/" + package_name + "/silica_data/index.json", "r") as content_file:
                        update_json = json.load(content_file)
                        update_json['version'] = deb.version
                        changelog_entry = input("The DEB provided for \"" + update_json['name'] +
                                                "\" has a new version available (" + recorded_version + " -> " +
                                                deb.version + "). What changed in this version?\n(Add multiple lines" +
                                                " by using newline characters [\\n\\n] and use valid Markdown syntax): "
                                                )

                        try:
                            update_json['changelog'].append(
                                {
                                    "version": deb.version,
                                    "changes": changelog_entry
                                }
                            )
                        except Exception:
                            # Make it a list!
                            update_json['changelog'] = []

                            update_json['changelog'].append(
                                {
                                    "version": deb.version,
                                    "changes": changelog_entry
                                }
                            )

                        # A small note: We already created the variables that contain the changelogs and, to
                        # make matters worse, all the web assets. The only way to mitigate this is to re-create the
                        # tweak_release variable again, which wrecks a lot of things (ie runtime).
                        # A Silica rewrite is required to properly fix this bug.
                        print("\nA small warning about adding changelogs mid-run:\n")
                        print("Due to some less-than-ideal design decisions with Silica, for the changelog to show")
                        print("up, you're going to have to run Silica again. Yes, I know this is annoying, and a proper")
                        print("solution is in the works, but the under-the-hood changes that'll be needed to fix")
                        print("it properly would require a rewrite [see issue #22].\n")
                        print("I'm deeply sorry about this.\n    - Shuga.\n")

                        # Get human-readable folder name
                        folder = PackageLister.BundleIdToDirName(self, bundle_id)
                        deb_path = self.root + "Packages/" + folder + "/" + file_name
                        # Extract Control file and scripts from DEB
                        DpkgPy.control_extract(self, deb_path, self.root + "Packages/" + folder +
                                               "/silica_data/scripts/")
                        # Remove the Control; it's not needed.
                        os.remove(self.root + "Packages/" + folder + "/silica_data/scripts/Control")
                        if not os.listdir(self.root + "Packages/" + folder + "/silica_data/scripts/"):
                            os.rmdir(self.root + "Packages/" + folder + "/silica_data/scripts/")

                        return_str = json.dumps(update_json)
                        print("Updating package index.json...")
                        PackageLister.CreateFile(self, "Packages/" + package_name +
                                                 "/silica_data/index.json", return_str)
                    pass
                DpkgPy.extract(self, self.root + "temp/" + bundle_id + "/" + file_name, self.root + "temp/" + bundle_id)
                try:
                    os.remove(self.root + "temp/" + bundle_id + "/" + file_name)
                except:
                    pass
                try:
                    os.remove(self.root + "temp/" + bundle_id + "/control")
                except:
                    pass
        else:
            # TODO: Update DpkgPy to generate DEB files without dependencies (for improved win32 support)
            # If the version is consistent, then assume the package is unchanged. Don't regenerate it.
            try:
                # Check for a DEB that already exists.
                docs_deb = Dpkg(self.root + "docs/pkg/" + bundle_id + ".deb")
                if docs_deb.version == recorded_version:
                    shutil.copy(self.root + "docs/pkg/" + bundle_id + ".deb", self.root + "temp/" + bundle_id + ".deb")
                    call_result = 0;
                else:
                    # Sneaky swap.
                    call_result = call(["dpkg-deb", "-b", "-Zgzip", self.root + "temp/" + bundle_id], cwd=self.root + "temp/")  # Compile DEB
            except:
                # Create the DEB again.
                call_result = call(["dpkg-deb", "-b", "-Zgzip", self.root + "temp/" + bundle_id], cwd=self.root + "temp/")  # Compile DEB
            if call_result != 0:
                # Did we run within WSL?
                if "Microsoft" in platform.release():
                    PackageLister.ErrorReporter(self, "Platform Error!", "dpkg-deb failed to run. "
                    "This is likely due to improper configuration of WSL. Please check the Silcia README for "
                    "how to set up WSL for dpkg-deb.")
                else:
                    PackageLister.ErrorReporter(self, "DPKG Error!", "dpkg-deb failed to run. "
                    "This could be due to a faulty system configuration.")
Esempio n. 4
0
    def CreateDEB(self, bundle_id, recorded_version):
        """
        Creates a DEB from information stored in the "temp" folder.

        String bundle_id: The bundle id of the package to compress.
        String recorded_version: 
        Object tweak_release: A "tweak release" object.
        """
        # TODO: Find a Python-based method to safely delete all DS_Store files.
        call(["find", ".", "-name", ".DS_Store", "-delete"],
             cwd=self.root + "temp/" + bundle_id)  # Remove .DS_Store. Kinda finicky.
        for file_name in os.listdir(self.root + "temp/" + bundle_id):
            if file_name.endswith(".deb"):
                # Check if the DEB is a newer version
                deb = Dpkg(self.root + "temp/" + bundle_id + "/" + file_name)
                if Dpkg.compare_versions(recorded_version, deb.version) == -1:
                    # Update package stuff
                    package_name = PackageLister.BundleIdToDirName(self, bundle_id)
                    with open(self.root + "Packages/" + package_name + "/silica_data/index.json", "r") as content_file:
                        update_json = json.load(content_file)
                        update_json['version'] = deb.version
                        changelog_entry = input("The DEB provided for \"" + update_json['name'] +
                                                "\" has a new version available (" + recorded_version + " -> " +
                                                deb.version + "). What changed in this version?\n(Add multiple lines" +
                                                " by using newline characters [\\n\\n] and use valid Markdown syntax): "
                                                )
                        try:
                            update_json['changelog'].append({
                                "version": deb.version,
                                "changes": changelog_entry
                            })
                        except Exception:
                            update_json['changelog'] = {
                                "version": deb.version,
                                "changes": changelog_entry
                            }

                        # Get human-readable folder name
                        folder = PackageLister.BundleIdToDirName(self, bundle_id)
                        deb_path = self.root + "Packages/" + folder + "/" + file_name
                        # Extract Control file and scripts from DEB
                        DpkgPy.control_extract(self, deb_path, self.root + "Packages/" + folder +
                                               "/silica_data/scripts/")
                        # Remove the Control; it's not needed.
                        os.remove(self.root + "Packages/" + folder + "/silica_data/scripts/Control")
                        if not os.listdir(self.root + "Packages/" + folder + "/silica_data/scripts/"):
                            os.rmdir(self.root + "Packages/" + folder + "/silica_data/scripts/")

                        return_str = json.dumps(update_json)
                        print("Updating package index.json...")
                        PackageLister.CreateFile(self, "Packages/" + package_name +
                                                 "/silica_data/index.json", return_str)
                    pass
                DpkgPy.extract(self, self.root + "temp/" + bundle_id + "/" + file_name, self.root + "temp/" + bundle_id)
                os.remove(self.root + "temp/" + bundle_id + "/" + file_name)
                os.remove(self.root + "temp/" + bundle_id + "/control")
        else:
            # TODO: Update DpkgPy to generate DEB files without dependencies (for improved win32 support)
            # If the version is consistent, then assume the package is unchanged. Don't regenerate it.
            try:
                docs_deb = Dpkg(self.root + "docs/pkg/" + bundle_id + ".deb")
                if docs_deb.version == recorded_version:
                    shutil.copy(self.root + "docs/pkg/" + bundle_id + ".deb", self.root + "temp/" + bundle_id + ".deb")
                    call_result = 0;
                else:
                    # Sneaky swap.
                    call_result = call(["dpkg-deb", "-b", "-Zgzip", self.root + "temp/" + bundle_id], cwd=self.root + "temp/")  # Compile DEB
            except:
                call_result = call(["dpkg-deb", "-b", "-Zgzip", self.root + "temp/" + bundle_id], cwd=self.root + "temp/")  # Compile DEB
            if call_result != 0:
                # Did we run within WSL?
                if "Microsoft" in platform.release():
                    PackageLister.ErrorReporter(self, "Platform Error!", "dpkg-deb failed to run. "
                    "This is due to improper configuration of WSL. Please check the Silcia README for "
                    "how to set up WSL for dpkg-deb.")
                else:
                    PackageLister.ErrorReporter(self, "Platform Error!", "dpkg-deb failed to run. "
                    "This may be due to a faulty system configuration.")