refactoring async work

This commit is contained in:
Vinícius Moreira
2019-07-24 16:01:44 -03:00
committed by GitHub
parent e35b515b5b
commit c7a111174a
10 changed files with 263 additions and 222 deletions

View File

@@ -1,11 +1,9 @@
import time
from abc import ABC, abstractmethod
from argparse import Namespace
from threading import Lock
from typing import List, Dict
from fpakman.core.disk import DiskCacheLoader, DiskCacheLoaderFactory
from fpakman.core.model import Application
from fpakman.core.model import Application, ApplicationUpdate
from fpakman.core.system import FpakmanProcess
@@ -82,6 +80,10 @@ class ApplicationManager(ABC):
"""
pass
@abstractmethod
def list_updates(self) -> List[ApplicationUpdate]:
pass
class GenericApplicationManager(ApplicationManager):
@@ -90,7 +92,6 @@ class GenericApplicationManager(ApplicationManager):
self.managers = managers
self.map = {m.get_app_type(): m for m in self.managers}
self.disk_loader_factory = disk_loader_factory
self.lock_read = Lock()
self._enabled_map = {} if app_args.check_packaging_once else None
self.prepare()
@@ -131,57 +132,48 @@ class GenericApplicationManager(ApplicationManager):
return man.is_enabled()
def search(self, word: str, disk_loader: DiskCacheLoader = None) -> Dict[str, List[Application]]:
self.lock_read.acquire()
try:
res = {'installed': [], 'new': []}
res = {'installed': [], 'new': []}
norm_word = word.strip().lower()
disk_loader = None
norm_word = word.strip().lower()
disk_loader = None
for man in self.managers:
if self._is_enabled(man):
if not disk_loader:
disk_loader = self.disk_loader_factory.new()
disk_loader.start()
for man in self.managers:
if self._is_enabled(man):
if not disk_loader:
disk_loader = self.disk_loader_factory.new()
disk_loader.start()
apps_found = man.search(word=norm_word, disk_loader=disk_loader)
res['installed'].extend(apps_found['installed'])
res['new'].extend(apps_found['new'])
apps_found = man.search(word=norm_word, disk_loader=disk_loader)
res['installed'].extend(apps_found['installed'])
res['new'].extend(apps_found['new'])
disk_loader.stop = True
disk_loader.join()
disk_loader.stop = True
disk_loader.join()
for key in res:
res[key] = self._sort(res[key], norm_word)
for key in res:
res[key] = self._sort(res[key], norm_word)
return res
finally:
self.lock_read.release()
return res
def read_installed(self, disk_loader: DiskCacheLoader = None) -> List[Application]:
self.lock_read.acquire()
installed = []
try:
installed = []
disk_loader = None
disk_loader = None
for man in self.managers:
if self._is_enabled(man):
if not disk_loader:
disk_loader = self.disk_loader_factory.new()
disk_loader.start()
for man in self.managers:
if self._is_enabled(man):
if not disk_loader:
disk_loader = self.disk_loader_factory.new()
disk_loader.start()
installed.extend(man.read_installed(disk_loader=disk_loader))
installed.extend(man.read_installed(disk_loader=disk_loader))
disk_loader.stop = True
disk_loader.join()
disk_loader.stop = True
disk_loader.join()
installed.sort(key=lambda a: a.base_data.name.lower())
installed.sort(key=lambda a: a.base_data.name.lower())
return installed
finally:
self.lock_read.release()
return installed
def can_downgrade(self):
return True
@@ -260,8 +252,17 @@ class GenericApplicationManager(ApplicationManager):
return man.refresh(app, root_password)
def prepare(self):
if self.managers:
for man in self.managers:
if self._is_enabled(man):
man.prepare()
def list_updates(self) -> List[ApplicationUpdate]:
updates = []
if self.managers:
for man in self.managers:
if self._is_enabled(man):
updates.extend(man.list_updates())
return updates

View File

@@ -9,8 +9,8 @@ from fpakman.core.controller import ApplicationManager
from fpakman.core.disk import DiskCacheLoader
from fpakman.core.flatpak import flatpak
from fpakman.core.flatpak.model import FlatpakApplication
from fpakman.core.flatpak.worker import FlatpakAsyncDataLoader
from fpakman.core.model import ApplicationData
from fpakman.core.flatpak.worker import FlatpakAsyncDataLoader, FlatpakUpdateLoader
from fpakman.core.model import ApplicationData, ApplicationUpdate
from fpakman.core.system import FpakmanProcess
from fpakman.util.cache import Cache
@@ -148,3 +148,33 @@ class FlatpakManager(ApplicationManager):
def prepare(self):
flatpak.set_default_remotes()
def list_updates(self) -> List[ApplicationUpdate]:
updates = []
installed = flatpak.list_installed(extra_fields=False)
if installed:
available_updates = flatpak.list_updates_as_str()
if available_updates:
loaders = None
for app_json in installed:
if app_json['id'] in available_updates:
loader = FlatpakUpdateLoader(app=app_json, http_session=self.http_session)
loader.start()
if loaders is None:
loaders = []
loaders.append(loader)
if loaders:
for loader in loaders:
loader.join()
app = loader.app
updates.append(ApplicationUpdate(app_id='{}:{}'.format(app['id'], app['branch']),
app_type='flatpak',
version=app.get('version')))
return updates

View File

@@ -1,6 +1,6 @@
import re
import subprocess
from typing import List
from typing import List, Set
from fpakman.core import system
from fpakman.core.exception import NoInternetException
@@ -8,7 +8,7 @@ from fpakman.core.exception import NoInternetException
BASE_CMD = 'flatpak'
def app_str_to_json(line: str, version: str) -> dict:
def app_str_to_json(line: str, version: str, extra_fields: bool = True) -> dict:
app_array = line.split('\t')
@@ -17,18 +17,21 @@ def app_str_to_json(line: str, version: str) -> dict:
'id': app_array[1],
'version': app_array[2],
'branch': app_array[3]}
elif '1.0' <= version < '1.1':
app = {'ref': app_array[0], 'options': app_array[1]}
ref_data = app['ref'].split('/')
app['id'] = ref_data[0]
app['arch'] = ref_data[1]
app['branch'] = ref_data[2]
app['name'] = ref_data[0].split('.')[-1]
app['version'] = None
elif '1.0' <= version < '1.1':
ref_data = app_array[0].split('/')
app = {'id': ref_data[0],
'arch': ref_data[1],
'name': ref_data[0].split('.')[-1],
'ref': app_array[0],
'options': app_array[1],
'branch': ref_data[2],
'version': None}
elif '1.2' <= version < '1.3':
app = {'name': app_array[1].strip().split('.')[-1],
'id': app_array[1],
app = {'id': app_array[1],
'name': app_array[1].strip().split('.')[-1],
'version': app_array[2],
'branch': app_array[3],
'arch': app_array[4],
@@ -36,8 +39,9 @@ def app_str_to_json(line: str, version: str) -> dict:
else:
raise Exception('Unsupported version')
extra_fields = get_app_info_fields(app['id'], app['branch'], ['origin', 'arch', 'ref', 'commit'], check_runtime=True)
app.update(extra_fields)
if extra_fields:
extra_fields = get_app_info_fields(app['id'], app['branch'], ['origin', 'arch', 'ref', 'commit'], check_runtime=True)
app.update(extra_fields)
return app
@@ -81,13 +85,13 @@ def get_app_info(app_id: str, branch: str):
return system.run_cmd('{} info {} {}'.format(BASE_CMD, app_id, branch))
def list_installed() -> List[dict]:
def list_installed(extra_fields: bool = True) -> List[dict]:
apps_str = system.run_cmd('{} list'.format(BASE_CMD))
if apps_str:
version = get_version()
app_lines = apps_str.split('\n')
return [app_str_to_json(line, version) for line in app_lines if line]
return [app_str_to_json(line, version, extra_fields=extra_fields) for line in app_lines if line]
return []
@@ -215,4 +219,3 @@ def install_and_stream(app_id: str, origin: str):
def set_default_remotes():
system.run_cmd('flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo')

View File

@@ -1,9 +1,11 @@
import time
import traceback
from threading import Thread
from colorama import Fore
from fpakman.core.controller import ApplicationManager
from fpakman.core.flatpak import flatpak
from fpakman.core.flatpak.constants import FLATHUB_API_URL, FLATHUB_URL
from fpakman.core.flatpak.model import FlatpakApplication
from fpakman.core.model import ApplicationStatus
@@ -82,3 +84,41 @@ class FlatpakAsyncDataLoader(AsyncDataLoader):
http_session=self.http_session,
timeout=self.timeout,
app=self.app)
class FlatpakUpdateLoader(Thread):
def __init__(self, app: dict, http_session, attempts: int = 2, timeout: int = 20):
super(FlatpakUpdateLoader, self).__init__(daemon=True)
self.app = app
self.http_session = http_session
self.attempts = attempts
self.timeout = timeout
def run(self):
if self.app.get('ref') is None:
self.app.update(flatpak.get_app_info_fields(self.app['id'], self.app['branch'], fields=['ref'], check_runtime=True))
else:
self.app['runtime'] = self.app['ref'].startswith('runtime/')
if not self.app['runtime']:
current_attempts = 0
while current_attempts < self.attempts:
current_attempts += 1
try:
res = self.http_session.get('{}/apps/{}'.format(FLATHUB_API_URL, self.app['id']), timeout=self.timeout)
if res.status_code == 200 and res.text:
data = res.json()
if data.get('currentReleaseVersion'):
self.app['version'] = data['currentReleaseVersion']
break
except:
traceback.print_exc()
time.sleep(0.5)

View File

@@ -86,3 +86,14 @@ class Application(ABC):
def __str__(self):
return '{} (id={}, name={})'.format(self.__class__.__name__, self.base_data.id, self.base_data.name)
class ApplicationUpdate:
def __init__(self, app_id: str, version: str, app_type: str):
self.id = app_id
self.version = version
self.type = app_type
def __str__(self):
return '{} (id={}, type={}, new_version={})'.format(self.__class__.__name__, self.id, self.type, self.type)

View File

@@ -7,7 +7,7 @@ from typing import Dict, List
from fpakman.core import disk
from fpakman.core.controller import ApplicationManager
from fpakman.core.disk import DiskCacheLoader
from fpakman.core.model import ApplicationData, Application
from fpakman.core.model import ApplicationData, Application, ApplicationUpdate
from fpakman.core.snap import snap
from fpakman.core.snap.model import SnapApplication
from fpakman.core.snap.worker import SnapAsyncDataLoader
@@ -131,3 +131,6 @@ class SnapManager(ApplicationManager):
def prepare(self):
pass
def list_updates(self) -> List[ApplicationUpdate]:
return []