[arch] improvment -> initializing task 'Organizing data from installed packages' is taking about 80% less time

This commit is contained in:
Vinicius Moreira
2020-08-21 15:12:05 -03:00
parent dcd2cfd8df
commit 634f3dc932
13 changed files with 171 additions and 240 deletions

View File

@@ -27,6 +27,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- default search path set to '~/Downloads' - default search path set to '~/Downloads'
- trying to auto-fill the 'Name' and 'Version' fields - trying to auto-fill the 'Name' and 'Version' fields
- Arch - Arch
- initializing task "Organizing data from installed packages" is taking about 80% less time (now is called "Indexing packages data")
- upgrade summary: displaying the reason a given package must be installed - upgrade summary: displaying the reason a given package must be installed
<p align="center"> <p align="center">
<img src="https://raw.githubusercontent.com/vinifmor/bauh-files/master/pictures/releases/0.9.7/arch_install_reason.png"> <img src="https://raw.githubusercontent.com/vinifmor/bauh-files/master/pictures/releases/0.9.7/arch_install_reason.png">

View File

@@ -886,7 +886,7 @@ class ArchManager(SoftwareManager):
maintainer=repo, maintainer=repo,
categories=self.categories.get(name)) categories=self.categories.get(name))
disk.save_several(pkg_map, overwrite=True, maintainer=None) disk.write_several(pkgs=pkg_map, overwrite=True, maintainer=None)
return True return True
elif 'conflicting files' in upgrade_output: elif 'conflicting files' in upgrade_output:
files = self._map_conflicting_file(upgrade_output) files = self._map_conflicting_file(upgrade_output)
@@ -1532,7 +1532,7 @@ class ArchManager(SoftwareManager):
if installed: if installed:
pkg_map = {d[0]: ArchPackage(name=d[0], repository=d[1], maintainer=d[1], pkg_map = {d[0]: ArchPackage(name=d[0], repository=d[1], maintainer=d[1],
categories=self.categories.get(d[0])) for d in repo_deps} categories=self.categories.get(d[0])) for d in repo_deps}
disk.save_several(pkg_map, overwrite=True, maintainer=None) disk.write_several(pkg_map, overwrite=True, maintainer=None)
progress += len(repo_deps) * progress_increment progress += len(repo_deps) * progress_increment
self._update_progress(context, progress) self._update_progress(context, progress)
else: else:
@@ -2078,7 +2078,7 @@ class ArchManager(SoftwareManager):
maintainer=dep[1] if dep[1] != 'aur' else (aur_data[dep[0]].get('Maintainer') if aur_data else None), maintainer=dep[1] if dep[1] != 'aur' else (aur_data[dep[0]].get('Maintainer') if aur_data else None),
categories=self.categories.get(context.name)) categories=self.categories.get(context.name))
disk.save_several(pkgs=cache_map, maintainer=None, overwrite=True) disk.write_several(pkgs=cache_map, maintainer=None, overwrite=True)
context.watcher.change_substatus('') context.watcher.change_substatus('')
self._update_progress(context, 100) self._update_progress(context, 100)

View File

@@ -2,184 +2,127 @@ import json
import os import os
import re import re
from pathlib import Path from pathlib import Path
from typing import List, Dict from typing import List, Dict, Tuple, Optional, Callable
from bauh.gems.arch import pacman from bauh.gems.arch import pacman
from bauh.gems.arch.model import ArchPackage from bauh.gems.arch.model import ArchPackage
RE_DESKTOP_ENTRY = re.compile(r'(Exec|Icon|NoDisplay)\s*=\s*(.+)') RE_DESKTOP_ENTRY = re.compile(r'[\n^](Exec|Icon|NoDisplay)\s*=\s*(.+)')
RE_CLEAN_NAME = re.compile(r'[+*?%]') RE_CLEAN_NAME = re.compile(r'[+*?%]')
def write(pkg: ArchPackage): def write_several(pkgs: Dict[str, ArchPackage], overwrite: bool = True, maintainer: str = None, after_desktop_files: Optional[Callable] = None, after_written: Optional[Callable[[str], None]] = None) -> int:
data = pkg.get_data_to_cache()
Path(pkg.get_disk_cache_path()).mkdir(parents=True, exist_ok=True)
with open(pkg.get_disk_data_path(), 'w+') as f:
f.write(json.dumps(data))
def fill_icon_path(pkg: ArchPackage, icon_paths: List[str], only_exact_match: bool):
clean_name = RE_CLEAN_NAME.sub('', pkg.name)
ends_with = re.compile(r'.+/{}\.(png|svg|xpm)$'.format(pkg.icon_path if pkg.icon_path else clean_name), re.IGNORECASE)
for path in icon_paths:
if ends_with.match(path):
pkg.icon_path = path
return
if not only_exact_match:
pkg_icons_path = pacman.list_icon_paths({pkg.name})
if pkg_icons_path:
pkg.set_icon(pkg_icons_path)
def set_icon_path(pkg: ArchPackage, icon_name: str = None):
installed_icons = pacman.list_icon_paths({pkg.name})
if installed_icons:
exact_match = re.compile(r'.+/{}\..+$'.format(icon_name.split('.')[0] if icon_name else pkg.name))
for icon_path in installed_icons:
if exact_match.match(icon_path):
pkg.icon_path = icon_path
break
def save_several(pkgs: Dict[str, ArchPackage], overwrite: bool = True, maintainer: str = None, when_prepared=None, after_written=None) -> int:
if overwrite: if overwrite:
to_cache = {p.name for p in pkgs.values()} to_cache = {p.name for p in pkgs.values()}
else: else:
to_cache = {p.name for p in pkgs.values() if not os.path.exists(p.get_disk_cache_path())} to_cache = {p.name for p in pkgs.values() if not os.path.exists(p.get_disk_cache_path())}
desktop_files = pacman.list_desktop_entries(to_cache) desktop_files = pacman.map_desktop_files(*to_cache)
no_desktop_files = set() if after_desktop_files:
after_desktop_files()
to_write = [] if not desktop_files:
for pkgname in to_cache:
write(pkg=pkgs[pkgname], maintainer=maintainer, after_written=after_written)
if desktop_files: return len(to_cache)
desktop_matches, no_exact_match = {}, set()
for pkg in to_cache: # first try to find exact matches
try:
clean_name = RE_CLEAN_NAME.sub('', pkg)
ends_with = re.compile(r'/usr/share/applications/{}.desktop$'.format(clean_name), re.IGNORECASE)
except:
raise
for f in desktop_files:
if ends_with.match(f) and os.path.isfile(f):
desktop_matches[pkg] = f
break
if pkg not in desktop_matches:
no_exact_match.add(pkg)
if no_exact_match: # check every not matched app individually
for pkgname in no_exact_match:
entries = pacman.list_desktop_entries({pkgname})
if entries:
if len(entries) > 1:
for e in entries:
if e.startswith('/usr/share/applications') and os.path.isfile(e):
desktop_matches[pkgname] = e
break
else:
if os.path.isfile(entries[0]):
desktop_matches[pkgname] = entries[0]
if not desktop_matches:
no_desktop_files = to_cache
else:
if len(desktop_matches) != len(to_cache):
no_desktop_files = {p for p in to_cache if p not in desktop_matches}
instances, apps_icons_noabspath = [], []
for pkgname, file in desktop_matches.items():
p = pkgs[pkgname]
with open(file) as f:
try:
desktop_entry = f.read()
p.desktop_entry = file
for field in RE_DESKTOP_ENTRY.findall(desktop_entry):
if field[0] == 'Exec':
p.command = field[1].strip().replace('"', '')
elif field[0] == 'Icon':
p.icon_path = field[1].strip()
if p.icon_path and '/' not in p.icon_path: # if the icon full path is not defined
apps_icons_noabspath.append(p)
elif field[0] == 'NoDisplay' and field[1].strip().lower() == 'true':
p.command = None
if p.icon_path:
apps_icons_noabspath.remove(p.icon_path)
p.icon_path = None
except:
continue
instances.append(p)
if when_prepared:
when_prepared(p.name)
if apps_icons_noabspath:
icon_paths = pacman.list_icon_paths({app.name for app in apps_icons_noabspath})
if icon_paths:
for p in apps_icons_noabspath:
fill_icon_path(p, icon_paths, False)
for p in instances:
to_write.append(p)
else: else:
no_desktop_files = {n for n in to_cache} for pkgname in to_cache:
pkgfiles = desktop_files.get(pkgname)
if no_desktop_files: if not pkgfiles:
bin_paths = pacman.list_bin_paths(no_desktop_files) write(pkg=pkgs[pkgname], maintainer=maintainer, after_written=after_written)
icon_paths = pacman.list_icon_paths(no_desktop_files) else:
desktop_entry = find_best_desktop_entry(pkgname, pkgfiles)
for n in no_desktop_files: if desktop_entry:
p = pkgs[n] write(pkg=pkgs[pkgname], maintainer=maintainer, after_written=after_written,
desktop_file=desktop_entry[0], command=desktop_entry[1], icon=desktop_entry[2])
else:
write(pkg=pkgs[pkgname], maintainer=maintainer, after_written=after_written)
if bin_paths: return len(to_cache)
clean_name = RE_CLEAN_NAME.sub('', p.name)
ends_with = re.compile(r'.+/{}$'.format(clean_name), re.IGNORECASE)
for path in bin_paths:
if ends_with.match(path):
p.command = path
break
if icon_paths:
fill_icon_path(p, icon_paths, only_exact_match=True)
to_write.append(p) def find_best_desktop_entry(pkgname: str, desktop_files: List[str]) -> Optional[Tuple[str, str, str]]:
if len(desktop_files) == 1:
exec_icon = read_desktop_exec_and_icon(pkgname, desktop_files[0])
if when_prepared: if exec_icon:
when_prepared(p.name) return desktop_files[0], exec_icon[0], exec_icon[1]
else:
# trying to find the exact name match:
for dfile in desktop_files:
if dfile.endswith('{}.desktop'.format(pkgname)):
exec_icon = read_desktop_exec_and_icon(pkgname, dfile)
if to_write: if exec_icon:
written = set() return dfile, exec_icon[0], exec_icon[1]
for p in to_write:
if maintainer and not p.maintainer:
p.maintainer = maintainer
write(p) # trying to find a close name match:
clean_name = RE_CLEAN_NAME.sub('', pkgname)
for dfile in desktop_files:
if dfile.endswith('{}.desktop'.format(clean_name)):
exec_icon = read_desktop_exec_and_icon(clean_name, dfile)
if after_written: if exec_icon:
after_written(p.name) return dfile, exec_icon[0], exec_icon[1]
written.add(p.name) # finding any match:
for dfile in desktop_files:
exec_icon = read_desktop_exec_and_icon(pkgname, dfile)
if len(to_write) != len(to_cache): if exec_icon:
for pkgname in to_cache: return dfile, exec_icon[0], exec_icon[1]
if pkgname not in written:
Path(ArchPackage.disk_cache_path(pkgname)).mkdir(parents=True, exist_ok=True)
if after_written:
after_written(pkgname)
return len(to_write)
return 0 def read_desktop_exec_and_icon(pkgname: str, desktop_file: str) -> Optional[Tuple[str, str]]:
if os.path.isfile(desktop_file):
with open(desktop_file) as f:
possibilities = set()
content = f.read()
cmd, icon = None, None
for field in RE_DESKTOP_ENTRY.findall(content):
if field[0] == 'Exec':
cmd = field[1].strip().replace('"', '')
elif field[0] == 'Icon':
icon = field[1].strip()
elif field[0] == 'NoDisplay' and field[1].strip().lower() == 'true':
cmd, icon = None, None
if cmd and icon:
possibilities.add((cmd, icon))
cmd, icon = None, None
if possibilities:
if len(possibilities) == 1:
return [*possibilities][0]
else:
# trying to find the exact name x command match
for p in possibilities:
if p[0].startswith('{} '.format(pkgname)):
return p
return sorted(possibilities)[0] # returning any possibility
def write(pkg: ArchPackage, desktop_file: Optional[str] = None, command: Optional[str] = None,
icon: Optional[str] = None, maintainer: Optional[str] = None, after_written: Optional[callable] = None):
pkg.desktop_entry = desktop_file
pkg.command = command
pkg.icon_path = icon
if maintainer and not pkg.maintainer:
pkg.maintainer = maintainer
Path(pkg.get_disk_cache_path()).mkdir(parents=True, exist_ok=True)
data = pkg.get_data_to_cache()
with open(pkg.get_disk_data_path(), 'w+') as f:
f.write(json.dumps(data))
if after_written:
after_written(pkg.name)

View File

@@ -19,6 +19,7 @@ RE_UPDATE_REQUIRED_FIELDS = re.compile(r'(\bProvides\b|\bInstalled Size\b|\bConf
RE_REMOVE_TRANSITIVE_DEPS = re.compile(r'removing\s([\w\-_]+)\s.+required\sby\s([\w\-_]+)\n?') RE_REMOVE_TRANSITIVE_DEPS = re.compile(r'removing\s([\w\-_]+)\s.+required\sby\s([\w\-_]+)\n?')
RE_AVAILABLE_MIRRORS = re.compile(r'.+\s+OK\s+.+\s+(\d+:\d+)\s+.+(http.+)') RE_AVAILABLE_MIRRORS = re.compile(r'.+\s+OK\s+.+\s+(\d+:\d+)\s+.+(http.+)')
RE_PACMAN_SYNC_FIRST = re.compile(r'SyncFirst\s*=\s*(.+)') RE_PACMAN_SYNC_FIRST = re.compile(r'SyncFirst\s*=\s*(.+)')
RE_DESKTOP_FILES = re.compile(r'\n?([\w\-_]+)\s+(/usr/share/.+\.desktop)')
def is_available() -> bool: def is_available() -> bool:
@@ -153,42 +154,19 @@ def install_as_process(pkgpaths: Iterable[str], root_password: str, file: bool,
shell=True) shell=True)
def list_desktop_entries(pkgnames: Set[str]) -> List[str]: def map_desktop_files(*pkgnames) -> Dict[str, List[str]]:
res = {}
if pkgnames: if pkgnames:
installed_files = new_subprocess(['pacman', '-Qlq', *pkgnames]) output = run_cmd('pacman -Ql {}'.format(' '.join(pkgnames)), print_error=False)
desktop_files = [] if output:
for out in new_subprocess(['grep', '-E', ".desktop$"], stdin=installed_files.stdout).stdout: for match in RE_DESKTOP_FILES.findall(output):
if out: pkgfiles = res.get(match[0], [])
desktop_files.append(out.decode().strip()) res[match[0]] = pkgfiles
pkgfiles.append(match[1])
return desktop_files return res
def list_icon_paths(pkgnames: Set[str]) -> List[str]:
installed_files = new_subprocess(['pacman', '-Qlq', *pkgnames])
icon_files = []
for out in new_subprocess(['grep', '-E', '.(png|svg|xpm)$'], stdin=installed_files.stdout).stdout:
if out:
line = out.decode().strip()
if line:
icon_files.append(line)
return icon_files
def list_bin_paths(pkgnames: Set[str]) -> List[str]:
installed_files = new_subprocess(['pacman', '-Qlq', *pkgnames])
bin_paths = []
for out in new_subprocess(['grep', '-E', '^/usr/bin/.+'], stdin=installed_files.stdout).stdout:
if out:
line = out.decode().strip()
if line:
bin_paths.append(line)
return bin_paths
def list_installed_files(pkgname: str) -> List[str]: def list_installed_files(pkgname: str) -> List[str]:

View File

@@ -181,10 +181,11 @@ arch.substatus.loading_files=Loading package files
arch.substatus.pre_hooks=Running pre-transaction hooks arch.substatus.pre_hooks=Running pre-transaction hooks
arch.sync_databases.substatus=Synchronizing package databases arch.sync_databases.substatus=Synchronizing package databases
arch.sync_databases.substatus.error=It was not possible to synchronize the package database arch.sync_databases.substatus.error=It was not possible to synchronize the package database
arch.task.disk_cache=Organitzen dades dels paquets instal·lats arch.task.disk_cache=Indexing packages data
arch.task.disk_cache.indexed=Preparats arch.task.disk_cache.checking=Checking index
arch.task.disk_cache.prepared=Llegits arch.task.disk_cache.indexed=Indexed
arch.task.disk_cache.reading=Determinant els paquets instal·lats arch.task.disk_cache.indexing=Indexing
arch.task.disk_cache.reading_files=Reading files
arch.task.mirrors=Refreshing mirrors arch.task.mirrors=Refreshing mirrors
arch.task.optimizing=Optimizing {} arch.task.optimizing=Optimizing {}
arch.task.sync_databases.waiting=Waiting for {} arch.task.sync_databases.waiting=Waiting for {}

View File

@@ -181,10 +181,11 @@ arch.substatus.loading_files=Loading package files
arch.substatus.pre_hooks=Running pre-transaction hooks arch.substatus.pre_hooks=Running pre-transaction hooks
arch.sync_databases.substatus=Synchronizing package databases arch.sync_databases.substatus=Synchronizing package databases
arch.sync_databases.substatus.error=It was not possible to synchronize the package database arch.sync_databases.substatus.error=It was not possible to synchronize the package database
arch.task.disk_cache=Organizing data from installed packages arch.task.disk_cache=Indexing packages data
arch.task.disk_cache.indexed=Ready arch.task.disk_cache.checking=Checking index
arch.task.disk_cache.prepared=Read arch.task.disk_cache.indexed=Indexed
arch.task.disk_cache.reading=Determining installed packages arch.task.disk_cache.indexing=Indexing
arch.task.disk_cache.reading_files=Reading files
arch.task.mirrors=Refreshing mirrors arch.task.mirrors=Refreshing mirrors
arch.task.optimizing=Optimizing {} arch.task.optimizing=Optimizing {}
arch.task.sync_databases.waiting=Waiting for {} arch.task.sync_databases.waiting=Waiting for {}

View File

@@ -182,10 +182,11 @@ arch.substatus.loading_files=Loading package files
arch.substatus.pre_hooks=Running pre-transaction hooks arch.substatus.pre_hooks=Running pre-transaction hooks
arch.sync_databases.substatus=Synchronizing package databases arch.sync_databases.substatus=Synchronizing package databases
arch.sync_databases.substatus.error=It was not possible to synchronize the package database arch.sync_databases.substatus.error=It was not possible to synchronize the package database
arch.task.disk_cache=Organizing data from installed packages arch.task.disk_cache=Indexing packages data
arch.task.disk_cache.indexed=Ready arch.task.disk_cache.checking=Checking index
arch.task.disk_cache.prepared=Read arch.task.disk_cache.indexed=Indexed
arch.task.disk_cache.reading=Determining installed packages arch.task.disk_cache.indexing=Indexing
arch.task.disk_cache.reading_files=Reading files
arch.task.mirrors=Refreshing mirrors arch.task.mirrors=Refreshing mirrors
arch.task.optimizing=Optimizing {} arch.task.optimizing=Optimizing {}
arch.task.sync_databases.waiting=Waiting for {} arch.task.sync_databases.waiting=Waiting for {}

View File

@@ -181,10 +181,11 @@ arch.substatus.loading_files=Cargando archivos de los paquetes
arch.substatus.pre_hooks=Ejecutando ganchos pre-transacción arch.substatus.pre_hooks=Ejecutando ganchos pre-transacción
arch.sync_databases.substatus=Sincronizando bases de paquetes arch.sync_databases.substatus=Sincronizando bases de paquetes
arch.sync_databases.substatus.error=No fue posible sincronizar la base de paquetes arch.sync_databases.substatus.error=No fue posible sincronizar la base de paquetes
arch.task.disk_cache=Organizando datos de paquetes instalados arch.task.disk_cache=Indexando datos de paquetes
arch.task.disk_cache.indexed=Listos arch.task.disk_cache.checking=Comprobando índice
arch.task.disk_cache.prepared=Lidos arch.task.disk_cache.indexed=Indexados
arch.task.disk_cache.reading=Determinando los paquetes instalados arch.task.disk_cache.indexing=Indexando
arch.task.disk_cache.reading_files=Lendo archivos
arch.task.mirrors=Actualizando espejos arch.task.mirrors=Actualizando espejos
arch.task.optimizing=Optimizando {} arch.task.optimizing=Optimizando {}
arch.task.sync_databases.waiting=Esperando por {} arch.task.sync_databases.waiting=Esperando por {}

View File

@@ -181,10 +181,11 @@ arch.substatus.loading_files=Loading package files
arch.substatus.pre_hooks=Running pre-transaction hooks arch.substatus.pre_hooks=Running pre-transaction hooks
arch.sync_databases.substatus=Synchronizing package databases arch.sync_databases.substatus=Synchronizing package databases
arch.sync_databases.substatus.error=It was not possible to synchronize the package database arch.sync_databases.substatus.error=It was not possible to synchronize the package database
arch.task.disk_cache=Organizzando i dati dai pacchetti installati arch.task.disk_cache=Indexing packages data
arch.task.disk_cache.indexed=Pronti arch.task.disk_cache.checking=Checking index
arch.task.disk_cache.prepared=Letti arch.task.disk_cache.indexed=Indexed
arch.task.disk_cache.reading=Determinando i pacchetti installati arch.task.disk_cache.indexing=Indexing
arch.task.disk_cache.reading_files=Reading files
arch.task.mirrors=Aggiornando i mirror arch.task.mirrors=Aggiornando i mirror
arch.task.optimizing=Ottimizzando {} arch.task.optimizing=Ottimizzando {}
arch.task.sync_databases.waiting=Waiting for {} arch.task.sync_databases.waiting=Waiting for {}

View File

@@ -181,10 +181,11 @@ arch.substatus.loading_files=Carregando os arquivos dos pacotes
arch.substatus.pre_hooks=Executando ganchos pré-transação arch.substatus.pre_hooks=Executando ganchos pré-transação
arch.sync_databases.substatus=Sincronizando bases de pacotes arch.sync_databases.substatus=Sincronizando bases de pacotes
arch.sync_databases.substatus.error=Não foi possível sincronizar as bases de pacotes arch.sync_databases.substatus.error=Não foi possível sincronizar as bases de pacotes
arch.task.disk_cache=Organizando dados dos pacotes instalados arch.task.disk_cache=Indexando dados de pacotes
arch.task.disk_cache.indexed=Prontos arch.task.disk_cache.checking=Verificando índice
arch.task.disk_cache.prepared=Lidos arch.task.disk_cache.indexed=Indexados
arch.task.disk_cache.reading=Determinando pacotes instalados arch.task.disk_cache.indexing=Indexando
arch.task.disk_cache.reading_files=Lendo arquivos
arch.task.mirrors=Atualizando espelhos arch.task.mirrors=Atualizando espelhos
arch.task.optimizing=Otimizando {} arch.task.optimizing=Otimizando {}
arch.task.sync_databases.waiting=Aguardando por {} arch.task.sync_databases.waiting=Aguardando por {}

View File

@@ -181,10 +181,11 @@ arch.substatus.loading_files=Loading package files
arch.substatus.pre_hooks=Running pre-transaction hooks arch.substatus.pre_hooks=Running pre-transaction hooks
arch.sync_databases.substatus=Синхронизация баз данных пакетов arch.sync_databases.substatus=Синхронизация баз данных пакетов
arch.sync_databases.substatus.error=Синхронизировать базу данных пакета не удалось arch.sync_databases.substatus.error=Синхронизировать базу данных пакета не удалось
arch.task.disk_cache=Organizing data from installed packages arch.task.disk_cache=Indexing packages data
arch.task.disk_cache.indexed=Ready arch.task.disk_cache.checking=Checking index
arch.task.disk_cache.prepared=Read arch.task.disk_cache.indexed=Indexed
arch.task.disk_cache.reading=Determining installed packages arch.task.disk_cache.indexing=Indexing
arch.task.disk_cache.reading_files=Reading files
arch.task.mirrors=Обновление зеркал arch.task.mirrors=Обновление зеркал
arch.task.optimizing=Optimizing {} arch.task.optimizing=Optimizing {}
arch.task.sync_databases.waiting=Waiting for {} arch.task.sync_databases.waiting=Waiting for {}

View File

@@ -181,10 +181,11 @@ arch.substatus.loading_files=Loading package files
arch.substatus.pre_hooks=Running pre-transaction hooks arch.substatus.pre_hooks=Running pre-transaction hooks
arch.sync_databases.substatus=Paket veritabanı eşitleniyor arch.sync_databases.substatus=Paket veritabanı eşitleniyor
arch.sync_databases.substatus.error=Paket veritabanı eşitlenemedi arch.sync_databases.substatus.error=Paket veritabanı eşitlenemedi
arch.task.disk_cache=Kurulu paket verileri düzenleniyor arch.task.disk_cache=Indexing packages data
arch.task.disk_cache.indexed=Hazır arch.task.disk_cache.checking=Checking index
arch.task.disk_cache.prepared=okunan arch.task.disk_cache.indexed=Indexed
arch.task.disk_cache.reading=Kurulu paketler belirleniyor arch.task.disk_cache.indexing=Indexing
arch.task.disk_cache.reading_files=Reading files
arch.task.mirrors=Yansılar yenileniyor arch.task.mirrors=Yansılar yenileniyor
arch.task.optimizing=Uygun hale getiriliyor {} arch.task.optimizing=Uygun hale getiriliyor {}
arch.task.sync_databases.waiting=Waiting for {} arch.task.sync_databases.waiting=Waiting for {}

View File

@@ -66,8 +66,6 @@ class ArchDiskCacheUpdater(Thread):
self.task_man = task_man self.task_man = task_man
self.task_id = 'arch_cache_up' self.task_id = 'arch_cache_up'
self.i18n = i18n self.i18n = i18n
self.prepared = 0
self.prepared_template = self.i18n['arch.task.disk_cache.prepared'] + ': {}/ {}'
self.indexed = 0 self.indexed = 0
self.indexed_template = self.i18n['arch.task.disk_cache.indexed'] + ': {}/ {}' self.indexed_template = self.i18n['arch.task.disk_cache.indexed'] + ': {}/ {}'
self.to_index = 0 self.to_index = 0
@@ -79,19 +77,18 @@ class ArchDiskCacheUpdater(Thread):
self.installed_hash_path = '{}/installed.sha1'.format(ARCH_CACHE_PATH) self.installed_hash_path = '{}/installed.sha1'.format(ARCH_CACHE_PATH)
self.installed_cache_dir = '{}/installed'.format(ARCH_CACHE_PATH) self.installed_cache_dir = '{}/installed'.format(ARCH_CACHE_PATH)
def update_prepared(self, pkgname: str, add: bool = True):
if add:
self.prepared += 1
sub = self.prepared_template.format(self.prepared, self.to_index)
progress = ((self.prepared + self.indexed) / self.progress) * 100 if self.progress > 0 else 0
self.task_man.update_progress(self.task_id, progress, sub)
def update_indexed(self, pkgname: str): def update_indexed(self, pkgname: str):
self.indexed += 1 self.indexed += 1
sub = self.indexed_template.format(self.indexed, self.to_index) sub = self.indexed_template.format(self.indexed, self.to_index)
progress = ((self.prepared + self.indexed) / self.progress) * 100 if self.progress > 0 else 0 self.progress = self.progress + (self.indexed / self.to_index) * 50
self.task_man.update_progress(self.task_id, progress, sub) self.task_man.update_progress(self.task_id, self.progress, sub)
def _update_progress(self, progress: float, msg: str):
self.progress = progress
self.task_man.update_progress(self.task_id, self.progress, msg)
def _notify_reading_files(self):
self._update_progress(50, self.i18n['arch.task.disk_cache.indexing'])
def run(self): def run(self):
if not any([self.aur, self.repositories]): if not any([self.aur, self.repositories]):
@@ -100,19 +97,21 @@ class ArchDiskCacheUpdater(Thread):
ti = time.time() ti = time.time()
self.task_man.register_task(self.task_id, self.i18n['arch.task.disk_cache'], get_icon_path()) self.task_man.register_task(self.task_id, self.i18n['arch.task.disk_cache'], get_icon_path())
self.task_man.update_progress(self.task_id, 1, '')
self.logger.info("Checking already cached package data") self.logger.info("Checking already cached package data")
self._update_progress(1, self.i18n['arch.task.disk_cache.checking'])
cache_dirs = [fpath for fpath in glob.glob('{}/*'.format(self.installed_cache_dir)) if os.path.isdir(fpath)] cache_dirs = [fpath for fpath in glob.glob('{}/*'.format(self.installed_cache_dir)) if os.path.isdir(fpath)]
not_cached_names = None not_cached_names = None
self._update_progress(15, self.i18n['arch.task.disk_cache.checking'])
if cache_dirs: # if there are cache data if cache_dirs: # if there are cache data
installed_names = pacman.list_installed_names() installed_names = pacman.list_installed_names()
cached_pkgs = {cache_dir.split('/')[-1] for cache_dir in cache_dirs} cached_pkgs = {cache_dir.split('/')[-1] for cache_dir in cache_dirs}
not_cached_names = installed_names.difference(cached_pkgs) not_cached_names = installed_names.difference(cached_pkgs)
self._update_progress(20, self.i18n['arch.task.disk_cache.checking'])
if not not_cached_names: if not not_cached_names:
self.task_man.update_progress(self.task_id, 100, '') self.task_man.update_progress(self.task_id, 100, '')
self.task_man.finish_task(self.task_id) self.task_man.finish_task(self.task_id)
@@ -123,21 +122,23 @@ class ArchDiskCacheUpdater(Thread):
self.logger.info('Pre-caching installed Arch packages data to disk') self.logger.info('Pre-caching installed Arch packages data to disk')
self._update_progress(20, self.i18n['arch.task.disk_cache.checking'])
installed = self.controller.read_installed(disk_loader=None, internet_available=self.internet_available, installed = self.controller.read_installed(disk_loader=None, internet_available=self.internet_available,
only_apps=False, pkg_types=None, limit=-1, names=not_cached_names, only_apps=False, pkg_types=None, limit=-1, names=not_cached_names,
wait_disk_cache=False).installed wait_disk_cache=False).installed
self.task_man.update_progress(self.task_id, 0, self.i18n['arch.task.disk_cache.reading']) self._update_progress(35, self.i18n['arch.task.disk_cache.checking'])
saved = 0 saved = 0
pkgs = {p.name: p for p in installed if ((self.aur and p.repository == 'aur') or (self.repositories and p.repository != 'aur')) and not os.path.exists(p.get_disk_cache_path())}
pkgs = {p.name: p for p in installed if ((self.aur and p.repository == 'aur') or (self.repositories and p.repository != 'aur')) and not os.path.exists(p.get_disk_cache_path())}
self.to_index = len(pkgs) self.to_index = len(pkgs)
self.progress = self.to_index * 2
self.update_prepared(None, add=False)
# overwrite == True because the verification already happened # overwrite == True because the verification already happened
saved += disk.save_several(pkgs, when_prepared=self.update_prepared, after_written=self.update_indexed, overwrite=True) self._update_progress(40, self.i18n['arch.task.disk_cache.reading_files'])
saved += disk.write_several(pkgs=pkgs,
after_desktop_files=self._notify_reading_files,
after_written=self.update_indexed, overwrite=True)
self.task_man.update_progress(self.task_id, 100, None) self.task_man.update_progress(self.task_id, 100, None)
self.task_man.finish_task(self.task_id) self.task_man.finish_task(self.task_id)