def print_history(self): ordered_history = [_("Inary Transaction History: ")] for operation in self.historydb.get_last(ctx.get_option('last')): msg_oprt = util.colorize(_("Operation "), 'yellow') \ + util.colorize("#{}: ".format(operation.no), "blue") \ + util.colorize("{}:".format(opttrans[operation.type]), "white") date_and_time = util.colorize( _("Date: "), "cyan") + "{0.date} {0.time}".format(operation) ordered_history.append(msg_oprt) ordered_history.append(date_and_time) if operation.type == "snapshot": msg_snap = util.colorize( _(" * There are {} packages in this snapshot.").format(len(operation.packages)), "purple") ordered_history.append(msg_snap) elif operation.type == "repoupdate": for repo in operation.repos: ordered_history.append(" * " + repo.name) else: for pkg in operation.packages: ordered_history.append(" * " + pkg.name) return ordered_history
def info(self, msg, verbose=False, noln=False, color='default'): # TODO: need to look at more kinds of info messages # let's cheat from KDE :) msg = util.colorize(msg, color) if verbose: msg = util.colorize(_('Verboses: '), 'brightwhite') + msg if not noln: msg = '{}\n'.format(msg) self.output(str(msg), verbose=verbose)
def error(self, msg): msg = str(msg) self.errors += 1 if ctx.log: ctx.log.error(msg) if ctx.get_option('no_color'): self.output(_('Error: ') + msg + '\n', err=True) else: self.output(util.colorize(msg + '\n', 'brightred'), err=True)
def print_packages(self, repo): component = ctx.get_option('component') if component: try: packages = self.componentdb.get_packages(component, repo=repo, walk=True) except BaseException: return else: packages = self.packagedb.list_packages(repo) installed_list = inary.db.installdb.InstallDB().list_installed() # maxlen is defined dynamically from the longest package name (#9021) if packages: maxlen = max([len(_p) for _p in packages]) packages.sort() for p in packages: if ctx.config.get_option('uninstalled') and p in installed_list: continue pkgname = "" pkgsum = self.packagedb.get_summary(p, repo) if p in installed_list: pkgname = util.colorize(p, 'green') else: pkgname = util.colorize(p, 'brightwhite') # if self.options.long: # package = self.packagedb.get_package(p) # inst_info = self.packagedb.get_info(p) # ctx.ui.info(str(package)) # ctx.ui.info(str(inst_info)) if self.options.name_only: ctx.ui.info(str(pkgname)) else: pkgname += ' ' * max(0, maxlen - len(p)) ctx.ui.info('{0} - {1} '.format(pkgname, str(pkgsum)))
def info(self, msg, verbose=False, noln=False, color='default'): # TODO: need to look at more kinds of info messages # let's cheat from KDE :) msg = util.colorize(msg, color) if not noln: msg = '{}\n'.format(msg) if verbose: self.verbose(msg) else: self.output(msg)
def warning(self, msg, verbose=False): msg = str(msg) self.warnings += 1 if ctx.log: ctx.log.warning(msg) if ctx.get_option('no_color'): self.output(_('Warning: ') + msg + '\n', err=True, verbose=verbose) else: self.output(util.colorize(msg + '\n', 'brightyellow'), err=True, verbose=verbose)
def choose(self, msg, opts): msg = str(msg) prompt = "" for opt in opts: prompt += util.colorize('[ {} ]\n'.format(opt), 'faintblue') while True: s = input(prompt) for opt in opts: if opt.startswith(str(s)): return opt
def commands_string(): s = '' lst = sorted([x.name[0] for x in Command.cmd]) for name in lst: commandcls = Command.cmd_dict[name] trans = gettext.translation('inary', fallback=True) summary = trans.gettext(commandcls.__doc__).split('\n')[0] name = _(commandcls.name[0]) if commandcls.name[1]: name += ' ({})'.format(commandcls.name[1]) s += util.colorize(' %23s ' % name, 'red') + '- %s\n' % summary return s
def run_command(self, func): """Run postOps scripts""" if os.path.exists(self.specdir + "/" + ctx.const.postops[1]): curDir = os.getcwd() os.chdir(self.specdir) cmd_extra = "" # FIXME: translate support needed if ctx.config.get_option('debug'): ctx.ui.info( util.colorize("Running => {}", 'brightgreen').format( util.colorize(func, "brightyellow"))) else: cmd_extra = " > /dev/null" ret_val = os.system( 'bash --noprofile --norc -c \'source postoperations.sh ; if declare -F {0} &>/dev/null ; then {0} ; fi\'' .format(func) + cmd_extra) os.chdir(curDir) if (ret_val != 0): return False if os.path.exists(self.specdir + "/" + ctx.const.postops[0]): curDir = os.getcwd() os.chdir(self.specdir) cmd_extra = "" # FIXME: translate support needed if ctx.config.get_option('debug'): ctx.ui.info( util.colorize("Running => {}", 'brightgreen').format( util.colorize(func, "brightyellow"))) else: cmd_extra = " > /dev/null" ret_val = os.system( 'python3 -c \'import postoperations\nif(hasattr(postoperations,"{0}")):\n postoperations.{0}()\'' .format(func) + cmd_extra) os.chdir(curDir) if (ret_val != 0): return False return True
def system(command): # command an list but should be an str sys.stdout.write( colorize(_("[Running Command]: "), 'brightwhite') + command + "\n") # command = str.join(str.split(command)) retValue = run_logged(command) # if return value is different than 0, it means error, raise exception if retValue != 0: error( _("ActionsAPI [system]: Command \'{0}\' failed, return value was {1}." ).format(command, retValue)) return retValue
def print_packages(self, repo): component = ctx.get_option('component') if component: try: l = self.componentdb.get_packages(component, repo=repo, walk=True) except: return else: l = inary.db.packagedb.PackageDB().list_packages(repo) installed_list = inary.db.installdb.InstallDB().list_installed() # maxlen is defined dynamically from the longest package name (#9021) if l: maxlen = max([len(_p) for _p in l]) l.sort() for p in l: if ctx.config.get_option('uninstalled') and p in installed_list: continue package = self.packagedb.get_package(p, repo) if p in installed_list: package.name = util.colorize(package.name, 'green') else: package.name = util.colorize(package.name, 'brightwhite') if self.options.long: ctx.ui.info(str(package) + '\n') else: package.name += ' ' * max(0, maxlen - len(p)) ctx.ui.info('{0} - {1} '.format(package.name, str(package.summary)))
def print_history(self): for operation in self.historydb.get_last(ctx.get_option('last')): msg_oprt = util.colorize(_("Operation "), 'yellow') \ + util.colorize("#{}: ".format(operation.no), "blue") \ + util.colorize("{}:".format(opttrans[operation.type]), "white") date_and_time = util.colorize(_("Date: "), "cyan") + "{0.date} {0.time}".format(operation) print(msg_oprt) print(date_and_time) if operation.type == "snapshot": msg_snap = util.colorize( _(" * There are {} packages in this snapshot.").format(len(operation.packages)), "purple") print(msg_snap) elif operation.type == "repoupdate": for repo in operation.repos: print(" *", repo) else: for pkg in operation.packages: print(" *", pkg) print()
def confirm(self, msg, invert=False): msg = str(msg) if ctx.config.options and ctx.config.options.yes_all: return True yes_expr_nl = re.compile("^[" + _('(yes')[1].upper() + _('(yes')[1] + "]") yes_expr = re.compile("^[Yy]") tty.tcflush(sys.stdin.fileno(), 0) if invert: prompt = msg + util.colorize(" " + _('(yes'), 'red') + '/' + util.colorize( _('no)'), 'green') + ": " else: prompt = msg + util.colorize(" " + _('(yes'), 'green') + '/' + util.colorize( _('no)'), 'red') + ": " s = input(prompt) if yes_expr.search(s) or yes_expr_nl.search(s): return True else: return False
def show_changed_configs(package_dict, opt): for package in package_dict: if package_dict[package]: if ctx.ui.confirm(util.colorize( _("[?] Would you like to see changes in config files of \"{0}\" package").format( package), color='brightyellow')): for file in package_dict[package]: new_file = util.join_path( ctx.config.history_dir(), opt, package, ctx.config.dest_dir(), file) if os.path.exists(new_file): if ctx.config.options and ctx.config.options.yes_all: prompt = "1" else: ctx.ui.info( _("[*] Changes in config file: {}").format(file), color='yellow') os.system( "diff -u {0} {1} | less".format(new_file, file)) ctx.ui.info(_("[?] Select the process which will be happened:")) ctx.ui.info(_("1. Store new config file, not apply [*]")) ctx.ui.info(_("2. Apply new config file (keep old config)")) ctx.ui.info(_("3. Apply new config file (don't keep old config)")) ctx.ui.info(_("4. Delete new config file")) prompt = subprocess.getoutput("read -n 1 c ; echo $c") if prompt == "1": pass elif pprompt == "2": apply_changed_config( util.join_path( ctx.config.dest_dir(), file), new_file, keep=True) elif pprompt == "3": apply_changed_config( util.join_path( ctx.config.dest_dir(), file), new_file, keep=False) else: ctx.ui.info( _("Deleting new config file {0}").format(file), verbose=True) util.delete_file(new_file)
def run(self): self.init(database=True, write=False) sources = self.sourcedb.list_sources() if sources: maxlen = max([len(_p) for _p in sources]) installed_list = inary.db.sourcedb.SourceDB().list_sources() sources.sort() for p in sources: sf, repo = self.sourcedb.get_spec_repo(p) if self.options.long: ctx.ui.info(_('[Repository: ') + repo + ']') ctx.ui.info(str(sf.source)) else: if p in installed_list: sf.source.name = util.colorize(sf.source.name, 'cyan') sf.source.name += ' ' * max(0, maxlen - len(p)) ctx.ui.info('{0} - {1}'.format(sf.source.name, str(sf.source.summary)))
def show_changed_configs(package_dict): for package in package_dict: if package_dict[package]: if ctx.ui.confirm( util.colorize(_( "[?] Would you like to see changes in config files of \"{0}\" package" ).format(package, file), color='brightyellow')): for file in package_dict[package]: ctx.ui.info( _("[*] Changes in config file: {}").format(file), color='yellow') os.system("diff -u {0} {1} | less".format( file, file + ".newconfig-byinary")) prompt = ctx.ui.choose( _("[?] Select the process which will be happened:"), _("1. Store new config file, not apply [*]"), _("2. Apply new config file (keep old config)"), _("3. Apply new config file (don't keep old config)"), _("3. Delete new config file")) if prompt == _("1. Store new config file, not apply [*]"): pass elif prompt == _( "2. Apply new config file (keep old config)"): apply_changed_config(file, keep=True) elif prompt == _( "3. Apply new config file (don't keep old config)" ): apply_changed_config(file, keep=False) else: ctx.ui.info( _("Deleting new config file {0}").format(file), verbose=True) util.delete_file(file + ".newconfig-byinary")
def run(self, Test, retresult=True): """ Run the given test case or test suite. """ result = self.Result() startTime = time.time() Test(result) stopTime = time.time() timeTaken = stopTime - startTime if retresult == True: result.printErrors() self.stream.writeln(result.separator2) run = result.testsRun self.stream.write( util.colorize("\n\n====== COMPLATE TESTS =======\n", 'yellow')) self.stream.writeln( util.colorize( " * Runned %d test%s in %.3fs" % (run, run != 1 and "s" or "", timeTaken), 'blue')) self.stream.writeln() if not result.wasSuccessful(): failed = len(result.failures) errored = len(result.errors) todoed = len(result.todoed) success = run - (failed + errored + todoed) self.stream.write( util.colorize(" => %d Successed\n" % success, 'green')) if failed: self.stream.write( util.colorize("\n => %d Failures\n" % failed, 'red')) if errored: self.stream.write( util.colorize("\n => %d Errored\n" % errored, 'red')) if todoed: self.stream.write( util.colorize("\n => %d ToDo |" % todoed, 'yellow')) else: self.stream.writeln("Tests End Succesfull...") return result
def error(self, msg): msg = str(msg) self.errors += 1 if ctx.log: ctx.log.error(msg) self.output(util.colorize(msg + '\n', 'brightred'), err=True)
def action(self, msg, verbose=False): # TODO: this seems quite redundant? msg = str(msg) if ctx.log: ctx.log.info(msg) self.output(util.colorize(msg + '\n', 'green'))
def warning(self, msg, verbose=False): msg = str(msg) self.warnings += 1 if ctx.log: ctx.log.warning(msg) self.output(util.colorize(msg + '\n', 'brightyellow'), err=True)
def index(self, repo_uri, skip_sources=False): self.repo_dir = repo_uri packages = [] specs = [] deltas = {} ctx.ui.info(_("* Generating index tree...\n"), color="cyan") pkgs_sorted = False for fn in os.walk(repo_uri).__next__()[2]: if fn.endswith(ctx.const.delta_package_suffix) or fn.endswith( ctx.const.package_suffix): pkgpath = os.path.join(repo_uri, util.parse_package_dir_path(fn)) if not os.path.isdir(pkgpath): os.makedirs(pkgpath) ctx.ui.info( "{:80.80}\r".format(_(' -> Sorting: \"{}\"').format(fn)), noln=False if ctx.config.get_option("verbose") else True) shutil.copy2(os.path.join(repo_uri, fn), pkgpath) os.remove(os.path.join(repo_uri, fn)) pkgs_sorted = True if pkgs_sorted: ctx.ui.info("{:80.80}\r".format( util.colorize(_(' * Sorted: \"{}\"').format(fn), color="green"))) for root, dirs, files in os.walk(repo_uri): # Filter hidden directories # TODO: Add --exclude-dirs parameter to CLI and filter according # directories here dirs[:] = [d for d in dirs if not d.startswith(".")] for fn in files: if fn.endswith(ctx.const.delta_package_suffix): name = util.parse_package_name_get_name(fn) deltas.setdefault(name, []).append(os.path.join(root, fn)) elif fn.endswith(ctx.const.package_suffix): packages.append(os.path.join(root, fn)) if fn == 'components.xml': self.components.extend( add_components(os.path.join(root, fn))) if fn == 'pspec.xml' and not skip_sources: specs.append((os.path.join(root, fn), repo_uri)) if fn == 'distribution.xml': self.distribution = add_distro(os.path.join(root, fn)) if fn == 'groups.xml': self.groups.extend(add_groups(os.path.join(root, fn))) ctx.ui.info("") # Create a process pool, as many processes as the number of CPUs we # have try: obsoletes_list = list(map(str, self.distribution.obsoletes)) except AttributeError: obsoletes_list = [] if obsoletes_list: ctx.ui.info(_( " * Added obsoleted packages: [ {} ]".format(obsoletes_list)), color="blue", noln=False) pool = multiprocessing.Pool() # Before calling pool.map check if list is empty or not: python#12157 if specs: ctx.ui.info(_(" * Adding source packages: "), color="blue", noln=False) try: # Add source packages to index using a process pool self.specs = pool.map(add_spec, specs) ctx.ui.info("\n") except BaseException: # If an exception occurs (like a keyboard interrupt), # immediately terminate worker processes and propagate # exception. (CLI honors KeyboardInterrupt exception, if you're # not using CLI, you must handle KeyboardException yourself) pool.terminate() pool.join() ctx.ui.info("") raise latest_packages = [] for pkg in util.filter_latest_packages(packages): pkg_name = util.parse_package_name(os.path.basename(pkg))[0] if pkg_name.endswith(ctx.const.debug_name_suffix): pkg_name = util.remove_suffix(ctx.const.debug_name_suffix, pkg_name) if pkg_name not in obsoletes_list: # Currently, multiprocessing.Pool.map method accepts methods # with single parameters only. So we have to send our # parameters as a tuple to workaround that latest_packages.append((pkg, deltas, repo_uri)) # Before calling pool.map check if list is empty or not: python#12157 if latest_packages: sorted_pkgs = {} for pkg in latest_packages: key = re.search(r"\/((lib)?[\d\w])\/", pkg[0]) key = key.group(1) if key else os.path.dirname(pkg[0]) try: sorted_pkgs[key].append(pkg) except KeyError: sorted_pkgs[key] = [pkg] self.packages = [] ctx.ui.info(_(" * Adding binary packages: "), color="blue", noln=False) for key, pkgs in sorted(sorted_pkgs.items()): ctx.ui.info("{:80.80}\r".format( _(" -> Adding packages from directory \"{}\"... ".format( key))), noln=True) try: # Add binary packages to index using a process pool self.packages.extend(pool.map(add_package, pkgs)) except BaseException: pool.terminate() pool.join() ctx.ui.info("") raise ctx.ui.info("{:80.80}\r".format( _(" * Adding packages from directory \"{}\"... done.". format(key))), color="green", noln=False) ctx.ui.info(_("* Writing index file."), color="blue") pool.close() pool.join()
def status(self, msg=None, push_screen=True): if msg: msg = str(msg) if push_screen: self.output(util.colorize(msg + '\n', 'brightgreen')) util.xterm_title(msg)
def printErrors(self): if self.dots or self.showAll: self.stream.writeln() self.printErrorList(util.colorize('ERROR', 'red'), self.errors) self.printErrorList(util.colorize('FAIL', 'blue'), self.failures) self.printErrorList(util.colorize('TODO', 'purple'), self.todoed)
def notify(self, event, logging=True, **keywords): is_debug = False notify = True if event == inary.ui.installed: msg = _('Installed \"{}\"').format(keywords['package'].name) color = 'brightgreen' elif event == inary.ui.installing: msg = _( 'Installing \"{0.name}\", version {0.version}, release {0.release}' ).format(keywords['package']) color = 'faintblue' elif event == inary.ui.removed: msg = _('Removed \"{}\"').format(keywords['package'].name) color = 'brightgreen' elif event == inary.ui.removing: msg = _('Removing \"{}\"').format(keywords['package'].name) color = 'brightpurple' elif event == inary.ui.upgraded: msg = _('Upgraded \"{}\"').format(keywords['package'].name) color = 'brightgreen' elif event == inary.ui.configured: msg = _('Configured \"{}\"').format(keywords['package'].name) color = 'brightgreen' elif event == inary.ui.configuring: msg = _('Configuring \"{}\"').format(keywords['package'].name) color = 'faintyellow' elif event == inary.ui.extracting: msg = _('Extracting the files of \"{}\"').format( keywords['package'].name) color = 'faintgreen' elif event == inary.ui.updatingrepo: msg = _('Updating package repository: \"{}\"').format( keywords['name']) color = 'green' elif event == inary.ui.cached: total_size, total_symbol = util.human_readable_size( keywords['total']) cached_size, cached_symbol = util.human_readable_size( keywords['cached']) msg = _('Total size of package(s): {:.2f} {} / {:.2f} {}').format( cached_size, cached_symbol, total_size, total_symbol) color = 'cyan' notify = False elif event == inary.ui.packagestogo: if ctx.log: ctx.log.info( _("Following packages ordered for process: {}").format( keywords['order'])) msg = None notify = False elif event == inary.ui.desktopfile: if ctx.log: ctx.log.info( _("Extracted desktop file \"{}\"").format( keywords['desktopfile'])) msg = None elif event == inary.ui.fetched: if self.show_verbose: msg = "" else: msg = "\x1b[K" msg += _("Downloaded \"{}\"".format(keywords['name'])) color = "green" is_debug = True else: msg = None if msg: if ((not is_debug) or ctx.get_option('debug')): self.output(util.colorize(msg + '\n', color)) if ctx.log and logging: ctx.log.info(msg) if notify: self.notify(msg, push_screen=False)
def verbose(self, msg, err=False): if self.show_verbose: msg = util.colorize(_('Verboses: '), 'brightwhite') + msg self.output(msg, err)