Esempio n. 1
0
class SBoInstall(object):
    """Build and install SBo packages with all dependencies
    """
    def __init__(self, slackbuilds, flag):
        self.slackbuilds = slackbuilds
        pkg_security(self.slackbuilds)
        self.flag = flag
        self.meta = _meta_
        self.msg = Msg()
        self.arch = SBoArch().get()
        self.build_folder = self.meta.build_path
        self._SOURCES = self.meta.SBo_SOURCES
        for fl in self.flag:
            if fl.startswith("--directory-prefix="):
                self.build_folder = fl.split("=")[1]
                if not self.build_folder.endswith("/"):
                    self.build_folder += "/"
        self.unst = ["UNSUPPORTED", "UNTESTED"]
        self.master_packages = []
        self.deps = []
        self.dependencies = []
        self.package_not_found = []
        self.package_found = []
        self.deps_dict = {}
        self.answer = ""
        self.match = False
        self.count_ins = 0
        self.count_upg = 0
        self.count_uni = 0
        self.msg.reading()
        self.data = SBoGrep(name="").names()
        self.blacklist = BlackList().packages(pkgs=self.data, repo="sbo")

    def start(self, is_upgrade):
        """Start view, build and install SBo packages
        """
        tagc = ""
        self.is_upgrade = is_upgrade
        self.case_insensitive()
        for _sbo in self.slackbuilds:
            status(0.03)
            if _sbo in self.data and _sbo not in self.blacklist:
                sbo_deps = Requires(self.flag).sbo(_sbo)
                self.deps += sbo_deps
                self.deps_dict[_sbo] = self.one_for_all(sbo_deps)
                self.package_found.append(_sbo)
            else:
                self.package_not_found.append(_sbo)
        self.update_deps()

        if not self.package_found:
            self.match = True
            self.matching()

        self.master_packages, mas_src = self.sbo_version_source(
            self.package_found)
        self.msg.done()
        if (self.meta.rsl_deps in ["on", "ON"] and self.flag != "--resolve-off"
                and not self.match):
            self.msg.resolving()
        self.dependencies, dep_src = self.sbo_version_source(
            self.one_for_all(self.deps))
        if (self.meta.rsl_deps in ["on", "ON"] and self.flag != "--resolve-off"
                and not self.match):
            self.msg.done()
        self.clear_masters()

        if self.package_found:
            print("\nThe following packages will be automatically "
                  "installed or upgraded \nwith new version:\n")
            if self.match:
                self.msg.matching(self.slackbuilds)
            self.top_view()
            self.msg.upg_inst(self.is_upgrade)

            # view master packages
            for sbo, arch in zip(self.master_packages, mas_src):
                tagc = self.tag(sbo)
                name = "-".join(sbo.split("-")[:-1])
                self.view_packages(tagc, name,
                                   sbo.split("-")[-1], self.select_arch(arch))
            self.view_installing_for_deps()

            # view dependencies
            for dep, arch in zip(self.dependencies, dep_src):
                tagc = self.tag(dep)
                name = "-".join(dep.split("-")[:-1])
                self.view_packages(tagc, name,
                                   dep.split("-")[-1], self.select_arch(arch))

            count_total = sum([self.count_ins, self.count_upg, self.count_uni])
            print("\nInstalling summary")
            print("=" * 79)
            print("{0}Total {1} {2}.".format(self.meta.color["GREY"],
                                             count_total,
                                             self.msg.pkg(count_total)))
            print("{0} {1} will be installed, {2} already installed and "
                  "{3} {4}".format(self.count_uni,
                                   self.msg.pkg(self.count_uni),
                                   self.count_ins, self.count_upg,
                                   self.msg.pkg(self.count_upg)))
            print("will be upgraded.{0}\n".format(self.meta.color["ENDC"]))
            self.continue_to_install()
        else:
            self.msg.not_found(self.is_upgrade)
            raise SystemExit(1)

    def case_insensitive(self):
        """Matching packages distinguish between uppercase and
        lowercase
        """
        if "--case-ins" in self.flag:
            data_dict = Utils().case_sensitive(self.data)
            for name in self.slackbuilds:
                index = self.slackbuilds.index(name)
                for key, value in data_dict.iteritems():
                    if key == name.lower():
                        self.slackbuilds[index] = value

    def update_deps(self):
        """Update dependencies dictionary with all package
        """
        onelist, dependencies = [], []
        onelist = Utils().dimensional_list(self.deps)
        dependencies = Utils().remove_dbs(onelist)
        for dep in dependencies:
            deps = Requires(self.flag).sbo(dep)
            self.deps_dict[dep] = self.one_for_all(deps)

    def continue_to_install(self):
        """Continue to install ?
        """
        if (self.count_uni > 0 or self.count_upg > 0
                or "--download-only" in self.flag or "--rebuild" in self.flag):
            if self.master_packages and self.msg.answer() in ["y", "Y"]:
                installs, upgraded = self.build_install()
                if "--download-only" in self.flag:
                    raise SystemExit()
                self.msg.reference(installs, upgraded)
                write_deps(self.deps_dict)
                delete(self.build_folder)

    def view_installing_for_deps(self):
        """View installing message for dependencies
        """
        if not self.match and self.dependencies:
            print("Installing for dependencies:")

    def clear_masters(self):
        """Clear master slackbuilds if already exist in dependencies
        or if added to install two or more times
        """
        self.master_packages = Utils().remove_dbs(self.master_packages)
        for mas in self.master_packages:
            if mas in self.dependencies:
                self.master_packages.remove(mas)

    def matching(self):
        """Return found matching SBo packages
        """
        for sbo in self.package_not_found:
            for pkg in self.data:
                if sbo in pkg and pkg not in self.blacklist:
                    self.package_found.append(pkg)

    def sbo_version_source(self, slackbuilds):
        """Create sbo name with version
        """
        sbo_versions, sources = [], []
        for sbo in slackbuilds:
            status(0.02)
            sbo_ver = "{0}-{1}".format(sbo, SBoGrep(sbo).version())
            sbo_versions.append(sbo_ver)
            sources.append(SBoGrep(sbo).source())
        return [sbo_versions, sources]

    def one_for_all(self, deps):
        """Because there are dependencies that depend on other
        dependencies are created lists into other lists.
        Thus creating this loop create one-dimensional list and
        remove double packages from dependencies.
        """
        requires, dependencies = [], []
        deps.reverse()
        # Inverting the list brings the
        # dependencies in order to be installed.
        requires = Utils().dimensional_list(deps)
        dependencies = Utils().remove_dbs(requires)
        return dependencies

    def top_view(self):
        """View top template
        """
        self.msg.template(78)
        print("{0}{1}{2}{3}{4}{5}{6}{7}{8}{9}{10}".format(
            "| Package", " " * 17, "New version", " " * 8, "Arch", " " * 4,
            "Build", " " * 2, "Repos", " " * 10, "Size"))
        self.msg.template(78)

    def view_packages(self, *args):
        """:View slackbuild packages with version and arch
        args[0] package color
        args[1] package
        args[2] version
        args[3] arch
        """
        ver = GetFromInstalled(args[1]).version()
        print("  {0}{1}{2}{3} {4}{5} {6}{7}{8}{9}{10}{11:>11}{12}".format(
            args[0], args[1] + ver, self.meta.color["ENDC"],
            " " * (23 - len(args[1] + ver)), args[2],
            " " * (18 - len(args[2])), args[3], " " * (15 - len(args[3])), "",
            "", "SBo", "", "")).rstrip()

    def tag(self, sbo):
        """Tag with color green if package already installed,
        color yellow for packages to upgrade and color red
        if not installed.
        """
        # split sbo name with version and get name
        sbo_name = "-".join(sbo.split("-")[:-1])
        find = GetFromInstalled(sbo_name).name()
        if find_package(sbo, self.meta.pkg_path):
            paint = self.meta.color["GREEN"]
            self.count_ins += 1
            if "--rebuild" in self.flag:
                self.count_upg += 1
        elif sbo_name == find:
            paint = self.meta.color["YELLOW"]
            self.count_upg += 1
        else:
            paint = self.meta.color["RED"]
            self.count_uni += 1
        return paint

    def select_arch(self, src):
        """Looks if sources unsupported or untested
        from arch else select arch.
        """
        arch = self.arch
        for item in self.unst:
            if item in src:
                arch = item
        return arch

    def filenames(self, sources):
        """Return filenames from sources links
        """
        filename = []
        for src in sources:
            filename.append(src.split("/")[-1])
        return filename

    def build_install(self):
        """Build and install packages if not already installed
        """
        slackbuilds = self.dependencies + self.master_packages
        installs, upgraded, = [], []
        if not os.path.exists(self.build_folder):
            os.makedirs(self.build_folder)
        if not os.path.exists(self._SOURCES):
            os.makedirs(self._SOURCES)
        os.chdir(self.build_folder)
        for prgnam in slackbuilds:
            if (self.meta.not_downgrade == "on"
                    and self.not_downgrade(prgnam) is True):
                continue
            pkg = "-".join(prgnam.split("-")[:-1])
            installed = "".join(find_package(prgnam, self.meta.pkg_path))
            src_link = SBoGrep(pkg).source().split()
            if (installed and "--download-only" not in self.flag
                    and "--rebuild" not in self.flag):
                self.msg.template(78)
                self.msg.pkg_found(prgnam)
                self.msg.template(78)
            elif self.unst[0] in src_link or self.unst[1] in src_link:
                self.msg.template(78)
                print("| Package {0} {1}{2}{3}".format(
                    prgnam, self.meta.color["RED"], "".join(src_link),
                    self.meta.color["ENDC"]))
                self.msg.template(78)
            else:
                sbo_url = sbo_search_pkg(pkg)
                sbo_link = SBoLink(sbo_url).tar_gz()
                script = sbo_link.split("/")[-1]
                if self.meta.sbosrcarch in ["on", "ON"]:
                    src_link = self.sbosrcarsh(prgnam, sbo_link, src_link)
                Download(self.build_folder, sbo_link.split(),
                         repo="sbo").start()
                Download(self._SOURCES, src_link, repo="sbo").start()
                if "--download-only" in self.flag:
                    continue
                sources = self.filenames(src_link)
                BuildPackage(script, sources, self.build_folder,
                             auto=False).build()
                binary = slack_package(prgnam)
                if os.path.isfile("".join(binary)):
                    if GetFromInstalled(pkg).name() == pkg:
                        print("[ {0}Upgrading{1} ] --> {2}".format(
                            self.meta.color["YELLOW"], self.meta.color["ENDC"],
                            prgnam))
                        upgraded.append(prgnam)
                    else:
                        print("[ {0}Installing{1} ] --> {2}".format(
                            self.meta.color["GREEN"], self.meta.color["ENDC"],
                            prgnam))
                        installs.append(prgnam)
                    if ("--rebuild" in self.flag
                            and GetFromInstalled(pkg).name() == pkg):
                        PackageManager(binary).upgrade(flag="--reinstall")
                    else:
                        PackageManager(binary).upgrade(flag="--install-new")
        return installs, upgraded

    def not_downgrade(self, prgnam):
        """Don't downgrade packages if sbo version is lower than
        installed"""
        name = "-".join(prgnam.split("-")[:-1])
        sbo_ver = prgnam.split("-")[-1]
        ins_ver = GetFromInstalled(name).version()[1:]
        if not ins_ver:
            ins_ver = "0"
        if LooseVersion(sbo_ver) < LooseVersion(ins_ver):
            self.msg.template(78)
            print("| Package {0} don't downgrade, "
                  "setting by user".format(name))
            self.msg.template(78)
            return True

    def sbosrcarsh(self, prgnam, sbo_link, src_link):
        """Alternative repository for sbo sources"""
        sources = []
        name = "-".join(prgnam.split("-")[:-1])
        category = "{0}/{1}/".format(sbo_link.split("/")[-2], name)
        for link in src_link:
            source = link.split("/")[-1]
            sources.append("{0}{1}{2}".format(self.meta.sbosrcarch_link,
                                              category, source))
        return sources
Esempio n. 2
0
class BinaryInstall(object):
    """Install binaries packages with all dependencies from
    repository
    """
    def __init__(self, packages, repo, flag):
        self.packages = packages
        pkg_security(packages)
        self.repo = repo
        self.flag = flag
        self.meta = _meta_
        self.msg = Msg()
        self.version = self.meta.slack_rel
        self.tmp_path = self.meta.slpkg_tmp_packages
        for fl in self.flag:
            if fl.startswith("--directory-prefix="):
                self.tmp_path = fl.split("=")[1]
                if not self.tmp_path.endswith("/"):
                    self.tmp_path += "/"
        self.dwn, self.dep_dwn = [], []
        self.install, self.dep_install = [], []
        self.comp_sum, self.dep_comp_sum = [], []
        self.uncomp_sum, self.dep_uncomp_sum = [], []
        self.dependencies = []
        self.deps_dict = {}
        self.answer = ""
        self.msg.reading()
        self.PACKAGES_TXT, self.mirror = RepoInit(self.repo).fetch()
        self.data = repo_data(self.PACKAGES_TXT, self.repo, self.flag)
        self.repo_pkg_names = []
        for name in self.data[0]:
            self.repo_pkg_names.append(split_package(name)[0])
        self.blacklist = BlackList().packages(self.data[0], self.repo)
        self.matching = False

    def start(self, is_upgrade):
        """
        Install packages from official Slackware distribution
        """
        self.case_insensitive()
        # fix if packages is for upgrade
        self.is_upgrade = is_upgrade
        mas_sum = dep_sum = sums = [0, 0, 0]
        self.msg.done()
        self.dependencies = self.resolving_deps()
        self.update_deps()
        (self.dep_dwn, self.dep_install, self.dep_comp_sum,
            self.dep_uncomp_sum) = self.store(self.dependencies)
        self.clear_masters()
        (self.dwn, self.install, self.comp_sum,
            self.uncomp_sum) = self.store(self.packages)
        if (self.meta.rsl_deps in ["on", "ON"] and
                "--resolve-off" not in self.flag):
            self.msg.done()
        if self.install:
            print("\nThe following packages will be automatically "
                  "installed or upgraded \nwith new version:\n")
            if self.matching:
                self.msg.matching(self.packages)
            self.top_view()
            self.msg.upg_inst(self.is_upgrade)
            mas_sum = self.views(self.install, self.comp_sum)
            if self.dependencies:
                print("Installing for dependencies:")
                dep_sum = self.views(self.dep_install, self.dep_comp_sum)
            # sums[0] --> installed
            # sums[1] --> upgraded
            # sums[2] --> uninstall
            sums = [sum(i) for i in zip(mas_sum, dep_sum)]
            unit, size = units(self.comp_sum + self.dep_comp_sum,
                               self.uncomp_sum + self.dep_uncomp_sum)
            print("\nInstalling summary")
            print("=" * 79)
            print("{0}Total {1} {2}.".format(self.meta.color["GREY"],
                                             sum(sums),
                                             self.msg.pkg(sum(sums))))
            print("{0} {1} will be installed, {2} will be upgraded and "
                  "{3} will be reinstalled.".format(sums[2],
                                                    self.msg.pkg(sums[2]),
                                                    sums[1], sums[0]))
            print("Need to get {0} {1} of archives.".format(size[0],
                                                            unit[0]))
            print("After this process, {0} {1} of additional disk "
                  "space will be used.{2}".format(size[1], unit[1],
                                                  self.meta.color["ENDC"]))
            print("")
            self.if_all_installed()
            if self.msg.answer() in ["y", "Y"]:
                for inst, dwn in zip(self.dep_install + self.install,
                                     self.dep_dwn + self.dwn):
                    if (self.meta.not_downgrade == "on" and
                            self.not_downgrade(inst) is True):
                        continue
                    if (not os.path.isfile(self.meta.pkg_path + inst[:-4]) or
                            "--download-only" in self.flag or
                            "--reinstall" in self.flag):
                        Download(self.tmp_path, dwn.split(), self.repo).start()
                    else:
                        self.msg.template(78)
                        self.msg.pkg_found(inst)
                        self.msg.template(78)
                if "--download-only" in self.flag:
                    raise SystemExit()
                self.dep_install = Utils().check_downloaded(
                    self.tmp_path, self.dep_install)
                self.install = Utils().check_downloaded(
                    self.tmp_path, self.install)
                ins, upg = self.install_packages()
                self.msg.reference(ins, upg)
                write_deps(self.deps_dict)
                delete_package(self.tmp_path, self.dep_install + self.install)
        else:
            self.msg.not_found(self.is_upgrade)
            raise SystemExit(1)

    def if_all_installed(self):
        """Check if all packages is already installed
        """
        count_inst = 0
        for inst in (self.dep_install + self.install):
            if (os.path.isfile(self.meta.pkg_path + inst[:-4]) and
                    "--download-only" not in self.flag):
                count_inst += 1
        if (count_inst == len(self.dep_install + self.install) and
                "--reinstall" not in self.flag):
            raise SystemExit()

    def case_insensitive(self):
        """Matching packages distinguish between uppercase and
        lowercase
        """
        if "--case-ins" in self.flag:
            data = []
            data = Utils().package_name(self.PACKAGES_TXT)
            data_dict = Utils().case_sensitive(data)
            for pkg in self.packages:
                index = self.packages.index(pkg)
                for key, value in data_dict.iteritems():
                    if key == pkg.lower():
                        self.packages[index] = value

    def update_deps(self):
        """Update dependencies dictionary with all package
        """
        for dep in self.dependencies:
            deps = Utils().dimensional_list(Dependencies(
                self.repo, self.blacklist).binary(
                    dep, self.flag))
            self.deps_dict[dep] = deps

    def clear_masters(self):
        """Clear master packages if already exist in dependencies
        or if added to install two or more times
        """
        packages = []
        for mas in Utils().remove_dbs(self.packages):
            if mas not in self.dependencies:
                packages.append(mas)
        self.packages = packages

    def install_packages(self):
        """Install or upgrade packages
        """
        installs, upgraded = [], []
        for inst in (self.dep_install + self.install):
            package = (self.tmp_path + inst).split()
            pkg_ver = "{0}-{1}".format(split_package(inst)[0],
                                       split_package(inst)[1])
            self.checksums(inst)
            if GetFromInstalled(split_package(inst)[0]).name():
                print("[ {0}upgrading{1} ] --> {2}".format(
                    self.meta.color["YELLOW"], self.meta.color["ENDC"], inst))
                upgraded.append(pkg_ver)
                if "--reinstall" in self.flag:
                    PackageManager(package).upgrade("--reinstall")
                else:
                    PackageManager(package).upgrade("--install-new")
            else:
                print("[ {0}installing{1} ] --> {2}".format(
                    self.meta.color["GREEN"], self.meta.color["ENDC"], inst))
                installs.append(pkg_ver)
                PackageManager(package).upgrade("--install-new")
        return [installs, upgraded]

    def not_downgrade(self, package):
        """Don't downgrade packages if repository version is lower than
        installed"""
        name = split_package(package)[0]
        rep_ver = split_package(package)[1]
        ins_ver = GetFromInstalled(name).version()[1:]
        if not ins_ver:
            ins_ver = "0"
        if LooseVersion(rep_ver) < LooseVersion(ins_ver):
            self.msg.template(78)
            print("| Package {0} don't downgrade, "
                  "setting by user".format(name))
            self.msg.template(78)
            return True

    def checksums(self, install):
        """Checksums before install
        """
        check_md5(pkg_checksum(install, self.repo), self.tmp_path + install)

    def resolving_deps(self):
        """Return package dependencies
        """
        requires = []
        if (self.meta.rsl_deps in ["on", "ON"] and
                self.flag != "--resolve-off"):
            self.msg.resolving()
        for dep in self.packages:
            status(0.05)
            dependencies = []
            dependencies = Utils().dimensional_list(Dependencies(
                self.repo, self.blacklist).binary(dep, self.flag))
            requires += self._fix_deps_repos(dependencies)
            self.deps_dict[dep] = Utils().remove_dbs(requires)
        return Utils().remove_dbs(requires)

    def _fix_deps_repos(self, dependencies):
        """Fix store deps include in repository
        """
        requires = []
        for dep in dependencies:
            if dep in self.repo_pkg_names:
                requires.append(dep)
        return requires

    def views(self, install, comp_sum):
        """Views packages
        """
        pkg_sum = uni_sum = upg_sum = 0
        # fix repositories align
        repo = self.repo + (" " * (6 - (len(self.repo))))
        for pkg, comp in zip(install, comp_sum):
            pkg_repo = split_package(pkg[:-4])
            if find_package(pkg[:-4], self.meta.pkg_path):
                pkg_sum += 1
                COLOR = self.meta.color["GREEN"]
            elif pkg_repo[0] == GetFromInstalled(pkg_repo[0]).name():
                COLOR = self.meta.color["YELLOW"]
                upg_sum += 1
            else:
                COLOR = self.meta.color["RED"]
                uni_sum += 1
            ver = GetFromInstalled(pkg_repo[0]).version()
            print("  {0}{1}{2}{3} {4}{5} {6}{7}{8}{9}{10}{11:>11}{12}".format(
                COLOR, pkg_repo[0] + ver, self.meta.color["ENDC"],
                " " * (23-len(pkg_repo[0] + ver)), pkg_repo[1],
                " " * (18-len(pkg_repo[1])), pkg_repo[2],
                " " * (8-len(pkg_repo[2])), pkg_repo[3],
                " " * (7-len(pkg_repo[3])), repo,
                comp, " K")).rstrip()
        return [pkg_sum, upg_sum, uni_sum]

    def top_view(self):
        """Print packages status bar
        """
        self.msg.template(78)
        print("{0}{1}{2}{3}{4}{5}{6}{7}{8}{9}{10}".format(
            "| Package", " " * 17,
            "New Version", " " * 8,
            "Arch", " " * 4,
            "Build", " " * 2,
            "Repos", " " * 10,
            "Size"))
        self.msg.template(78)

    def store(self, packages):
        """Store and return packages for install
        """
        dwn, install, comp_sum, uncomp_sum = ([] for i in range(4))
        # name = data[0]
        # location = data[1]
        # size = data[2]
        # unsize = data[3]
        for pkg in packages:
            for pk, loc, comp, uncomp in zip(self.data[0], self.data[1],
                                             self.data[2], self.data[3]):
                if (pk and pkg == split_package(pk)[0] and
                        pk not in install and
                        split_package(pk)[0] not in self.blacklist):
                    dwn.append("{0}{1}/{2}".format(self.mirror, loc, pk))
                    install.append(pk)
                    comp_sum.append(comp)
                    uncomp_sum.append(uncomp)
        if not install:
            for pkg in packages:
                for pk, loc, comp, uncomp in zip(self.data[0], self.data[1],
                                                 self.data[2], self.data[3]):
                    name = split_package(pk)[0]
                    if (pk and pkg in name and name not in self.blacklist):
                        self.matching = True
                        dwn.append("{0}{1}/{2}".format(self.mirror, loc, pk))
                        install.append(pk)
                        comp_sum.append(comp)
                        uncomp_sum.append(uncomp)
        dwn.reverse()
        install.reverse()
        comp_sum.reverse()
        uncomp_sum.reverse()
        if self.repo == "slack":
            dwn, install, comp_sum, uncomp_sum = self.patches(dwn, install,
                                                              comp_sum,
                                                              uncomp_sum)
        return [dwn, install, comp_sum, uncomp_sum]

    def patches(self, dwn, install, comp_sum, uncomp_sum):
        """Seperates packages from patches/ directory
        """
        dwnp, installp, comp_sump, uncomp_sump = ([] for i in range(4))
        for d, i, c, u in zip(dwn, install, comp_sum, uncomp_sum):
            if "_slack" + slack_ver() in i:
                dwnp.append(d)
                dwn.remove(d)
                installp.append(i)
                install.remove(i)
                comp_sump.append(c)
                comp_sum.remove(c)
                uncomp_sump.append(u)
                uncomp_sum.remove(u)
        if "--patches" in self.flag:
            return dwnp, installp, comp_sump, uncomp_sump
        return dwn, install, comp_sum, uncomp_sum
Esempio n. 3
0
class SBoInstall(object):
    """Build and install SBo packages with all dependencies
    """
    def __init__(self, slackbuilds, flag):
        self.slackbuilds = slackbuilds
        pkg_security(self.slackbuilds)
        self.flag = flag
        self.meta = _meta_
        self.msg = Msg()
        self.arch = SBoArch().get()
        self.build_folder = self.meta.build_path
        self._SOURCES = self.meta.SBo_SOURCES
        for fl in self.flag:
            if fl.startswith("--directory-prefix="):
                self.build_folder = fl.split("=")[1]
                if not self.build_folder.endswith("/"):
                    self.build_folder += "/"
        self.unst = ["UNSUPPORTED", "UNTESTED"]
        self.master_packages = []
        self.deps = []
        self.dependencies = []
        self.package_not_found = []
        self.package_found = []
        self.deps_dict = {}
        self.answer = ""
        self.match = False
        self.count_ins = 0
        self.count_upg = 0
        self.count_uni = 0
        self.msg.reading()
        self.data = SBoGrep(name="").names()
        self.blacklist = BlackList().packages(pkgs=self.data, repo="sbo")

    def start(self, is_upgrade):
        """Start view, build and install SBo packages
        """
        tagc = ""
        self.is_upgrade = is_upgrade
        self.case_insensitive()
        for _sbo in self.slackbuilds:
            status(0.03)
            if _sbo in self.data and _sbo not in self.blacklist:
                sbo_deps = Requires(self.flag).sbo(_sbo)
                self.deps += sbo_deps
                self.deps_dict[_sbo] = self.one_for_all(sbo_deps)
                self.package_found.append(_sbo)
            else:
                self.package_not_found.append(_sbo)
        self.update_deps()

        if not self.package_found:
            self.match = True
            self.matching()

        self.master_packages, mas_src = self.sbo_version_source(
            self.package_found)
        self.msg.done()
        if (self.meta.rsl_deps in ["on", "ON"] and
                self.flag != "--resolve-off" and not self.match):
            self.msg.resolving()
        self.dependencies, dep_src = self.sbo_version_source(
            self.one_for_all(self.deps))
        if (self.meta.rsl_deps in ["on", "ON"] and
                self.flag != "--resolve-off" and not self.match):
            self.msg.done()
        self.clear_masters()

        if self.package_found:
            if self.match and [""] != self.slackbuilds:
                self.msg.matching(self.slackbuilds)
            else:
                print("\nThe following packages will be automatically "
                      "installed or upgraded \nwith new version:\n")
            self.top_view()
            self.msg.upg_inst(self.is_upgrade)

            # view master packages
            for sbo, arch in zip(self.master_packages, mas_src):
                tagc = self.tag(sbo)
                name = "-".join(sbo.split("-")[:-1])
                self.view_packages(tagc, name, sbo.split("-")[-1],
                                   self.select_arch(arch))
            self.view_installing_for_deps()

            # view dependencies
            for dep, arch in zip(self.dependencies, dep_src):
                tagc = self.tag(dep)
                name = "-".join(dep.split("-")[:-1])
                self.view_packages(tagc, name, dep.split("-")[-1],
                                   self.select_arch(arch))

            count_total = sum([self.count_ins, self.count_upg,
                               self.count_uni])
            if self.match and [""] != self.slackbuilds:
                print("\nMatching summary")
                print("=" * 79)
                print("Total {0} matching packages\n".format(count_total))
                raise SystemExit(1)
            print("\nInstalling summary")
            print("=" * 79)
            print("{0}Total {1} {2}.".format(
                self.meta.color["GREY"], count_total,
                self.msg.pkg(count_total)))
            print("{0} {1} will be installed, {2} already installed and "
                  "{3} {4}".format(self.count_uni,
                                   self.msg.pkg(self.count_uni),
                                   self.count_ins, self.count_upg,
                                   self.msg.pkg(self.count_upg)))
            print("will be upgraded.{0}\n".format(self.meta.color["ENDC"]))
            self.continue_to_install()
        else:
            self.msg.not_found(self.is_upgrade)
            raise SystemExit(1)

    def case_insensitive(self):
        """Matching packages distinguish between uppercase and
        lowercase
        """
        if "--case-ins" in self.flag:
            data_dict = Utils().case_sensitive(self.data)
            for name in self.slackbuilds:
                index = self.slackbuilds.index(name)
                for key, value in data_dict.iteritems():
                    if key == name.lower():
                        self.slackbuilds[index] = value

    def update_deps(self):
        """Update dependencies dictionary with all package
        """
        onelist, dependencies = [], []
        onelist = Utils().dimensional_list(self.deps)
        dependencies = Utils().remove_dbs(onelist)
        for dep in dependencies:
            deps = Requires(self.flag).sbo(dep)
            self.deps_dict[dep] = self.one_for_all(deps)

    def continue_to_install(self):
        """Continue to install ?
        """
        if (self.count_uni > 0 or self.count_upg > 0 or
                "--download-only" in self.flag or "--rebuild" in self.flag):
            if self.master_packages and self.msg.answer() in ["y", "Y"]:
                installs, upgraded = self.build_install()
                if "--download-only" in self.flag:
                    raise SystemExit()
                self.msg.reference(installs, upgraded)
                write_deps(self.deps_dict)
                delete(self.build_folder)

    def view_installing_for_deps(self):
        """View installing message for dependencies
        """
        if not self.match and self.dependencies:
            print("Installing for dependencies:")

    def clear_masters(self):
        """Clear master slackbuilds if already exist in dependencies
        or if added to install two or more times
        """
        self.master_packages = Utils().remove_dbs(self.master_packages)
        for mas in self.master_packages:
            if mas in self.dependencies:
                self.master_packages.remove(mas)

    def matching(self):
        """Return found matching SBo packages
        """
        for sbo in self.package_not_found:
            for pkg in self.data:
                if sbo in pkg and pkg not in self.blacklist:
                    self.package_found.append(pkg)

    def sbo_version_source(self, slackbuilds):
        """Create sbo name with version
        """
        sbo_versions, sources = [], []
        for sbo in slackbuilds:
            status(0.02)
            sbo_ver = "{0}-{1}".format(sbo, SBoGrep(sbo).version())
            sbo_versions.append(sbo_ver)
            sources.append(SBoGrep(sbo).source())
        return [sbo_versions, sources]

    def one_for_all(self, deps):
        """Because there are dependencies that depend on other
        dependencies are created lists into other lists.
        Thus creating this loop create one-dimensional list and
        remove double packages from dependencies.
        """
        requires, dependencies = [], []
        deps.reverse()
        # Inverting the list brings the
        # dependencies in order to be installed.
        requires = Utils().dimensional_list(deps)
        dependencies = Utils().remove_dbs(requires)
        return dependencies

    def top_view(self):
        """View top template
        """
        self.msg.template(78)
        print("{0}{1}{2}{3}{4}{5}{6}{7}{8}{9}{10}".format(
            "| Package", " " * 17,
            "New version", " " * 8,
            "Arch", " " * 4,
            "Build", " " * 2,
            "Repos", " " * 10,
            "Size"))
        self.msg.template(78)

    def view_packages(self, *args):
        """:View slackbuild packages with version and arch
        args[0] package color
        args[1] package
        args[2] version
        args[3] arch
        """
        ver = GetFromInstalled(args[1]).version()
        print("  {0}{1}{2}{3} {4}{5} {6}{7}{8}{9}{10}{11:>11}{12}".format(
            args[0], args[1] + ver, self.meta.color["ENDC"],
            " " * (23-len(args[1] + ver)), args[2],
            " " * (18-len(args[2])), args[3],
            " " * (15-len(args[3])), "",
            "", "SBo", "", "")).rstrip()

    def tag(self, sbo):
        """Tag with color green if package already installed,
        color yellow for packages to upgrade and color red
        if not installed.
        """
        # split sbo name with version and get name
        sbo_name = "-".join(sbo.split("-")[:-1])
        find = GetFromInstalled(sbo_name).name()
        if find_package(sbo, self.meta.pkg_path):
            paint = self.meta.color["GREEN"]
            self.count_ins += 1
            if "--rebuild" in self.flag:
                self.count_upg += 1
        elif sbo_name == find:
            paint = self.meta.color["YELLOW"]
            self.count_upg += 1
        else:
            paint = self.meta.color["RED"]
            self.count_uni += 1
        return paint

    def select_arch(self, src):
        """Looks if sources unsupported or untested
        from arch else select arch.
        """
        arch = self.arch
        for item in self.unst:
            if item in src:
                arch = item
        return arch

    def filenames(self, sources):
        """Return filenames from sources links
        """
        filename = []
        for src in sources:
            filename.append(src.split("/")[-1])
        return filename

    def build_install(self):
        """Build and install packages if not already installed
        """
        slackbuilds = self.dependencies + self.master_packages
        installs, upgraded, = [], []
        if not os.path.exists(self.build_folder):
            os.makedirs(self.build_folder)
        if not os.path.exists(self._SOURCES):
            os.makedirs(self._SOURCES)
        os.chdir(self.build_folder)
        for prgnam in slackbuilds:
            if (self.meta.not_downgrade == "on" and
                    self.not_downgrade(prgnam) is True):
                continue
            pkg = "-".join(prgnam.split("-")[:-1])
            installed = "".join(find_package(prgnam, self.meta.pkg_path))
            src_link = SBoGrep(pkg).source().split()
            if (installed and "--download-only" not in self.flag and
                    "--rebuild" not in self.flag):
                self.msg.template(78)
                self.msg.pkg_found(prgnam)
                self.msg.template(78)
            elif self.unst[0] in src_link or self.unst[1] in src_link:
                self.msg.template(78)
                print("| Package {0} {1}{2}{3}".format(
                    prgnam, self.meta.color["RED"], "".join(src_link),
                    self.meta.color["ENDC"]))
                self.msg.template(78)
            else:
                sbo_url = sbo_search_pkg(pkg)
                sbo_link = SBoLink(sbo_url).tar_gz()
                script = sbo_link.split("/")[-1]
                if self.meta.sbosrcarch in ["on", "ON"]:
                    src_link = self.sbosrcarsh(prgnam, sbo_link, src_link)
                Download(self.build_folder, sbo_link.split(),
                         repo="sbo").start()
                Download(self._SOURCES, src_link, repo="sbo").start()
                if "--download-only" in self.flag:
                    continue
                sources = self.filenames(src_link)
                BuildPackage(script, sources, self.build_folder,
                             auto=False).build()
                binary = slack_package(prgnam)
                if os.path.isfile("".join(binary)):
                    if GetFromInstalled(pkg).name() == pkg:
                        print("[ {0}Upgrading{1} ] --> {2}".format(
                            self.meta.color["YELLOW"],
                            self.meta.color["ENDC"], prgnam))
                        upgraded.append(prgnam)
                    else:
                        print("[ {0}Installing{1} ] --> {2}".format(
                            self.meta.color["GREEN"],
                            self.meta.color["ENDC"], prgnam))
                        installs.append(prgnam)
                    if ("--rebuild" in self.flag and
                            GetFromInstalled(pkg).name() == pkg):
                        PackageManager(binary).upgrade(flag="--reinstall")
                    else:
                        PackageManager(binary).upgrade(flag="--install-new")
        return installs, upgraded

    def not_downgrade(self, prgnam):
        """Don't downgrade packages if sbo version is lower than
        installed"""
        name = "-".join(prgnam.split("-")[:-1])
        sbo_ver = prgnam.split("-")[-1]
        ins_ver = GetFromInstalled(name).version()[1:]
        if not ins_ver:
            ins_ver = "0"
        if LooseVersion(sbo_ver) < LooseVersion(ins_ver):
            self.msg.template(78)
            print("| Package {0} don't downgrade, "
                  "setting by user".format(name))
            self.msg.template(78)
            return True

    def sbosrcarsh(self, prgnam, sbo_link, src_link):
        """Alternative repository for sbo sources"""
        sources = []
        name = "-".join(prgnam.split("-")[:-1])
        category = "{0}/{1}/".format(sbo_link.split("/")[-2], name)
        for link in src_link:
            source = link.split("/")[-1]
            sources.append("{0}{1}{2}".format(self.meta.sbosrcarch_link,
                                              category, source))
        return sources
Esempio n. 4
0
class BinaryInstall(object):
    """Install binaries packages with all dependencies from
    repository
    """
    def __init__(self, packages, repo, flag):
        self.packages = packages
        pkg_security(packages)
        self.repo = repo
        self.flag = flag
        self.meta = _meta_
        self.msg = Msg()
        self.version = self.meta.slack_rel
        self.tmp_path = self.meta.slpkg_tmp_packages
        for fl in self.flag:
            if fl.startswith("--directory-prefix="):
                self.tmp_path = fl.split("=")[1]
                if not self.tmp_path.endswith("/"):
                    self.tmp_path += "/"
        self.dwn, self.dep_dwn = [], []
        self.install, self.dep_install = [], []
        self.comp_sum, self.dep_comp_sum = [], []
        self.uncomp_sum, self.dep_uncomp_sum = [], []
        self.dependencies = []
        self.deps_dict = {}
        self.answer = ""
        self.msg.reading()
        self.PACKAGES_TXT, self.mirror = RepoInit(self.repo).fetch()
        self.data = repo_data(self.PACKAGES_TXT, self.repo, self.flag)
        self.repo_pkg_names = []
        for name in self.data[0]:
            self.repo_pkg_names.append(split_package(name)[0])
        self.blacklist = BlackList().packages(self.data[0], self.repo)
        self.matching = False

    def start(self, is_upgrade):
        """
        Install packages from official Slackware distribution
        """
        self.case_insensitive()
        # fix if packages is for upgrade
        self.is_upgrade = is_upgrade
        mas_sum = dep_sum = sums = [0, 0, 0]
        self.msg.done()
        self.dependencies = self.resolving_deps()
        self.update_deps()
        (self.dep_dwn, self.dep_install, self.dep_comp_sum,
            self.dep_uncomp_sum) = self.store(self.dependencies)
        self.clear_masters()
        (self.dwn, self.install, self.comp_sum,
            self.uncomp_sum) = self.store(self.packages)
        if (self.meta.rsl_deps in ["on", "ON"] and
                "--resolve-off" not in self.flag):
            self.msg.done()
        if self.install:
            if self.matching and [""] != self.packages:
                self.msg.matching(self.packages)
            else:
                print("\nThe following packages will be automatically "
                      "installed or upgraded \nwith new version:\n")
            self.top_view()
            self.msg.upg_inst(self.is_upgrade)
            mas_sum = self.views(self.install, self.comp_sum)
            if self.dependencies:
                print("Installing for dependencies:")
                dep_sum = self.views(self.dep_install, self.dep_comp_sum)
            # sums[0] --> installed
            # sums[1] --> upgraded
            # sums[2] --> uninstall
            sums = [sum(i) for i in zip(mas_sum, dep_sum)]
            unit, size = units(self.comp_sum + self.dep_comp_sum,
                               self.uncomp_sum + self.dep_uncomp_sum)
            if self.matching and [""] != self.packages:
                print("\nMatching summary")
                print("=" * 79)
                print("Total {0} matching packages\n".format(sum(sums)))
                raise SystemExit(1)
            print("\nInstalling summary")
            print("=" * 79)
            print("{0}Total {1} {2}.".format(self.meta.color["GREY"],
                                             sum(sums),
                                             self.msg.pkg(sum(sums))))
            print("{0} {1} will be installed, {2} will be upgraded and "
                  "{3} will be reinstalled.".format(sums[2],
                                                    self.msg.pkg(sums[2]),
                                                    sums[1], sums[0]))
            print("Need to get {0} {1} of archives.".format(size[0],
                                                            unit[0]))
            print("After this process, {0} {1} of additional disk "
                  "space will be used.{2}".format(size[1], unit[1],
                                                  self.meta.color["ENDC"]))
            print("")
            self.if_all_installed()
            if self.msg.answer() in ["y", "Y"]:
                for inst, dwn in zip(self.dep_install + self.install,
                                     self.dep_dwn + self.dwn):
                    if (self.meta.not_downgrade == "on" and
                            self.not_downgrade(inst) is True):
                        continue
                    if (not os.path.isfile(self.meta.pkg_path + inst[:-4]) or
                            "--download-only" in self.flag or
                            "--reinstall" in self.flag):
                        Download(self.tmp_path, dwn.split(), self.repo).start()
                    else:
                        self.msg.template(78)
                        self.msg.pkg_found(inst)
                        self.msg.template(78)
                if "--download-only" in self.flag:
                    raise SystemExit()
                self.dep_install = Utils().check_downloaded(
                    self.tmp_path, self.dep_install)
                self.install = Utils().check_downloaded(
                    self.tmp_path, self.install)
                ins, upg = self.install_packages()
                self.msg.reference(ins, upg)
                write_deps(self.deps_dict)
                delete_package(self.tmp_path, self.dep_install + self.install)
        else:
            self.msg.not_found(self.is_upgrade)
            raise SystemExit(1)

    def if_all_installed(self):
        """Check if all packages is already installed
        """
        count_inst = 0
        for inst in (self.dep_install + self.install):
            if (os.path.isfile(self.meta.pkg_path + inst[:-4]) and
                    "--download-only" not in self.flag):
                count_inst += 1
        if (count_inst == len(self.dep_install + self.install) and
                "--reinstall" not in self.flag):
            raise SystemExit()

    def case_insensitive(self):
        """Matching packages distinguish between uppercase and
        lowercase
        """
        if "--case-ins" in self.flag:
            data = []
            data = Utils().package_name(self.PACKAGES_TXT)
            data_dict = Utils().case_sensitive(data)
            for pkg in self.packages:
                index = self.packages.index(pkg)
                for key, value in data_dict.iteritems():
                    if key == pkg.lower():
                        self.packages[index] = value

    def update_deps(self):
        """Update dependencies dictionary with all package
        """
        for dep in self.dependencies:
            deps = Utils().dimensional_list(Dependencies(
                self.repo, self.blacklist).binary(
                    dep, self.flag))
            self.deps_dict[dep] = deps

    def clear_masters(self):
        """Clear master packages if already exist in dependencies
        or if added to install two or more times
        """
        packages = []
        for mas in Utils().remove_dbs(self.packages):
            if mas not in self.dependencies:
                packages.append(mas)
        self.packages = packages

    def install_packages(self):
        """Install or upgrade packages
        """
        installs, upgraded = [], []
        for inst in (self.dep_install + self.install):
            package = (self.tmp_path + inst).split()
            pkg_ver = "{0}-{1}".format(split_package(inst)[0],
                                       split_package(inst)[1])
            self.checksums(inst)
            if GetFromInstalled(split_package(inst)[0]).name():
                print("[ {0}upgrading{1} ] --> {2}".format(
                    self.meta.color["YELLOW"], self.meta.color["ENDC"], inst))
                upgraded.append(pkg_ver)
                if "--reinstall" in self.flag:
                    PackageManager(package).upgrade("--reinstall")
                else:
                    PackageManager(package).upgrade("--install-new")
            else:
                print("[ {0}installing{1} ] --> {2}".format(
                    self.meta.color["GREEN"], self.meta.color["ENDC"], inst))
                installs.append(pkg_ver)
                PackageManager(package).upgrade("--install-new")
        return [installs, upgraded]

    def not_downgrade(self, package):
        """Don't downgrade packages if repository version is lower than
        installed"""
        name = split_package(package)[0]
        rep_ver = split_package(package)[1]
        ins_ver = GetFromInstalled(name).version()[1:]
        if not ins_ver:
            ins_ver = "0"
        if LooseVersion(rep_ver) < LooseVersion(ins_ver):
            self.msg.template(78)
            print("| Package {0} don't downgrade, "
                  "setting by user".format(name))
            self.msg.template(78)
            return True

    def checksums(self, install):
        """Checksums before install
        """
        check_md5(pkg_checksum(install, self.repo), self.tmp_path + install)

    def resolving_deps(self):
        """Return package dependencies
        """
        requires = []
        if (self.meta.rsl_deps in ["on", "ON"] and
                self.flag != "--resolve-off"):
            self.msg.resolving()
        for dep in self.packages:
            status(0.05)
            dependencies = []
            dependencies = Utils().dimensional_list(Dependencies(
                self.repo, self.blacklist).binary(dep, self.flag))
            requires += self._fix_deps_repos(dependencies)
            self.deps_dict[dep] = Utils().remove_dbs(requires)
        return Utils().remove_dbs(requires)

    def _fix_deps_repos(self, dependencies):
        """Fix store deps include in repository
        """
        requires = []
        for dep in dependencies:
            if dep in self.repo_pkg_names:
                requires.append(dep)
        return requires

    def views(self, install, comp_sum):
        """Views packages
        """
        pkg_sum = uni_sum = upg_sum = 0
        # fix repositories align
        repo = self.repo + (" " * (6 - (len(self.repo))))
        for pkg, comp in zip(install, comp_sum):
            pkg_repo = split_package(pkg[:-4])
            if find_package(pkg[:-4], self.meta.pkg_path):
                pkg_sum += 1
                COLOR = self.meta.color["GREEN"]
            elif pkg_repo[0] == GetFromInstalled(pkg_repo[0]).name():
                COLOR = self.meta.color["YELLOW"]
                upg_sum += 1
            else:
                COLOR = self.meta.color["RED"]
                uni_sum += 1
            ver = GetFromInstalled(pkg_repo[0]).version()
            print("  {0}{1}{2}{3} {4}{5} {6}{7}{8}{9}{10}{11:>11}{12}".format(
                COLOR, pkg_repo[0] + ver, self.meta.color["ENDC"],
                " " * (23-len(pkg_repo[0] + ver)), pkg_repo[1],
                " " * (18-len(pkg_repo[1])), pkg_repo[2],
                " " * (8-len(pkg_repo[2])), pkg_repo[3],
                " " * (7-len(pkg_repo[3])), repo,
                comp, " K")).rstrip()
        return [pkg_sum, upg_sum, uni_sum]

    def top_view(self):
        """Print packages status bar
        """
        self.msg.template(78)
        print("{0}{1}{2}{3}{4}{5}{6}{7}{8}{9}{10}".format(
            "| Package", " " * 17,
            "New Version", " " * 8,
            "Arch", " " * 4,
            "Build", " " * 2,
            "Repos", " " * 10,
            "Size"))
        self.msg.template(78)

    def store(self, packages):
        """Store and return packages for install
        """
        dwn, install, comp_sum, uncomp_sum = ([] for i in range(4))
        # name = data[0]
        # location = data[1]
        # size = data[2]
        # unsize = data[3]
        for pkg in packages:
            for pk, loc, comp, uncomp in zip(self.data[0], self.data[1],
                                             self.data[2], self.data[3]):
                if (pk and pkg == split_package(pk)[0] and
                        pk not in install and
                        split_package(pk)[0] not in self.blacklist):
                    dwn.append("{0}{1}/{2}".format(self.mirror, loc, pk))
                    install.append(pk)
                    comp_sum.append(comp)
                    uncomp_sum.append(uncomp)
        if not install:
            for pkg in packages:
                for pk, loc, comp, uncomp in zip(self.data[0], self.data[1],
                                                 self.data[2], self.data[3]):
                    name = split_package(pk)[0]
                    if (pk and pkg in name and name not in self.blacklist):
                        self.matching = True
                        dwn.append("{0}{1}/{2}".format(self.mirror, loc, pk))
                        install.append(pk)
                        comp_sum.append(comp)
                        uncomp_sum.append(uncomp)
        dwn.reverse()
        install.reverse()
        comp_sum.reverse()
        uncomp_sum.reverse()
        if self.repo == "slack":
            dwn, install, comp_sum, uncomp_sum = self.patches(dwn, install,
                                                              comp_sum,
                                                              uncomp_sum)
        return [dwn, install, comp_sum, uncomp_sum]

    def patches(self, dwn, install, comp_sum, uncomp_sum):
        """Seperates packages from patches/ directory
        """
        dwnp, installp, comp_sump, uncomp_sump = ([] for i in range(4))
        for d, i, c, u in zip(dwn, install, comp_sum, uncomp_sum):
            if "_slack" + slack_ver() in i:
                dwnp.append(d)
                dwn.remove(d)
                installp.append(i)
                install.remove(i)
                comp_sump.append(c)
                comp_sum.remove(c)
                uncomp_sump.append(u)
                uncomp_sum.remove(u)
        if "--patches" in self.flag:
            return dwnp, installp, comp_sump, uncomp_sump
        return dwn, install, comp_sum, uncomp_sum