def validate_username_string(self, username, username_clean): self.check_connection() try: const_convert_to_unicode(username.encode('utf-8')) except ( UnicodeDecodeError, UnicodeEncodeError, ): return False, 'Invalid username' if (""" in username) or ("'" in username) or ('"' in username) or \ (" " in username): return False, 'Invalid username' try: valid = self.validate_username_regex(username) except: return False, 'Username contains bad characters' if not valid: return False, 'Invalid username' exists = self.does_username_exist(username, username_clean) if exists: return False, 'Username already taken' allowed = self.is_username_allowed(username) if not allowed: return False, 'Username not allowed' return True, 'All fine'
def _show_did_you_mean(self, entropy_client, package, from_installed): """ Show "Did you mean?" results for the given package name. """ items = entropy_client.get_meant_packages( package, from_installed=from_installed) if not items: return mytxt = "%s %s %s %s %s" % ( bold(const_convert_to_unicode(" ?")), teal(_("When you wrote")), bold(const_convert_to_unicode(package)), darkgreen(_("You Meant(tm)")), teal(_("one of these below?")), ) entropy_client.output(mytxt) _cache = set() for pkg_id, repo_id in items: if from_installed: repo = entropy_client.installed_repository() else: repo = entropy_client.open_repository(repo_id) key_slot = repo.retrieveKeySlotAggregated(pkg_id) if key_slot not in _cache: entropy_client.output(enlightenatom(key_slot), header=brown(" # ")) _cache.add(key_slot)
def _show_did_you_mean(self, entropy_client, package, from_installed): """ Show "Did you mean?" results for the given package name. """ items = entropy_client.get_meant_packages( package, from_installed=from_installed) if not items: return mytxt = "%s %s %s %s %s" % ( bold(const_convert_to_unicode(" ?")), teal(_("When you wrote")), bold(const_convert_to_unicode(package)), darkgreen(_("You Meant(tm)")), teal(_("one of these below?")), ) entropy_client.output(mytxt) _cache = set() for pkg_id, repo_id in items: if from_installed: repo = entropy_client.installed_repository() else: repo = entropy_client.open_repository(repo_id) key_slot = repo.retrieveKeySlotAggregated(pkg_id) if key_slot not in _cache: entropy_client.output( enlightenatom(key_slot), header=brown(" # ")) _cache.add(key_slot)
def _description(self, entropy_client, inst_repo): """ Solo Query Description command. """ quiet = self._nsargs.quiet verbose = self._nsargs.verbose descriptions = self._nsargs.descriptions settings = entropy_client.Settings() found = False if not quiet: entropy_client.output(darkgreen(_("Description Search")), header=darkred(" @@ ")) repo_number = 0 for repo_id in entropy_client.repositories(): repo_number += 1 repo_data = settings["repositories"]["available"][repo_id] if not quiet: header = ( const_convert_to_unicode(" #") + const_convert_to_unicode(repo_number) + const_convert_to_unicode(" ") ) entropy_client.output("%s" % (bold(repo_data["description"]),), header=blue(header)) repo = entropy_client.open_repository(repo_id) found = self._search_descriptions(descriptions, entropy_client, repo, quiet, verbose) if not quiet and not found: entropy_client.output(darkgreen("%s." % (_("No matches"),)), header=darkred(" @@ ")) return 0
def _selfile(self, entropy_client): entropy_client.output( darkred( _("Please choose a file to update by typing " "its identification number."))) entropy_client.output(darkred(_("Other options are:"))) entropy_client.output(" (%s) %s" % ( blue(const_convert_to_unicode("-1")), darkgreen(_("Exit")), )) entropy_client.output(" (%s) %s" % ( blue(const_convert_to_unicode("-3")), brown(_("Automerge all the files asking you one by one")), )) entropy_client.output(" (%s) %s" % ( blue(const_convert_to_unicode("-5")), darkred(_("Automerge all the files without questioning")), )) entropy_client.output(" (%s) %s" % ( blue(const_convert_to_unicode("-7")), brown(_("Discard all the files asking you one by one")), )) entropy_client.output(" (%s) %s" % ( blue(const_convert_to_unicode("-9")), darkred(_("Discard all the files without questioning")), )) # wait user interaction try: action = readtext( _("Your choice (type a number and press enter):") + " ") except EOFError: action = None return action
def _show_license(self, uri, license_apps): """ Show selected License to User. """ tmp_fd, tmp_path = None, None try: license_text = None # get the first repo with valid license text repos = set([x.get_details().channelname for \ x in license_apps]) if not repos: return with self._entropy.rwsem().reader(): for repo_id in repos: repo = self._entropy.open_repository(repo_id) license_text = repo.retrieveLicenseText(uri) if license_text is not None: break if license_text is not None: tmp_fd, tmp_path = const_mkstemp(suffix=".txt") try: license_text = const_convert_to_unicode( license_text, enctype=etpConst['conf_encoding']) except UnicodeDecodeError: license_text = const_convert_to_unicode( license_text) with entropy.tools.codecs_fdopen( tmp_fd, "w", etpConst['conf_encoding']) as tmp_f: tmp_f.write("License: %s\n" % ( uri,)) apps = self._licenses.get(uri, []) if apps: tmp_f.write("Applications:\n") for app in apps: tmp_f.write("\t%s\n" % (app.name,)) if apps: tmp_f.write("\n") tmp_f.write("-" * 79 + "\n") tmp_f.write(license_text) tmp_f.flush() else: const_debug_write( __name__, "LicensesNotificationBox._show_license: " "not available" ) finally: if tmp_fd is not None: try: os.close(tmp_fd) except OSError: pass # leaks, but xdg-open is async if tmp_path is not None: open_url(tmp_path)
def _generate_sql(self, action, table, data, where = ''): sql = '' keys = sorted(data.keys()) if action == "update": sql += 'UPDATE %s SET ' % (self.escape_string(table),) keys_data = [] for key in keys: keys_data.append("%s = '%s'" % ( self.escape_string(key), self.escape_string( const_convert_to_unicode(data[key], 'utf-8').encode('utf-8')).decode('utf-8') ) ) sql += ', '.join(keys_data) sql += ' WHERE %s' % (where,) elif action == "insert": sql = 'INSERT INTO %s (%s) VALUES (%s)' % ( self.escape_string(table), ', '.join([self.escape_string(x) for x in keys]), ', '.join(["'" + \ self.escape_string( const_convert_to_unicode(data[x], 'utf-8').encode('utf-8')).decode('utf-8') + \ "'" for x in keys]) ) return sql
def _updates(self, entropy_client): """ Solo Query Updates command. """ quiet = self._nsargs.quiet verbose = self._nsargs.verbose if not quiet: entropy_client.output(brown(_("Available Updates")), header=darkred(" @@ ")) outcome = entropy_client.calculate_updates(quiet=True) update, remove = outcome["update"], outcome["remove"] fine, critical_f = outcome["fine"], outcome["critical_found"] if quiet: entropy_client.output("%d" % (len(update),), level="generic") return 0 toc = [] toc.append((darkgreen(_("Packages to update:")), bold(const_convert_to_unicode(len(update))))) toc.append((darkred(_("Packages to remove:")), bold(const_convert_to_unicode(len(remove))))) if verbose: toc.append((blue(_("Packages already up-to-date:")), bold(const_convert_to_unicode(len(fine))))) toc.append((purple(_("Critical updates found:")), teal(const_convert_to_unicode(str(critical_f))))) print_table(entropy_client, toc) return 0
def validate_username_string(self, username, username_clean): self.check_connection() try: const_convert_to_unicode(username.encode('utf-8')) except (UnicodeDecodeError, UnicodeEncodeError,): return False, 'Invalid username' if (""" in username) or ("'" in username) or ('"' in username) or \ (" " in username): return False, 'Invalid username' try: valid = self.validate_username_regex(username) except: return False, 'Username contains bad characters' if not valid: return False, 'Invalid username' exists = self.does_username_exist(username, username_clean) if exists: return False, 'Username already taken' allowed = self.is_username_allowed(username) if not allowed: return False, 'Username not allowed' return True, 'All fine'
def _garbage_collect_preserved_libs(self, preserved_mgr): """ Garbage collect (and remove) libraries preserved on the system no longer available or no longer needed by any installed package. """ preserved_libs = preserved_mgr.collect() inst_repo = preserved_mgr.installed_repository() for library, elfclass, path in preserved_libs: self._entropy.output( "%s: %s [%s, %s]" % ( brown(_("Removing library")), darkgreen(path), purple(library), teal(const_convert_to_unicode("%s" % (elfclass,))), ), importance = 0, level = "warning", header = darkgreen(" :: ") ) self._entropy.logger.log( "[Package]", etpConst['logging']['normal_loglevel_id'], "%s %s [%s:%s]" % ( const_convert_to_unicode("Removing library"), path, library, elfclass,) ) # This will also check if path and it's destinations (in case of # symlink) is owned by other packages. # If this is the case, removal will fail for that specific path. # This may be the case for packages like vmware-workstation, # containing symlinks pointing to system libraries. # See Sabayon bug #5182. remove_failed = preserved_mgr.remove(path) for failed_path, err in remove_failed: self._entropy.output( "%s: %s, %s" % ( purple(_("Failed to remove the library")), darkred(failed_path), err, ), importance = 1, level = "warning", header = brown(" ## ") ) self._entropy.logger.log( "[Package]", etpConst['logging']['normal_loglevel_id'], "Error during %s removal: %s" % (failed_path, err) ) preserved_mgr.unregister(library, elfclass, path) # commit changes to repository if collected if preserved_libs: inst_repo.commit()
def __unicode__(self): method = self.__get_method() message = self.__get_message() if const_isstring(self.value): return const_convert_to_unicode(method + " " + self.value) \ + ", " + message return const_convert_to_unicode(method + " " + repr(self.value)) \ + ", " + message
def _show_license(self, uri, license_apps): """ Show selected License to User. """ tmp_fd, tmp_path = None, None try: license_text = None # get the first repo with valid license text repos = set([x.get_details().channelname for \ x in license_apps]) if not repos: return with self._entropy.rwsem().reader(): for repo_id in repos: repo = self._entropy.open_repository(repo_id) license_text = repo.retrieveLicenseText(uri) if license_text is not None: break if license_text is not None: tmp_fd, tmp_path = const_mkstemp(suffix=".txt") try: license_text = const_convert_to_unicode( license_text, enctype=etpConst['conf_encoding']) except UnicodeDecodeError: license_text = const_convert_to_unicode(license_text) with entropy.tools.codecs_fdopen( tmp_fd, "w", etpConst['conf_encoding']) as tmp_f: tmp_f.write("License: %s\n" % (uri, )) apps = self._licenses.get(uri, []) if apps: tmp_f.write("Applications:\n") for app in apps: tmp_f.write("\t%s\n" % (app.name, )) if apps: tmp_f.write("\n") tmp_f.write("-" * 79 + "\n") tmp_f.write(license_text) tmp_f.flush() else: const_debug_write( __name__, "LicensesNotificationBox._show_license: " "not available") finally: if tmp_fd is not None: try: os.close(tmp_fd) except OSError: pass # leaks, but xdg-open is async if tmp_path is not None: open_url(tmp_path)
def _list(self, entropy_client, inst_repo): """ Solo PreservedLibs List command. """ quiet = self._nsargs.quiet verbose = self._nsargs.verbose preserved_mgr = preservedlibs.PreservedLibraries( inst_repo, None, frozenset(), root=etpConst['systemroot']) preserved = preserved_mgr.list() if not preserved: if not quiet: entropy_client.output( darkgreen(_("No preserved libraries found")), header=darkred(" @@ ")) return 0 for library, elfclass, path, atom in preserved: if quiet: entropy_client.output(path, level="generic") continue needed_by_str = const_convert_to_unicode("") if verbose: needed_by_str += ", %s:" % ( darkgreen(_("needed by")), ) entropy_client.output( "%s [%s:%s -> %s]%s" % ( darkred(path), purple(library), teal(const_convert_to_unicode(elfclass)), enlightenatom(atom), needed_by_str, )) if verbose: package_ids = inst_repo.searchNeeded( library, elfclass=elfclass) for package_id in package_ids: atom = inst_repo.retrieveAtom(package_id) if atom is None: continue entropy_client.output( "%s" % (enlightenatom(atom),), header=brown(" -> "), importance=0) return 0
def _unicode_path(self, path): """ Convert a potentially raw string into a well formed unicode one. Usually, this method is called on string that went through _encode_path() """ try: path = const_convert_to_unicode(path, enctype=etpConst["conf_encoding"]) except (UnicodeDecodeError,): path = const_convert_to_unicode(path, enctype=sys.getfilesystemencoding()) return path
def _show_vote(self, entropy_client, vote, repository, pkgkey): if vote is None: vote = _("no votes") else: vote = const_convert_to_unicode("%.2f" % (vote,)) entropy_client.output(" %s [%s] %s: %s" % ( bold(const_convert_to_unicode("@@")), purple(pkgkey), darkred(_("current package vote")), darkgreen(vote), ) )
def _unicode_path(self, path): """ Convert a potentially raw string into a well formed unicode one. Usually, this method is called on string that went through _encode_path() """ try: path = const_convert_to_unicode(path, enctype=etpConst['conf_encoding']) except (UnicodeDecodeError, ): path = const_convert_to_unicode( path, enctype=sys.getfilesystemencoding()) return path
def _list(self, entropy_client, inst_repo): """ Solo PreservedLibs List command. """ quiet = self._nsargs.quiet verbose = self._nsargs.verbose preserved_mgr = preservedlibs.PreservedLibraries( inst_repo, None, frozenset(), root=etpConst['systemroot']) preserved = preserved_mgr.list() if not preserved: if not quiet: entropy_client.output(darkgreen( _("No preserved libraries found")), header=darkred(" @@ ")) return 0 for library, elfclass, path, atom in preserved: if quiet: entropy_client.output(path, level="generic") continue needed_by_str = const_convert_to_unicode("") if verbose: needed_by_str += ", %s:" % (darkgreen(_("needed by")), ) entropy_client.output("%s [%s:%s -> %s]%s" % ( darkred(path), purple(library), teal(const_convert_to_unicode(elfclass)), enlightenatom(atom), needed_by_str, )) if verbose: package_ids = inst_repo.searchNeeded(library, elfclass=elfclass) for package_id in package_ids: atom = inst_repo.retrieveAtom(package_id) if atom is None: continue entropy_client.output("%s" % (enlightenatom(atom), ), header=brown(" -> "), importance=0) return 0
def _prompt_final_removal(self, entropy_client, inst_repo, removal_queue): """ Prompt some final information to User with respect to the removal queue. """ total = len(removal_queue) mytxt = "%s: %s" % ( blue(_("Packages that would be removed")), darkred(const_convert_to_unicode(total)), ) entropy_client.output( mytxt, header=darkred(" @@ ")) total_removal_size = 0 total_pkg_size = 0 for package_id in set(removal_queue): on_disk_size = inst_repo.retrieveOnDiskSize(package_id) if on_disk_size is None: on_disk_size = 0 pkg_size = inst_repo.retrieveSize(package_id) if pkg_size is None: pkg_size = 0 extra_downloads = inst_repo.retrieveExtraDownload(package_id) for extra_download in extra_downloads: pkg_size += extra_download['size'] on_disk_size += extra_download['disksize'] total_removal_size += on_disk_size total_pkg_size += pkg_size human_removal_size = entropy.tools.bytes_into_human( total_removal_size) human_pkg_size = entropy.tools.bytes_into_human(total_pkg_size) mytxt = "%s: %s" % ( blue(_("Freed disk space")), bold(const_convert_to_unicode(human_removal_size)), ) entropy_client.output( mytxt, header=darkred(" @@ ")) mytxt = "%s: %s" % ( blue(_("Total bandwidth wasted")), bold(str(human_pkg_size)), ) entropy_client.output( mytxt, header=darkred(" @@ "))
def _license(self, entropy_client): """ Solo Query License command. """ quiet = self._nsargs.quiet verbose = self._nsargs.verbose licenses = self._nsargs.licenses settings = entropy_client.Settings() if not quiet: entropy_client.output(darkgreen(_("License Search")), header=darkred(" @@ ")) found = False repo_number = 0 for repo_id in entropy_client.repositories(): repo_number += 1 repo_data = settings["repositories"]["available"][repo_id] if not quiet: header = ( const_convert_to_unicode(" #") + const_convert_to_unicode(repo_number) + const_convert_to_unicode(" ") ) entropy_client.output("%s" % (bold(repo_data["description"]),), header=blue(header)) repo = entropy_client.open_repository(repo_id) key_sorter = lambda x: repo.retrieveAtom(x) for mylicense in licenses: results = repo.searchLicense(mylicense, just_id=True) if not results: continue found = True for pkg_id in sorted(results, key=key_sorter): print_package_info(pkg_id, entropy_client, repo, extended=verbose, strict_output=quiet, quiet=quiet) if not quiet: res_txt = ngettext("entry", "entries", len(results)) toc = [] toc.append(("%s:" % (blue(_("Keyword")),), purple(mylicense))) toc.append(("%s:" % (blue(_("Found")),), "%s %s" % (len(results), brown(res_txt)))) print_table(entropy_client, toc) if not quiet and not found: entropy_client.output(darkgreen("%s." % (_("No matches"),)), header=darkred(" @@ ")) return 0
def _my_raw_input(txt = ''): try: import readline except ImportError: # not available? ignore pass if not txt: txt = "" if const_is_python3(): try: response = input(darkgreen(txt)) except UnicodeEncodeError: response = input(darkgreen(txt.encode('utf-8'))) else: try: response = raw_input(darkgreen(txt)) except UnicodeEncodeError: response = raw_input(darkgreen(txt.encode('utf-8'))) _flush_stdouterr() # try to convert to unicode, because responses are stored that # way, fix bug #2006. if not const_isunicode(response): try: response = const_convert_to_unicode(response, enctype = "utf-8") except (UnicodeDecodeError, UnicodeEncodeError): # be fault tolerant, we just tried pass return response
def _scan_packages(self, entropy_client, packages, installed=False): """ Scan the list of package names filtering out unmatched entries. """ found_pkgs = [] for package in packages: if installed: repo = entropy_client.installed_repository() repo_id = repo.repository_id() package_id, _pkg_rc = repo.atomMatch(package) else: package_id, repo_id = entropy_client.atom_match(package) if package_id == -1: mytxt = "!!! %s: %s %s." % ( purple(_("Warning")), teal(const_convert_to_unicode(package)), purple(_("is not available")), ) entropy_client.output( "!!!", level="warning", importance=1) entropy_client.output( mytxt, level="warning", importance=1) entropy_client.output( "!!!", level="warning", importance=1) continue found_pkgs.append((package_id, repo_id)) return found_pkgs
def _to_unicode(arg): try: return const_convert_to_unicode( arg, enctype=etpConst['conf_encoding']) except UnicodeDecodeError: print_error("invalid argument: %s" % (arg,)) raise SystemExit(1)
def _needed(self, entropy_client, inst_repo): """ Solo Query Needed command. """ quiet = self._nsargs.quiet verbose = self._nsargs.verbose packages = self._nsargs.packages if not quiet: entropy_client.output(darkgreen(_("Needed Libraries Search")), header=darkred(" @@ ")) for package in packages: pkg_id, pkg_rc = inst_repo.atomMatch(package) if pkg_id == -1: continue atom = inst_repo.retrieveAtom(pkg_id) neededs = inst_repo.retrieveNeededLibraries(pkg_id) for usr_path, usr_soname, soname, elfclass, rpath in neededs: out_str = "%s:%s" % (soname, elfclass) if verbose: out_str = "%s:%s:%s:%s:%s" % (usr_path, usr_soname, soname, elfclass, rpath) if quiet: entropy_client.output(out_str, level="generic") else: entropy_client.output(darkred(const_convert_to_unicode(out_str)), header=blue(" # ")) if not quiet: toc = [] toc.append(("%s:" % (blue(_("Package")),), purple(atom))) toc.append(("%s:" % (blue(_("Found")),), "%s %s" % (len(neededs), brown(_("libraries"))))) print_table(entropy_client, toc) return 0
def _scan_packages(self, entropy_client, inst_repo, packages): """ Scan the list of package names filtering out unmatched entries. """ found_pkgs = [] for package in packages: package_id, _pkg_rc = inst_repo.atomMatch(package) if package_id == -1: mytxt = "!!! %s: %s %s." % ( purple(_("Warning")), teal(const_convert_to_unicode(package)), purple(_("is not available")), ) entropy_client.output( "!!!", level="warning", importance=1) entropy_client.output( mytxt, level="warning", importance=1) entropy_client.output( "!!!", level="warning", importance=1) continue found_pkgs.append(package_id) return found_pkgs
def _guess_kernel_package_file(release_level): """ This method takes advantage of Entropy kernel package info files available at /etc/kernels/<pkg-name>-<pkg-ver>/ directory looking for a RELEASE_LEVEL file whose content matches release_level (uname -r). """ if not os.path.isdir(KERNELS_DIR): return None subs = collections.deque() for _curdir, subdirs, _files in os.walk(KERNELS_DIR): subs.extend(subdirs) break for sub in subs: sub_path = os.path.join(KERNELS_DIR, sub) try: dir_list = os.listdir(sub_path) except OSError as err: if err.errno != errno.ENOENT: raise continue if RELEASE_LEVEL not in dir_list: continue level_path = os.path.join( sub_path, RELEASE_LEVEL) with codecs.open( level_path, "r", etpConst["conf_raw_encoding"]) as rel_f: rel_line = rel_f.readline().strip() if release_level == rel_line: return const_convert_to_unicode(level_path)
def _show_preserved_libraries(self, entropy_client): """ Inform User about preserved libraries living on the filesystem. This method is process and thread safe. """ inst_repo = entropy_client.installed_repository() with inst_repo.shared(): preserved_mgr = PreservedLibraries( inst_repo, None, frozenset(), root=etpConst['systemroot']) preserved = preserved_mgr.list() if preserved: mytxt = ngettext( "There is %s preserved library on the system", "There are %s preserved libraries on the system", len(preserved)) % (len(preserved),) entropy_client.output( darkgreen(mytxt), level="warning") for library, elfclass, path, atom in preserved: entropy_client.output( "%s [%s:%s -> %s]" % ( darkred(path), purple(library), teal(const_convert_to_unicode(elfclass)), enlightenatom(atom), ))
def run(text): mytxt = const_convert_to_unicode(text) if len(mytxt) > 80: mytxt = mytxt[:80].strip()+"..." self.ui.progressExtraLabel.set_markup( "<span size=\"small\">%s</span>" % cleanMarkupString(mytxt)) return False
def _to_unicode(arg): try: return const_convert_to_unicode(arg, enctype=etpConst['conf_encoding']) except UnicodeDecodeError: print_error("invalid argument: %s" % (arg, )) raise SystemExit(1)
def option_chooser(option_data): mydict = {} counter = 1 option_text, option_list = option_data cls.output(option_text) for item in option_list: mydict[counter] = item txt = "[%s] %s" % (darkgreen(str(counter)), blue(item),) cls.output(txt) counter += 1 while True: try: if const_is_python3(): myresult = const_convert_to_unicode( readtext("%s: " % (_('Selected number'),)), enctype = "utf-8") else: myresult = readtext( "%s: " % (_('Selected number'),)).decode('utf-8') except UnicodeDecodeError: continue except UnicodeEncodeError: continue try: myresult = int(myresult) except ValueError: continue selected = mydict.get(myresult) if selected != None: return myresult, selected
def __init__(self, installed_repository, installed_package_id, provided_libraries, root=None): """ Object constructor. @param installed_repository: an EntropyRepository object pointing to the installed packages repository @type installed_repository: EntropyRepository @param installed_package_id: the installed packages repository package identifier @type installed_package_id: int @param provided_libraries: set of libraries that a package provides, typically this is the data returned by EntropyRepository.retrieveProvidedLibraries() @type provided_libraries: set @keyword root: path to the root directory minus the trailing "/". For "/" it's just "" or None. @type root: string """ self._inst_repo = installed_repository self._package_id = installed_package_id self._raw_provided = provided_libraries self._provided = dict( ((l_path, (library, elfclass, l_path)) for library, l_path, elfclass in provided_libraries)) self._root = root or const_convert_to_unicode("") self._search_needed_cache = {}
def _guess_kernel_package_file(release_level): """ This method takes advantage of Entropy kernel package info files available at /etc/kernels/<pkg-name>-<pkg-ver>/ directory looking for a RELEASE_LEVEL file whose content matches release_level (uname -r). """ if not os.path.isdir(KERNELS_DIR): return None subs = collections.deque() for _curdir, subdirs, _files in os.walk(KERNELS_DIR): subs.extend(subdirs) break for sub in subs: sub_path = os.path.join(KERNELS_DIR, sub) try: dir_list = os.listdir(sub_path) except OSError as err: if err.errno != errno.ENOENT: raise continue if RELEASE_LEVEL not in dir_list: continue level_path = os.path.join(sub_path, RELEASE_LEVEL) with codecs.open(level_path, "r", etpConst["conf_raw_encoding"]) as rel_f: rel_line = rel_f.readline().strip() if release_level == rel_line: return const_convert_to_unicode(level_path)
def __init__(self, installed_repository, installed_package_id, provided_libraries, root = None): """ Object constructor. @param installed_repository: an EntropyRepository object pointing to the installed packages repository @type installed_repository: EntropyRepository @param installed_package_id: the installed packages repository package identifier @type installed_package_id: int @param provided_libraries: set of libraries that a package provides, typically this is the data returned by EntropyRepository.retrieveProvidedLibraries() @type provided_libraries: set @keyword root: path to the root directory minus the trailing "/". For "/" it's just "" or None. @type root: string """ self._inst_repo = installed_repository self._package_id = installed_package_id self._raw_provided = provided_libraries self._provided = dict(((l_path, (library, elfclass, l_path)) for library, l_path, elfclass in provided_libraries)) self._root = root or const_convert_to_unicode("") self._search_needed_cache = {}
def run(text): mytxt = const_convert_to_unicode(text) if len(mytxt) > 80: mytxt = mytxt[:80].strip()+"..." self.ui.progressSubLabel.set_markup("%s" % (cleanMarkupString(mytxt),)) self.ui.progressExtraLabel.set_text("") return False
def _scan_installed_packages(self, entropy_client, inst_repo, packages): """ Scan the Installed Packages repository for matches and return a list of matched package identifiers. """ package_ids = [] for package in packages: package_id, _result = inst_repo.atomMatch(package) if package_id != -1: package_ids.append(package_id) continue # support file paths and convert them to package_ids file_package_ids = inst_repo.isFileAvailable(package, get_id=True) if file_package_ids: package_ids.extend(file_package_ids) continue mytxt = "!!! %s: %s %s." % ( purple(_("Warning")), teal(const_convert_to_unicode(package)), purple(_("is not installed")), ) entropy_client.output("!!!", level="warning") entropy_client.output(mytxt, level="warning") entropy_client.output("!!!", level="warning") if len(package) > 3: self._show_did_you_mean(entropy_client, package, True) entropy_client.output("!!!", level="warning") return package_ids
def _show_preserved_libraries(self, entropy_client): """ Inform User about preserved libraries living on the filesystem. This method is process and thread safe. """ inst_repo = entropy_client.installed_repository() with inst_repo.shared(): preserved_mgr = PreservedLibraries(inst_repo, None, frozenset(), root=etpConst['systemroot']) preserved = preserved_mgr.list() if preserved: mytxt = ngettext("There is %s preserved library on the system", "There are %s preserved libraries on the system", len(preserved)) % (len(preserved), ) entropy_client.output(darkgreen(mytxt), level="warning") for library, elfclass, path, atom in preserved: entropy_client.output("%s [%s:%s -> %s]" % ( darkred(path), purple(library), teal(const_convert_to_unicode(elfclass)), enlightenatom(atom), ))
def _tags(self, entropy_client): """ Solo Query Tags command. """ quiet = self._nsargs.quiet verbose = self._nsargs.verbose tags = self._nsargs.tags settings = entropy_client.Settings() if not quiet: entropy_client.output(darkgreen(_("Tag Search")), header=darkred(" @@ ")) found = False # search inside each available database repo_number = 0 for repo_id in entropy_client.repositories(): repo_number += 1 repo_data = settings["repositories"]["available"][repo_id] if not quiet: header = ( const_convert_to_unicode(" #") + const_convert_to_unicode(repo_number) + const_convert_to_unicode(" ") ) entropy_client.output("%s" % (bold(repo_data["description"]),), header=blue(header)) repo = entropy_client.open_repository(repo_id) for tag in tags: results = repo.searchTaggedPackages(tag) key_sorter = lambda x: repo.retrieveAtom(x) for pkg_id in sorted(results, key=key_sorter): found = True print_package_info(pkg_id, entropy_client, repo, extended=verbose, strict_output=quiet, quiet=quiet) if not quiet: toc = [] entity_str = ngettext("entry", "entries", len(results)) toc.append(("%s:" % (blue(_("Keyword")),), purple(tag))) toc.append(("%s:" % (blue(_("Found")),), "%s %s" % (len(results), brown(entity_str)))) print_table(entropy_client, toc) if not quiet and not found: entropy_client.output(darkgreen("%s." % (_("No matches"),)), header=darkred(" @@ ")) return 0
def _show_document(self, entropy_client, doc, repository, pkgkey): title = const_convert_to_unicode(doc[Document.DOCUMENT_TITLE_ID]) if not title: title = _("No title") title = darkgreen(title) ts = doc.document_timestamp() ts = entropy.tools.convert_unix_time_to_human_time(ts) entropy_client.output(" %s [%s|%s|%s|%s|%s|%s]" % ( bold("@@"), bold(str(doc.document_id())), darkred(str(doc.document_type())), darkgreen(repository), purple(pkgkey), blue(doc[DocumentFactory.DOCUMENT_USERNAME_ID]), darkgreen(ts), ) ) entropy_client.output("\t%s: %s" % ( blue(_("Title")), title, ) ) if const_isstring(doc.document_data()): text = doc.document_data() else: text = doc.document_data().tostring() text = const_convert_to_unicode(text) self._formatted_print( entropy_client, text, "\t%s: " % (blue(_("Content")),), "\t") entropy_client.output("\t%s: %s" % ( blue(_("Keywords")), doc.document_keywords(), ) ) url = doc.document_url() if url is not None: entropy_client.output("\t%s: %s" % ( blue(_("Download")), url, ) )
def _commit_message(self, entropy_server, successfull_mirrors): """ Ask user to enter the commit message for data being pushed. Store inside rss metadata object. """ enc = etpConst['conf_encoding'] tmp_fd, tmp_commit_path = const_mkstemp(prefix="eit._push", suffix=".COMMIT_MSG") with entropy.tools.codecs_fdopen(tmp_fd, "w", enc) as tmp_f: tmp_f.write(EitPush.DEFAULT_REPO_COMMIT_MSG) if successfull_mirrors: tmp_f.write( const_convert_to_unicode("# Changes to be committed:\n")) for sf_mirror in sorted(successfull_mirrors): tmp_f.write( const_convert_to_unicode("#\t updated: %s\n" % (sf_mirror, ))) # spawn editor cm_msg_rc = entropy_server.edit_file(tmp_commit_path) commit_msg = None if not cm_msg_rc: # wtf?, fallback to old way def fake_callback(*args, **kwargs): return True input_params = [('message', _("Commit message"), fake_callback, False)] commit_data = entropy_server.input_box( _("Enter the commit message"), input_params, cancel_button=True) if commit_data: commit_msg = const_convert_to_unicode(commit_data['message']) else: commit_msg = const_convert_to_unicode("") with codecs.open(tmp_commit_path, "r", encoding=enc) as tmp_f: for line in tmp_f.readlines(): if line.strip().startswith("#"): continue commit_msg += line entropy_server.output(commit_msg) os.remove(tmp_commit_path) return commit_msg
def _commit_message(self, entropy_server, successfull_mirrors): """ Ask user to enter the commit message for data being pushed. Store inside rss metadata object. """ enc = etpConst['conf_encoding'] tmp_fd, tmp_commit_path = const_mkstemp( prefix="eit._push", suffix=".COMMIT_MSG") with entropy.tools.codecs_fdopen(tmp_fd, "w", enc) as tmp_f: tmp_f.write(EitPush.DEFAULT_REPO_COMMIT_MSG) if successfull_mirrors: tmp_f.write(const_convert_to_unicode( "# Changes to be committed:\n")) for sf_mirror in sorted(successfull_mirrors): tmp_f.write(const_convert_to_unicode( "#\t updated: %s\n" % (sf_mirror,))) # spawn editor cm_msg_rc = entropy_server.edit_file(tmp_commit_path) commit_msg = None if not cm_msg_rc: # wtf?, fallback to old way def fake_callback(*args, **kwargs): return True input_params = [ ('message', _("Commit message"), fake_callback, False)] commit_data = entropy_server.input_box( _("Enter the commit message"), input_params, cancel_button = True) if commit_data: commit_msg = const_convert_to_unicode(commit_data['message']) else: commit_msg = const_convert_to_unicode("") with codecs.open(tmp_commit_path, "r", encoding=enc) as tmp_f: for line in tmp_f.readlines(): if line.strip().startswith("#"): continue commit_msg += line entropy_server.output(commit_msg) os.remove(tmp_commit_path) return commit_msg
def _search(self, old_text, _force=False): cur_text = self._search_entry.get_text() if (cur_text == old_text and cur_text) or _force: search_text = copy.copy(old_text) search_text = const_convert_to_unicode( search_text, enctype=etpConst['conf_encoding']) if _force: self._search_entry.set_text(search_text) th = ParallelTask(self.__search_thread, search_text) th.name = "SearchThread" th.start()
def _get_info_directories(self): """ Return a list of `info` directories as declared in the INFOPATH and INFODIR environment variable. """ info_dirs = os.getenv("INFOPATH", "").split(":") info_dirs += os.getenv("INFODIR", "").split(":") info_dirs = [const_convert_to_unicode( os.path.normpath(x)) for x in info_dirs] info_dirs.sort() return info_dirs
def _selfile(self, entropy_client): entropy_client.output( darkred( _("Please choose a file to update by typing " "its identification number."))) entropy_client.output( darkred(_("Other options are:"))) entropy_client.output( " (%s) %s" % ( blue(const_convert_to_unicode("-1")), darkgreen(_("Exit")), )) entropy_client.output( " (%s) %s" % ( blue(const_convert_to_unicode("-3")), brown(_("Automerge all the files asking you one by one")), )) entropy_client.output( " (%s) %s" % ( blue(const_convert_to_unicode("-5")), darkred(_("Automerge all the files without questioning")), )) entropy_client.output( " (%s) %s" % ( blue(const_convert_to_unicode("-7")), brown(_("Discard all the files asking you one by one")), )) entropy_client.output( " (%s) %s" % ( blue(const_convert_to_unicode("-9")), darkred(_("Discard all the files without questioning")), )) # wait user interaction try: action = readtext( _("Your choice (type a number and press enter):")+" ") except EOFError: action = None return action
def _get_info_directories(self): """ Return a list of `info` directories as declared in the INFOPATH and INFODIR environment variable. """ info_dirs = os.getenv("INFOPATH", "").split(":") info_dirs += os.getenv("INFODIR", "").split(":") info_dirs = [ const_convert_to_unicode(os.path.normpath(x)) for x in info_dirs ] info_dirs.sort() return info_dirs
def _login(self, button): """ Try to login to Entropy Web Services. """ username = self._username_entry.get_text() password = self._password_entry.get_text() try: username = const_convert_to_unicode( username, enctype=etpConst['conf_encoding']) password = const_convert_to_unicode( password, enctype=etpConst['conf_encoding']) except UnicodeDecodeError as err: const_debug_write( __name__, "LoginNotificationBox._login: %s" % (repr(err), )) return task = ParallelTask(self._login_thread_body, username, password) task.name = "LoginNotificationThreadBody" task.daemon = True task.start()
def xpand(myid, mydest): myindex = myid[0] mydata = myid[1] myindexlen = len(myindex) startpos = 0 while ((startpos + 8) < myindexlen): namelen = decodeint(myindex[startpos:startpos + 4]) datapos = decodeint(myindex[startpos + 4 + namelen:startpos + 8 + namelen]) datalen = decodeint(myindex[startpos + 8 + namelen:startpos + 12 + namelen]) myname = myindex[startpos + 4:startpos + 4 + namelen] myname = os.path.join(mydest, const_convert_to_unicode(myname)) dirname = os.path.dirname(myname) if not os.path.exists(dirname): os.makedirs(dirname) with open(myname, "wb") as mydat: mydat.write(mydata[datapos:datapos + datalen]) startpos = startpos + namelen + 12
def _gc(self, entropy_client, inst_repo): """ Solo PreservedLibs Gc command. """ preserved_mgr = preservedlibs.PreservedLibraries( inst_repo, None, frozenset(), root=etpConst['systemroot']) collectables = preserved_mgr.collect() if not collectables: entropy_client.output(darkgreen( _("No preserved libraries to garbage collect")), header=darkred(" @@ ")) return 0 for library, elfclass, path in collectables: package_ids = inst_repo.isFileAvailable(path, get_id=True) entropy_client.output("%s [%s:%s]" % ( darkred(path), purple(library), teal(const_convert_to_unicode(elfclass)), )) for package_id in package_ids: atom = inst_repo.retrieveAtom(package_id) if atom is None: continue entropy_client.output("%s: %s, %s" % ( blue(_("but owned by")), darkgreen(atom), blue(_("then just unregister the library")), ), header=brown(" -> "), importance=0) return 0
def _on_send_comment(self, widget, app=None): """ Send comment to Web Service. """ if app is None: app = self._last_app if app is None: # we're hiding return text = self._app_comment_text_buffer.get_text( self._app_comment_text_buffer.get_start_iter(), self._app_comment_text_buffer.get_end_iter(), False) if not text.strip(): return # make it utf-8 text = const_convert_to_unicode(text, enctype=etpConst['conf_encoding']) def _sender(app, text): if not app.is_webservice_available(): GLib.idle_add(self._notify_webservice_na, app, self.COMMENT_NOTIFICATION_CONTEXT_ID) return ws_user = app.get_webservice_username() if ws_user is not None: GLib.idle_add(self._notify_comment_submit, app, ws_user, text) else: GLib.idle_add(self._notify_login_request, app, text, self._on_comment_login_success, self._on_comment_login_failed, self.COMMENT_NOTIFICATION_CONTEXT_ID) task = ParallelTask(_sender, app, text) task.name = "AppViewSendComment" task.start()
def _selaction(self, entropy_client): entropy_client.output( darkred( _("Please choose an action to take for" " the selected file."))) entropy_client.output(" (%s) %s" % ( blue(const_convert_to_unicode("-1")), darkgreen(_("Come back to the files list")), )) entropy_client.output(" (%s) %s" % ( blue(const_convert_to_unicode("1")), brown(_("Replace original with update")), )) entropy_client.output(" (%s) %s" % ( blue(const_convert_to_unicode("2")), darkred(_("Delete update, keeping original as is")), )) entropy_client.output(" (%s) %s" % ( blue(const_convert_to_unicode("3")), brown(_("Edit proposed file and show diffs again")), )) entropy_client.output(" (%s) %s" % ( blue(const_convert_to_unicode("4")), brown(_("Interactively merge original with update")), )) entropy_client.output(" (%s) %s" % ( blue(const_convert_to_unicode("5")), darkred(_("Show differences again")), )) # wait user interaction try: action = readtext( _("Your choice (type a number and press enter):") + " ") except EOFError: action = None return action
def __push_repo(self, entropy_server, repository_id): sys_settings_plugin_id = \ etpConst['system_settings_plugins_ids']['server_plugin'] srv_data = self._settings()[sys_settings_plugin_id]['server'] rss_enabled = srv_data['rss']['enabled'] mirrors_tainted, mirrors_errors, successfull_mirrors, \ broken_mirrors, check_data = \ entropy_server.Mirrors.sync_packages( repository_id, ask = self._ask, pretend = self._pretend) if mirrors_errors and not successfull_mirrors: entropy_server.output(red(_("Aborting !")), importance=1, level="error", header=darkred(" !!! ")) return 1 if not successfull_mirrors: return 0 if mirrors_tainted and (self._as_repository_id is None): commit_msg = None if self._ask and rss_enabled: # expected unicode out of here commit_msg = self._commit_message(entropy_server, successfull_mirrors) elif rss_enabled: commit_msg = const_convert_to_unicode("Automatic update") if commit_msg is None: commit_msg = const_convert_to_unicode("no commit message") ServerRssMetadata()['commitmessage'] = commit_msg if self._as_repository_id is not None: # change repository push location ServerSystemSettingsPlugin.set_override_remote_repository( self._settings(), repository_id, self._as_repository_id) sts = self.__sync_repo(entropy_server, repository_id) if sts == 0: # do not touch locking entropy_server.Mirrors.lock_mirrors(repository_id, False, unlock_locally = (self._as_repository_id is None)) if sts != 0: entropy_server.output(red(_("Aborting !")), importance=1, level="error", header=darkred(" !!! ")) return sts if self._ask: q_rc = entropy_server.ask_question( _("Should I cleanup old packages on mirrors ?")) if q_rc == _("No"): return 0 # fall through done = entropy_server.Mirrors.tidy_mirrors( repository_id, ask = self._ask, pretend = self._pretend) if not done: return 1 return 0
class EitPush(EitCommand): """ Main Eit reset command. """ NAME = "push" ALIASES = ["sync"] DEFAULT_REPO_COMMIT_MSG = const_convert_to_unicode(""" # This is Entropy Server repository commit message handler. # Please friggin' enter the commit message for your changes. Lines starting # with '#' will be ignored. To avoid encoding issue, write stuff in plain ASCII. """) def __init__(self, args): EitCommand.__init__(self, args) self._ask = True self._pretend = False self._all = False self._force = False self._repositories = [] self._cleanup_only = False self._as_repository_id = None self._conservative = False def _get_parser(self): self._real_command = sys.argv[0] descriptor = EitCommandDescriptor.obtain_descriptor( EitPush.NAME) parser = argparse.ArgumentParser( description=descriptor.get_description(), formatter_class=argparse.RawDescriptionHelpFormatter, prog="%s %s" % (sys.argv[0], EitPush.NAME)) parser.add_argument("repo", nargs='?', default=None, metavar="<repo>", help=_("repository")) parser.add_argument("--conservative", action="store_true", help=_("do not execute implicit package name " "and slot updates"), default=self._conservative) parser.add_argument("--quick", action="store_true", default=False, help=_("no stupid questions")) parser.add_argument("--force", action="store_true", default=False, help=_("force push in case of QA errors")) group = parser.add_mutually_exclusive_group() group.add_argument("--all", action="store_true", default=False, help=_("push all the repositories")) group.add_argument("--as", metavar="<repo>", default=None, help=_("push as fake repository"), dest="asrepo") parser.add_argument("--pretend", action="store_true", default=False, help=_("show what would be done")) return parser def bashcomp(self, last_arg): """ Overridden from EitCommand """ import sys entropy_server = self._entropy(handle_uninitialized=False, installed_repo=-1) outcome = entropy_server.repositories() for arg in self._args: if arg in outcome: # already given a repo if last_arg != "--as": outcome = [] break outcome += ["--conservative", "--quick", "--all", "--as", "--force"] def _startswith(string): if last_arg is not None: if last_arg not in outcome: return string.startswith(last_arg) return True if self._args: # only filter out if last_arg is actually # something after this.NAME. outcome = sorted(filter(_startswith, outcome)) for arg in self._args: if arg in outcome: outcome.remove(arg) sys.stdout.write(" ".join(outcome) + "\n") sys.stdout.flush() INTRODUCTION = """\ Synchronize remote mirrors with local repository content (packages and repository) by pushing updated data. """ def man(self): """ Overridden from EitCommand. """ return self._man() def parse(self): parser = self._get_parser() try: nsargs = parser.parse_args(self._args) except IOError as err: sys.stderr.write("%s\n" % (err,)) return parser.print_help, [] self._ask = not nsargs.quick self._all = nsargs.all if nsargs.repo is not None: self._repositories.append(nsargs.repo) self._as_repository_id = nsargs.asrepo self._pretend = nsargs.pretend self._force = nsargs.force self._entropy_class()._inhibit_treeupdates = nsargs.conservative return self._call_exclusive, [self._push, nsargs.repo] def _push(self, entropy_server): """ Main Eit push code. """ if not self._repositories and (not self._all): # pick default if none specified self._repositories.append(entropy_server.repository()) if not self._repositories and self._all: self._repositories.extend(entropy_server.repositories()) for repository_id in self._repositories: # avoid __system__ if repository_id == InstalledPackagesRepository.NAME: continue rc = self._push_repo(entropy_server, repository_id) if rc != 0: return rc return 0 def _push_repo(self, entropy_server, repository_id): """ Push the damn repository. """ rc = 0 if not self._cleanup_only: rc = self.__push_repo(entropy_server, repository_id) return rc def _commit_message(self, entropy_server, successfull_mirrors): """ Ask user to enter the commit message for data being pushed. Store inside rss metadata object. """ enc = etpConst['conf_encoding'] tmp_fd, tmp_commit_path = const_mkstemp( prefix="eit._push", suffix=".COMMIT_MSG") with entropy.tools.codecs_fdopen(tmp_fd, "w", enc) as tmp_f: tmp_f.write(EitPush.DEFAULT_REPO_COMMIT_MSG) if successfull_mirrors: tmp_f.write(const_convert_to_unicode( "# Changes to be committed:\n")) for sf_mirror in sorted(successfull_mirrors): tmp_f.write(const_convert_to_unicode( "#\t updated: %s\n" % (sf_mirror,))) # spawn editor cm_msg_rc = entropy_server.edit_file(tmp_commit_path) commit_msg = None if not cm_msg_rc: # wtf?, fallback to old way def fake_callback(*args, **kwargs): return True input_params = [ ('message', _("Commit message"), fake_callback, False)] commit_data = entropy_server.input_box( _("Enter the commit message"), input_params, cancel_button = True) if commit_data: commit_msg = const_convert_to_unicode(commit_data['message']) else: commit_msg = const_convert_to_unicode("") with codecs.open(tmp_commit_path, "r", encoding=enc) as tmp_f: for line in tmp_f.readlines(): if line.strip().startswith("#"): continue commit_msg += line entropy_server.output(commit_msg) os.remove(tmp_commit_path) return commit_msg @staticmethod def print_repository_status(entropy_server, repository_id): remote_db_status = entropy_server.Mirrors.remote_repository_status( repository_id) entropy_server.output( "%s:" % (brown(_("Entropy Repository Status")),), importance=1, header=darkgreen(" * ") ) for url, revision in remote_db_status.items(): host = EntropyTransceiver.get_uri_name(url) entropy_server.output( "%s: %s" % (darkgreen(_("Host")), bold(host)), header=" ") entropy_server.output( "%s: %s" % (purple(_("Remote")), blue(str(revision))), header=" ") local_revision = entropy_server.local_repository_revision( repository_id) entropy_server.output( "%s: %s" % (brown(_("Local")), teal(str(local_revision))), header=" ") def __sync_repo(self, entropy_server, repository_id): EitPush.print_repository_status(entropy_server, repository_id) # do the actual sync try: sts = entropy_server.Mirrors.sync_repository( repository_id, enable_upload = True, enable_download = False, force = self._force) except OnlineMirrorError as err: entropy_server.output( "%s: %s" % (darkred(_("Error")), err.value), importance=1, level="error") return 1 EitPush.print_repository_status(entropy_server, repository_id) return sts def __push_repo(self, entropy_server, repository_id): sys_settings_plugin_id = \ etpConst['system_settings_plugins_ids']['server_plugin'] srv_data = self._settings()[sys_settings_plugin_id]['server'] rss_enabled = srv_data['rss']['enabled'] mirrors_tainted, mirrors_errors, successfull_mirrors, \ broken_mirrors, check_data = \ entropy_server.Mirrors.sync_packages( repository_id, ask = self._ask, pretend = self._pretend) if mirrors_errors and not successfull_mirrors: entropy_server.output(red(_("Aborting !")), importance=1, level="error", header=darkred(" !!! ")) return 1 if not successfull_mirrors: return 0 if mirrors_tainted and (self._as_repository_id is None): commit_msg = None if self._ask and rss_enabled: # expected unicode out of here commit_msg = self._commit_message(entropy_server, successfull_mirrors) elif rss_enabled: commit_msg = const_convert_to_unicode("Automatic update") if commit_msg is None: commit_msg = const_convert_to_unicode("no commit message") ServerRssMetadata()['commitmessage'] = commit_msg if self._as_repository_id is not None: # change repository push location ServerSystemSettingsPlugin.set_override_remote_repository( self._settings(), repository_id, self._as_repository_id) sts = self.__sync_repo(entropy_server, repository_id) if sts == 0: # do not touch locking entropy_server.Mirrors.lock_mirrors(repository_id, False, unlock_locally = (self._as_repository_id is None)) if sts != 0: entropy_server.output(red(_("Aborting !")), importance=1, level="error", header=darkred(" !!! ")) return sts if self._ask: q_rc = entropy_server.ask_question( _("Should I cleanup old packages on mirrors ?")) if q_rc == _("No"): return 0 # fall through done = entropy_server.Mirrors.tidy_mirrors( repository_id, ask = self._ask, pretend = self._pretend) if not done: return 1 return 0