fix: not internet connection scenario when reading installed and searching

This commit is contained in:
Vinicius Moreira
2019-09-24 12:26:33 -03:00
parent 3c51046668
commit e56ecc8f49
14 changed files with 160 additions and 72 deletions

View File

@@ -7,6 +7,8 @@ from pathlib import Path
from threading import Thread
from typing import List, Set, Type
import requests
from bauh.api.abstract.controller import SearchResult, SoftwareManager, ApplicationContext
from bauh.api.abstract.disk import DiskCacheLoader
from bauh.api.abstract.handler import ProcessWatcher
@@ -103,19 +105,40 @@ class ArchManager(SoftwareManager):
res.total = len(res.installed) + len(res.new)
return res
def _fill_aur_pkgs(self, not_signed: dict, apps: list, disk_loader: DiskCacheLoader):
def _fill_aur_pkgs(self, not_signed: dict, pkgs: list, disk_loader: DiskCacheLoader, internet_available: bool):
downgrade_enabled = git.is_enabled()
pkgsinfo = self.aur_client.get_info(not_signed.keys())
if pkgsinfo:
for pkgdata in pkgsinfo:
pkg = self.mapper.map_api_data(pkgdata, not_signed)
pkg.downgrade_enabled = downgrade_enabled
if disk_loader:
disk_loader.fill(pkg)
pkg.status = PackageStatus.READY
if internet_available:
try:
pkgsinfo = self.aur_client.get_info(not_signed.keys())
apps.append(pkg)
if pkgsinfo:
for pkgdata in pkgsinfo:
pkg = self.mapper.map_api_data(pkgdata, not_signed)
pkg.downgrade_enabled = downgrade_enabled
if disk_loader:
disk_loader.fill(pkg)
pkg.status = PackageStatus.READY
pkgs.append(pkg)
return
except requests.exceptions.ConnectionError:
self.logger.warning('Could not retrieve installed AUR packages API data. It seems the internet connection is off.')
self.logger.info("Reading only local AUR packages data")
for name, data in not_signed.items():
pkg = ArchPackage(name=name, version=data.get('version'),
latest_version=data.get('version'), description=data.get('description'),
installed=True, mirror='aur')
pkg.downgrade_enabled = downgrade_enabled
if disk_loader:
disk_loader.fill(pkg)
pkg.status = PackageStatus.READY
pkgs.append(pkg)
def _fill_mirror_pkgs(self, mirrors: dict, apps: list):
# TODO
@@ -126,13 +149,13 @@ class ArchManager(SoftwareManager):
app.update = False # TODO
apps.append(app)
def read_installed(self, disk_loader: DiskCacheLoader, limit: int = -1, only_apps: bool = False, pkg_types: Set[Type[SoftwarePackage]] = None) -> SearchResult:
def read_installed(self, disk_loader: DiskCacheLoader, limit: int = -1, only_apps: bool = False, pkg_types: Set[Type[SoftwarePackage]] = None, internet_available: bool = None) -> SearchResult:
installed = pacman.list_and_map_installed()
apps = []
if installed and installed['not_signed']:
self.dcache_updater.join()
self._fill_aur_pkgs(installed['not_signed'], apps, disk_loader)
self._fill_aur_pkgs(installed['not_signed'], apps, disk_loader, internet_available)
return SearchResult(apps, None, len(apps))

View File

@@ -7,6 +7,8 @@ from bauh.commons import resource
from bauh.gems.arch import ROOT_DIR
CACHED_ATTRS = {'command', 'icon_path', 'mirror', 'maintainer', 'desktop_entry'}
class ArchPackage(SoftwarePackage):
@@ -77,20 +79,17 @@ class ArchPackage(SoftwarePackage):
cache = {}
# required attrs to cache
for a in {'command', 'icon_path', 'mirror'}:
for a in CACHED_ATTRS:
val = getattr(self, a)
if val:
cache[a] = val
if self.desktop_entry:
cache['desktop_entry'] = self.desktop_entry
return cache
def fill_cached_data(self, data: dict):
if data:
for a in {'command', 'icon_path', 'mirror', 'desktop_entry'}:
for a in CACHED_ATTRS:
val = data.get(a)
if val:
setattr(self, a, val)
@@ -100,7 +99,7 @@ class ArchPackage(SoftwarePackage):
def can_be_run(self) -> bool:
# only returns if there is a desktop entry set for the application to avoid running command-line applications
return bool(self.command) and bool(self.desktop_entry)
return bool(self.desktop_entry) and bool(self.command)
def get_publisher(self):
return self.maintainer

View File

@@ -31,13 +31,16 @@ class AURIndexUpdater(Thread):
def run(self):
while True:
self.logger.info('Pre-indexing AUR packages in memory')
res = self.http_client.get(URL_INDEX)
try:
res = self.http_client.get(URL_INDEX)
if res and res.text:
self.man.names_index = {n.replace('-', '').replace('_', '').replace('.', ''): n for n in res.text.split('\n') if n and not n.startswith('#')}
self.logger.info('Pre-indexed {} AUR package names in memory'.format(len(self.man.names_index)))
else:
self.logger.warning('No data returned from: {}'.format(URL_INDEX))
if res and res.text:
self.man.names_index = {n.replace('-', '').replace('_', '').replace('.', ''): n for n in res.text.split('\n') if n and not n.startswith('#')}
self.logger.info('Pre-indexed {} AUR package names in memory'.format(len(self.man.names_index)))
else:
self.logger.warning('No data returned from: {}'.format(URL_INDEX))
except ConnectionError:
self.logger.warning('No internet connection: could not pre-index packages')
time.sleep(5 * 60) # updates every 5 minutes

View File

@@ -1,4 +1,3 @@
import subprocess
from datetime import datetime
from threading import Thread
from typing import List, Set, Type
@@ -27,7 +26,7 @@ class FlatpakManager(SoftwareManager):
def get_managed_types(self) -> Set["type"]:
return {FlatpakApplication}
def _map_to_model(self, app_json: dict, installed: bool, disk_loader: DiskCacheLoader) -> FlatpakApplication:
def _map_to_model(self, app_json: dict, installed: bool, disk_loader: DiskCacheLoader, internet: bool = True) -> FlatpakApplication:
app = FlatpakApplication(**app_json)
app.installed = installed
@@ -39,7 +38,9 @@ class FlatpakManager(SoftwareManager):
if not app.runtime:
if disk_loader:
disk_loader.fill(app) # preloading cached disk data
FlatpakAsyncDataLoader(app=app, api_cache=self.api_cache, manager=self, context=self.context).start()
if internet:
FlatpakAsyncDataLoader(app=app, api_cache=self.api_cache, manager=self, context=self.context).start()
else:
app.fill_cached_data(api_data)
@@ -73,22 +74,28 @@ class FlatpakManager(SoftwareManager):
def _add_updates(self, version: str, output: list):
output.append(flatpak.list_updates_as_str(version))
def read_installed(self, disk_loader: DiskCacheLoader, limit: int = -1, only_apps: bool = False, pkg_types: Set[Type[SoftwarePackage]] = None) -> SearchResult:
def read_installed(self, disk_loader: DiskCacheLoader, limit: int = -1, only_apps: bool = False, pkg_types: Set[Type[SoftwarePackage]] = None, internet_available: bool = None) -> SearchResult:
version = flatpak.get_version()
updates = []
thread_updates = Thread(target=self._add_updates, args=(version, updates))
thread_updates.start()
if internet_available:
thread_updates = Thread(target=self._add_updates, args=(version, updates))
thread_updates.start()
else:
thread_updates = None
installed = flatpak.list_installed(version)
models = []
if installed:
thread_updates.join()
if thread_updates:
thread_updates.join()
for app_json in installed:
model = self._map_to_model(app_json=app_json, installed=True, disk_loader=disk_loader)
model.update = app_json['ref'] in updates[0]
model = self._map_to_model(app_json=app_json, installed=True,
disk_loader=disk_loader, internet=internet_available)
model.update = app_json['ref'] in updates[0] if updates else None
models.append(model)
return SearchResult(models, None, len(models))

View File

@@ -8,6 +8,7 @@ from bauh.api.abstract.disk import DiskCacheLoader
from bauh.api.abstract.handler import ProcessWatcher
from bauh.api.abstract.model import SoftwarePackage, PackageHistory, PackageUpdate, PackageSuggestion, \
SuggestionPriority
from bauh.commons import internet
from bauh.commons.system import SystemProcess, ProcessHandler
from bauh.gems.snap import snap, suggestions
from bauh.gems.snap.constants import SNAP_API_URL
@@ -26,7 +27,7 @@ class SnapManager(SoftwareManager):
self.http_client = context.http_client
self.logger = context.logger
def map_json(self, app_json: dict, installed: bool, disk_loader: DiskCacheLoader) -> SnapApplication:
def map_json(self, app_json: dict, installed: bool, disk_loader: DiskCacheLoader, internet: bool = True) -> SnapApplication:
app = SnapApplication(publisher=app_json.get('publisher'),
rev=app_json.get('rev'),
notes=app_json.get('notes'),
@@ -49,7 +50,8 @@ class SnapManager(SoftwareManager):
if disk_loader and app.installed:
disk_loader.fill(app)
SnapAsyncDataLoader(app=app, api_cache=self.api_cache, manager=self, context=self.context).start()
if internet:
SnapAsyncDataLoader(app=app, api_cache=self.api_cache, manager=self, context=self.context).start()
else:
app.fill_cached_data(api_data)
@@ -79,9 +81,10 @@ class SnapManager(SoftwareManager):
else:
return SearchResult([], [], 0)
def read_installed(self, disk_loader: DiskCacheLoader, limit: int = -1, only_apps: bool = False, pkg_types: Set[Type[SoftwarePackage]] = None) -> SearchResult:
def read_installed(self, disk_loader: DiskCacheLoader, limit: int = -1, only_apps: bool = False, pkg_types: Set[Type[SoftwarePackage]] = None, internet_available: bool = None) -> SearchResult:
if snap.is_snapd_running():
installed = [self.map_json(app_json, installed=True, disk_loader=disk_loader) for app_json in snap.read_installed()]
internet_available = internet.is_available(self.http_client, self.logger)
installed = [self.map_json(app_json, installed=True, disk_loader=disk_loader, internet=internet_available) for app_json in snap.read_installed()]
return SearchResult(installed, None, len(installed))
else:
return SearchResult([], None, 0)