def test_must_return_right_number_of_bytes_for_bibyte_units(self): self.assertEqual(1024.0, size_to_byte(1, 'KiB')) self.assertEqual(1579683.84, size_to_byte(1542.66, 'KiB')) self.assertEqual(1048576, size_to_byte(1, 'MiB')) self.assertEqual(4372561.92, size_to_byte(4.17, 'MiB')) self.assertEqual(1073741824, size_to_byte(1, 'GiB')) self.assertEqual(2168958484.48, size_to_byte(2.02, 'GiB')) self.assertEqual(1099511627776, size_to_byte(1, 'TiB')) self.assertEqual(3375500697272.32, size_to_byte(3.07, 'TiB')) self.assertEqual(1125899906842624, size_to_byte(1, 'PiB')) self.assertEqual(1294784892869017.5, size_to_byte(1.15, 'PiB'))
def map_update_download_size(app_ids: Iterable[str], installation: str, version: str) -> Dict[str, int]: success, output = ProcessHandler().handle_simple( SimpleProcess(['flatpak', 'update', '--{}'.format(installation)])) if version >= '1.5': res = {} p = re.compile(r'^\d+.\t') p2 = re.compile(r'\s([0-9.?a-zA-Z]+)\s?') for l in output.split('\n'): if l: line = l.strip() if line: found = p.match(line) if found: line_split = line.split('\t') line_id = line_split[2].strip() related_id = [ appid for appid in app_ids if appid == line_id ] if related_id: size = p2.findall(line_split[6])[0].split('?') res[related_id[0].strip()] = size_to_byte( float(size[0]), size[1]) return res
def map_update_download_size(app_ids: Iterable[str], installation: str, version: Version) -> Dict[str, float]: success, output = ProcessHandler().handle_simple( SimpleProcess(('flatpak', 'update', f'--{installation}', '--no-deps'))) if version >= VERSION_1_2: res = {} p = re.compile(r'^\d+.\t') p2 = re.compile(r'([0-9.?a-zA-Z]+\s?)') for l in output.split('\n'): if l: line = l.strip() if line: found = p.match(line) if found: line_split = line.split('\t') line_id = line_split[2].strip() related_id = [ appid for appid in app_ids if appid == line_id ] if related_id and len(line_split) >= 7: size_tuple = p2.findall(line_split[6]) if size_tuple: if version >= VERSION_1_5: size = size_tuple[0].split('?') if size and len(size) > 1: try: res[related_id[0].strip( )] = size_to_byte( size[0], size[1].strip()) except: traceback.print_exc() else: try: res[related_id[0].strip( )] = size_to_byte( size_tuple[0], size_tuple[1].strip()) except: traceback.print_exc() return res
def get_installed_size(pkgs: List[str]) -> Dict[str, int]: # bytes output = run_cmd('pacman -Qi {}'.format(' '.join(pkgs))) if output: return { pkgs[idx]: size_to_byte(float(size[0]), size[1]) for idx, size in enumerate(RE_INSTALLED_SIZE.findall(output)) } return {}
def map_download_sizes(pkgs: List[str]) -> Dict[str, int]: # bytes: output = run_cmd('pacman -Si {}'.format(' '.join(pkgs))) if output: return { pkgs[idx]: size_to_byte(float(size[0]), size[1]) for idx, size in enumerate(RE_DOWNLOAD_SIZE.findall(output)) } return {}
def map_update_sizes(pkgs: List[str]) -> Dict[str, float]: # bytes: output = run_cmd('pacman -Si {}'.format(' '.join(pkgs))) if output: return { pkgs[idx]: size_to_byte(size[0], size[1]) for idx, size in enumerate(RE_INSTALLED_SIZE.findall(output)) } return {}
def test_must_return_converted_string_sizes(self): self.assertEqual(1000, size_to_byte('1', 'K')) self.assertEqual(57300, size_to_byte('57.3', 'K')) self.assertEqual(57300000, size_to_byte('57.3', 'M')) self.assertEqual(57300000000, size_to_byte('57.3', 'G')) self.assertEqual(57300000000000, size_to_byte('57.3', 'T')) self.assertEqual(5670000000000000, size_to_byte('5.67', 'P'))
def search( self, query: str, fill_size: bool = False) -> Generator[DebianPackage, None, None]: attrs = f"%p^%v^%V^%m^%s^{'%I^' if fill_size else ''}%d" _, output = system.execute( f"aptitude search {query} -q -F '{attrs}' --disable-columns", shell=True) if output: no_attrs = 7 if fill_size else 6 for line in output.split('\n'): line_split = line.strip().split('^', maxsplit=no_attrs - 1) if len(line_split) == no_attrs: latest_version = line_split[2] if not self.re_none.match( line_split[2]) else None size = None if fill_size: size_split = line_split[no_attrs - 2].split(' ') unit = size_split[1][0].upper( ) if len(size_split) >= 2 else 'B' size = size_to_byte(size_split[0], unit, self._log) if latest_version is not None: installed_version = line_split[ 1] if not self.re_none.match( line_split[1]) else None section = strip_section(line_split[4]) yield DebianPackage( name=line_split[0], version=installed_version if installed_version else latest_version, latest_version=latest_version, installed=bool(installed_version), update=installed_version is not None and installed_version != latest_version, maintainer=strip_maintainer_email(line_split[3]), categories=(section, ) if section else None, uncompressed_size=size, description=line_split[no_attrs - 1])
def show(self, pkgs: Iterable[str], attrs: Optional[Collection[str]] = None, verbose: bool = False) \ -> Optional[Dict[str, Dict[str, object]]]: if pkgs: force_verbose = verbose if verbose else ( 'compressed size' in attrs if attrs else False) code, output = system.execute( f"aptitude show -q {' '.join(pkgs)}{' -v' if force_verbose else ''}", shell=True, custom_env=self.env) if code == 0 and output: info, pkg = dict(), None for field, val in self.re_show_attr.findall('\n' + output): final_field, final_val = field.strip().lower(), val.strip() if final_field == 'package': pkg = {} info[final_val] = pkg elif final_field not in self.ignored_fields and ( not attrs or final_field in attrs): if final_val: if final_field in self.list_attrs: final_val = tuple( (v.strip() for v in final_val.split(',') if v)) elif final_field in self.size_attrs: size_split = final_val.split(' ') if len(size_split) >= 1: unit = size_split[1].upper( ) if len(size_split) >= 2 else 'B' final_val = size_to_byte( size_split[0], unit, self._log) else: self._log.warning( f"Unhandled value ({val}) for attribute '{field}'" ) final_val = None pkg[final_field] = final_val return info
def map_transaction_output(self, output: str) -> DebianTransaction: to_install, to_upgrade, to_remove = None, None, None current_collection = None for line in output.split('\n'): if line.startswith( 'The following NEW packages will be installed:'): to_install = set() current_collection = to_install elif line.startswith('The following packages will be upgraded:'): to_upgrade = set() current_collection = to_upgrade elif line.startswith('The following packages will be REMOVED:'): to_remove = set() current_collection = to_remove elif line.startswith('Would download/install/remove packages'): break elif current_collection is not None and line.startswith(' '): for n, _, v, __, lv, ___, size in self.re_transaction_pkg.findall( line): pkg = DebianPackage(name=n, version=v, latest_version=lv if lv else v, transaction_size=0) if size: size_split = size.strip().split(' ') unit = size_split[1][0].upper( ) if len(size_split) >= 2 else 'B' pkg.transaction_size = size_to_byte( size_split[0], unit, self._log) current_collection.add(pkg) return DebianTransaction( to_install=tuple(to_install) if to_install else tuple(), to_remove=tuple(to_remove) if to_remove else tuple(), to_upgrade=tuple(to_upgrade) if to_upgrade else tuple())
def map_updates_data(pkgs: Iterable[str], files: bool = False) -> dict: if files: output = run_cmd('pacman -Qi -p {}'.format(' '.join(pkgs))) else: output = run_cmd('pacman -Si {}'.format(' '.join(pkgs))) if output: res = {} latest_name = None data = { 'ds': None, 's': None, 'v': None, 'c': None, 'p': None, 'd': None, 'r': None } latest_field = None for l in output.split('\n'): if l: if l[0] != ' ': line = l.strip() field_sep_idx = line.index(':') field = line[0:field_sep_idx].strip() val = line[field_sep_idx + 1:].strip() if field == 'Repository': data['r'] = val latest_field = 'r' elif field == 'Name': latest_name = val latest_field = 'n' elif field == 'Version': data['v'] = val.split('=')[0] latest_field = 'v' elif field == 'Provides': latest_field = 'p' data['p'] = { latest_name, '{}={}'.format(latest_name, data['v']) } if val != 'None': for w in val.split(' '): if w: word = w.strip() data['p'].add(word) word_split = word.split('=') if word_split[0] != word: data['p'].add(word_split[0]) elif field == 'Depends On': val = val.strip() if val == 'None': data['d'] = None else: data['d'] = { w.strip().split(':')[0].strip() for w in val.split(' ') if w } latest_field = 'd' elif field == 'Conflicts With': if val == 'None': data['c'] = None else: data['c'] = { w.strip() for w in val.split(' ') if w } latest_field = 'c' elif field == 'Download Size': size = val.split(' ') data['ds'] = size_to_byte(float(size[0]), size[1]) latest_field = 'ds' elif field == 'Installed Size': size = val.split(' ') data['s'] = size_to_byte(float(size[0]), size[1]) latest_field = 's' elif latest_name and latest_field == 's': res[latest_name] = data latest_name = None latest_field = None data = { 'ds': None, 's': None, 'c': None, 'p': None, 'd': None, 'r': None, 'v': None } else: latest_field = None elif latest_field and latest_field in ('p', 'c', 'd'): if latest_field == 'p': for w in l.split(' '): if w: word = w.strip() data['p'].add(word) word_split = word.split('=') if word_split[0] != word: data['p'].add(word_split[0]) else: data[latest_field].update( (w.strip() for w in l.split(' ') if w)) return res
def test_must_return_right_number_of_bytes_for_bit_size(self): self.assertEqual(0.125, size_to_byte(1, 'b')) self.assertEqual(0.250, size_to_byte(2, 'b')) self.assertEqual(0.40625, size_to_byte(3.25, 'b'))
def test_must_treat_string_sizes_before_converting(self): self.assertEqual(57300, size_to_byte(' 57 , 3 ', ' K '))
def test_must_return_right_number_of_bytes_for_byte_based_units(self): self.assertEqual(1.0, size_to_byte(1, 'B')) self.assertEqual(587, size_to_byte(587, 'B')) self.assertEqual(1000, size_to_byte(1, 'K')) self.assertEqual(57300, size_to_byte(57.3, 'K')) self.assertEqual(1000000, size_to_byte(1, 'M')) self.assertEqual(57300000, size_to_byte(57.3, 'M')) self.assertEqual(1000000000, size_to_byte(1, 'G')) self.assertEqual(57300000000, size_to_byte(57.3, 'G')) self.assertEqual(1000000000000, size_to_byte(1, 'T')) self.assertEqual(57300000000000, size_to_byte(57.3, 'T')) self.assertEqual(1000000000000000, size_to_byte(1, 'P')) self.assertEqual(5670000000000000, size_to_byte(5.67, 'P'))