loading translations from extension

This commit is contained in:
Vinicius Moreira
2019-07-29 18:51:39 -03:00
parent dff34ebb5f
commit 5918f0c3ad
17 changed files with 29 additions and 703 deletions

View File

@@ -1,5 +1,4 @@
import argparse
import inspect
import os
import pkgutil
import sys
@@ -8,13 +7,13 @@ import requests
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QApplication
from colorama import Fore
from fpakman_api.util.cache import Cache
from fpakman_api.util.disk import DiskCacheLoaderFactory
from fpakman import __version__, __app_name__, ROOT_DIR
from fpakman.core import resource
from fpakman.core import resource, extensions
from fpakman.core.controller import GenericApplicationManager
from fpakman_api.util.disk import DiskCacheLoaderFactory
from fpakman.util import util
from fpakman.util.cache import Cache
from fpakman.util.memory import CacheCleaner
from fpakman.view.qt import dialog
from fpakman.view.qt.systray import TrayIcon
@@ -68,19 +67,6 @@ if args.check_packaging_once == 1:
locale_keys = util.get_locale_keys(args.locale)
manager_classes = None
def _find_manager(member):
if inspect.isclass(member) and inspect.getmro(member)[1].__name__ == 'ApplicationManager':
return member
elif inspect.ismodule(member):
for name, mod in inspect.getmembers(member):
manager_found = _find_manager(mod)
if manager_found:
return manager_found
http_session = requests.Session()
caches, cache_map = [], {}
managers = None
@@ -94,9 +80,14 @@ for m in pkgutil.iter_modules():
if m.ispkg and m.name and m.name != 'fpakman_api' and m.name.startswith('fpakman_'):
module = pkgutil.find_loader(m.name).load_module()
manager = _find_manager(module)
manager = extensions.find_manager(module)
if manager:
locale_path = '{}/resources/locale'.format(module.__path__[0])
if os.path.exists(locale_path):
locale_keys.update(util.get_locale_keys(args.locale, locale_path))
if not managers:
managers = []
@@ -111,7 +102,7 @@ for m in pkgutil.iter_modules():
managers.append(man)
# if args.snap:
# if args.snap: TODO
# if args.disk_cache:
# Path(SNAP_CACHE_PATH).mkdir(parents=True, exist_ok=True)

View File

@@ -8,7 +8,6 @@ from fpakman_api.util.disk import DiskCacheLoaderFactory
from fpakman_api.util.system import FpakmanProcess
from fpakman import ROOT_DIR
from fpakman.util.cache import Cache
class GenericApplicationManager(ApplicationManager):

View File

@@ -0,0 +1,11 @@
import inspect
def find_manager(member):
if inspect.isclass(member) and inspect.getmro(member)[1].__name__ == 'ApplicationManager':
return member
elif inspect.ismodule(member):
for name, mod in inspect.getmembers(member):
manager_found = find_manager(mod)
if manager_found:
return manager_found

View File

@@ -1,182 +0,0 @@
import os
import shutil
from argparse import Namespace
from datetime import datetime
from typing import List, Dict
from fpakman.core import disk
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, FlatpakUpdateLoader
from fpakman.core.model import ApplicationData, ApplicationUpdate
from fpakman.core.system import FpakmanProcess
from fpakman.util.cache import Cache
class FlatpakManager(ApplicationManager):
def __init__(self, app_args: Namespace, api_cache: Cache, disk_cache: bool, http_session, locale_keys: dict):
super(FlatpakManager, self).__init__(app_args=app_args, locale_keys=locale_keys)
self.api_cache = api_cache
self.http_session = http_session
self.disk_cache = disk_cache
def get_app_type(self):
return FlatpakApplication
def _map_to_model(self, app_json: dict, installed: bool, disk_loader: DiskCacheLoader) -> FlatpakApplication:
app = FlatpakApplication(arch=app_json.get('arch'),
branch=app_json.get('branch'),
origin=app_json.get('origin'),
runtime=app_json.get('runtime'),
ref=app_json.get('ref'),
commit=app_json.get('commit'),
base_data=ApplicationData(id=app_json.get('id'),
name=app_json.get('name'),
version=app_json.get('version'),
latest_version=app_json.get('latest_version')))
app.installed = installed
api_data = self.api_cache.get(app_json['id'])
expired_data = api_data and api_data.get('expires_at') and api_data['expires_at'] <= datetime.utcnow()
if not api_data or expired_data:
if not app_json['runtime']:
disk_loader.add(app) # preloading cached disk data
FlatpakAsyncDataLoader(app=app, api_cache=self.api_cache, manager=self, http_session=self.http_session).start()
else:
app.fill_cached_data(api_data)
return app
def search(self, word: str, disk_loader: DiskCacheLoader) -> Dict[str, List[FlatpakApplication]]:
res = {'installed': [], 'new': []}
apps_found = flatpak.search(word)
if apps_found:
already_read = set()
installed_apps = self.read_installed(disk_loader=disk_loader)
if installed_apps:
for app_found in apps_found:
for installed_app in installed_apps:
if app_found['id'] == installed_app.base_data.id:
res['installed'].append(installed_app)
already_read.add(app_found['id'])
if len(apps_found) > len(already_read):
for app_found in apps_found:
if app_found['id'] not in already_read:
res['new'].append(self._map_to_model(app_found, False, disk_loader))
return res
def read_installed(self, disk_loader: DiskCacheLoader) -> List[FlatpakApplication]:
installed = flatpak.list_installed()
models = []
if installed:
available_updates = flatpak.list_updates_as_str()
for app_json in installed:
model = self._map_to_model(app_json=app_json, installed=True, disk_loader=disk_loader)
model.update = app_json['id'] in available_updates
models.append(model)
return models
def can_downgrade(self):
return True
def downgrade_app(self, app: FlatpakApplication, root_password: str) -> FpakmanProcess:
commits = flatpak.get_app_commits(app.ref, app.origin)
commit_idx = commits.index(app.commit)
# downgrade is not possible if the app current commit in the first one:
if commit_idx == len(commits) - 1:
return None
return FpakmanProcess(subproc=flatpak.downgrade_and_stream(app.ref, commits[commit_idx + 1], root_password),
success_phrase='Updates complete.')
def clean_cache_for(self, app: FlatpakApplication):
self.api_cache.delete(app.base_data.id)
if app.supports_disk_cache() and os.path.exists(app.get_disk_cache_path()):
shutil.rmtree(app.get_disk_cache_path())
def update_and_stream(self, app: FlatpakApplication) -> FpakmanProcess:
return FpakmanProcess(subproc=flatpak.update_and_stream(app.ref))
def uninstall_and_stream(self, app: FlatpakApplication, root_password: str = None) -> FpakmanProcess:
return FpakmanProcess(subproc=flatpak.uninstall_and_stream(app.ref))
def get_info(self, app: FlatpakApplication) -> dict:
app_info = flatpak.get_app_info_fields(app.base_data.id, app.branch)
app_info['name'] = app.base_data.name
app_info['type'] = 'runtime' if app.runtime else 'app'
app_info['description'] = app.base_data.description
return app_info
def get_history(self, app: FlatpakApplication) -> List[dict]:
return flatpak.get_app_commits_data(app.ref, app.origin)
def install_and_stream(self, app: FlatpakApplication, root_password: str) -> FpakmanProcess:
return FpakmanProcess(subproc=flatpak.install_and_stream(app.base_data.id, app.origin))
def is_enabled(self):
return flatpak.is_installed()
def cache_to_disk(self, app: FlatpakApplication, icon_bytes: bytes, only_icon: bool):
if self.disk_cache and app.supports_disk_cache():
disk.save(app, icon_bytes, only_icon)
def requires_root(self, action: str, app: FlatpakApplication):
return action == 'downgrade'
def refresh(self, app: FlatpakApplication, root_password: str) -> FpakmanProcess:
raise Exception("'refresh' is not supported for {}".format(app.__class__.__name__))
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
def list_warnings(self) -> List[str]:
return None

View File

@@ -1,221 +0,0 @@
import re
import subprocess
from typing import List, Set
from fpakman.core import system
from fpakman.core.exception import NoInternetException
BASE_CMD = 'flatpak'
def app_str_to_json(line: str, version: str, extra_fields: bool = True) -> dict:
app_array = line.split('\t')
if version >= '1.3.0':
app = {'name': app_array[0],
'id': app_array[1],
'version': app_array[2],
'branch': app_array[3]}
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 = {'id': app_array[1],
'name': app_array[1].strip().split('.')[-1],
'version': app_array[2],
'branch': app_array[3],
'arch': app_array[4],
'origin': app_array[5]}
else:
raise Exception('Unsupported version')
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
def get_app_info_fields(app_id: str, branch: str, fields: List[str] = [], check_runtime: bool = False):
info = re.findall(r'\w+:\s.+', get_app_info(app_id, branch))
data = {}
fields_to_retrieve = len(fields) + (1 if check_runtime and 'ref' not in fields else 0)
for field in info:
if fields and fields_to_retrieve == 0:
break
field_val = field.split(':')
field_name = field_val[0].lower()
if not fields or field_name in fields or (check_runtime and field_name == 'ref'):
data[field_name] = field_val[1].strip()
if fields:
fields_to_retrieve -= 1
if check_runtime and field_name == 'ref':
data['runtime'] = data['ref'].startswith('runtime/')
return data
def is_installed():
version = get_version()
return False if version is None else True
def get_version():
res = system.run_cmd('{} --version'.format(BASE_CMD), print_error=False)
return res.split(' ')[1].strip() if res else None
def get_app_info(app_id: str, branch: str):
return system.run_cmd('{} info {} {}'.format(BASE_CMD, app_id, branch))
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, extra_fields=extra_fields) for line in app_lines if line]
return []
def update_and_stream(app_ref: str):
"""
Updates the app reference and streams Flatpak output,
:param app_ref:
:return:
"""
return system.cmd_to_subprocess([BASE_CMD, 'update', '-y', app_ref])
def uninstall_and_stream(app_ref: str):
"""
Removes the app by its reference
:param app_ref:
:return:
"""
return system.cmd_to_subprocess([BASE_CMD, 'uninstall', app_ref, '-y'])
def list_updates_as_str():
return system.run_cmd('{} update'.format(BASE_CMD), ignore_return_code=True)
def downgrade_and_stream(app_ref: str, commit: str, root_password: str) -> subprocess.Popen:
return system.cmd_as_root([BASE_CMD, 'update', '--commit={}'.format(commit), app_ref, '-y'], root_password)
def get_app_commits(app_ref: str, origin: str) -> List[str]:
log = system.run_cmd('{} remote-info --log {} {}'.format(BASE_CMD, origin, app_ref))
if log:
return re.findall(r'Commit+:\s(.+)', log)
else:
raise NoInternetException()
def get_app_commits_data(app_ref: str, origin: str) -> List[dict]:
log = system.run_cmd('{} remote-info --log {} {}'.format(BASE_CMD, origin, app_ref))
if not log:
raise NoInternetException()
res = re.findall(r'(Commit|Subject|Date):\s(.+)', log)
commits = []
commit = {}
for idx, data in enumerate(res):
commit[data[0].strip().lower()] = data[1].strip()
if (idx + 1) % 3 == 0:
commits.append(commit)
commit = {}
return commits
def search(word: str) -> List[dict]:
cli_version = get_version()
res = system.run_cmd('{} search {}'.format(BASE_CMD, word))
found = []
split_res = res.split('\n')
if split_res and split_res[0].lower() != 'no matches found':
for info in split_res:
if info:
info_list = info.split('\t')
if cli_version >= '1.3.0':
version = info_list[3].strip()
found.append({
'name': info_list[0].strip(),
'description': info_list[1].strip(),
'id': info_list[2].strip(),
'version': version,
'latest_version': version,
'branch': info_list[4].strip(),
'origin': info_list[5].strip(),
'runtime': False,
'arch': None, # unknown at this moment,
'ref': None # unknown at this moment
})
elif cli_version >= '1.2.0':
desc = info_list[0].split('-')
version = info_list[2].strip()
found.append({
'name': desc[0].strip(),
'description': desc[1].strip(),
'id': info_list[1].strip(),
'version': version,
'latest_version': version,
'branch': info_list[3].strip(),
'origin': info_list[4].strip(),
'runtime': False,
'arch': None, # unknown at this moment,
'ref': None # unknown at this moment
})
else:
version = info_list[1].strip()
found.append({
'name': '',
'description': info_list[4].strip(),
'id': info_list[0].strip(),
'version': version,
'latest_version': version,
'branch': info_list[2].strip(),
'origin': info_list[3].strip(),
'runtime': False,
'arch': None, # unknown at this moment,
'ref': None # unknown at this moment
})
return found
def install_and_stream(app_id: str, origin: str):
return system.cmd_to_subprocess([BASE_CMD, 'install', origin, app_id, '-y'])
def set_default_remotes():
system.run_cmd('flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo')

View File

@@ -1,62 +0,0 @@
from fpakman.core import resource
from fpakman.core.flatpak.constants import FLATPAK_CACHE_PATH
from fpakman.core.model import Application, ApplicationData
class FlatpakApplication(Application):
def __init__(self, base_data: ApplicationData, branch: str, arch: str, origin: str, runtime: bool, ref: str, commit: str):
super(FlatpakApplication, self).__init__(base_data=base_data)
self.ref = ref
self.branch = branch
self.arch = arch
self.origin = origin
self.runtime = runtime
self.commit = commit
def is_incomplete(self):
return self.base_data.description is None and self.base_data.icon_url
def has_history(self):
return True
def has_info(self):
return self.installed
def can_be_downgraded(self):
return True
def can_be_uninstalled(self):
return True
def can_be_installed(self):
return True
def get_type(self):
return 'flatpak'
def can_be_refreshed(self):
return False
def get_default_icon_path(self):
return resource.get_path('img/flathub.svg')
def is_library(self):
return self.runtime
def get_disk_cache_path(self):
return '{}/{}'.format(FLATPAK_CACHE_PATH, self.base_data.id)
def get_data_to_cache(self):
return {
'description': self.base_data.description,
'icon_url': self.base_data.icon_url,
'latest_version': self.base_data.latest_version,
'version': self.base_data.version,
'name': self.base_data.name
}
def fill_cached_data(self, data: dict):
for attr in self.get_data_to_cache().keys():
if not getattr(self.base_data, attr):
setattr(self.base_data, attr, data[attr])

View File

@@ -1,117 +0,0 @@
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
from fpakman.core.worker import AsyncDataLoader
from fpakman.util.cache import Cache
class FlatpakAsyncDataLoader(AsyncDataLoader):
def __init__(self, app: FlatpakApplication, manager: ApplicationManager, http_session, api_cache: Cache, attempts: int = 2, timeout: int = 30):
super(FlatpakAsyncDataLoader, self).__init__(app=app)
self.manager = manager
self.http_session = http_session
self.attempts = attempts
self.api_cache = api_cache
self.persist = False
self.timeout = timeout
def run(self):
if self.app:
self.app.status = ApplicationStatus.LOADING_DATA
for _ in range(0, self.attempts):
try:
res = self.http_session.get('{}/apps/{}'.format(FLATHUB_API_URL, self.app.base_data.id), timeout=self.timeout)
if res.status_code == 200 and res.text:
data = res.json()
if not self.app.base_data.version:
self.app.base_data.version = data.get('version')
if not self.app.base_data.name:
self.app.base_data.name = data.get('name')
self.app.base_data.description = data.get('description', data.get('summary', None))
self.app.base_data.icon_url = data.get('iconMobileUrl', None)
self.app.base_data.latest_version = data.get('currentReleaseVersion', self.app.base_data.version)
if not self.app.base_data.version and self.app.base_data.latest_version:
self.app.base_data.version = self.app.base_data.latest_version
if self.app.base_data.icon_url and self.app.base_data.icon_url.startswith('/'):
self.app.base_data.icon_url = FLATHUB_URL + self.app.base_data.icon_url
loaded_data = self.app.get_data_to_cache()
self.api_cache.add(self.app.base_data.id, loaded_data)
self.app.status = ApplicationStatus.READY
self.persist = self.app.supports_disk_cache()
break
else:
self.log_msg("Could not retrieve app data for id '{}'. Server response: {}. Body: {}".format(
self.app.base_data.id, res.status_code, res.content.decode()), Fore.RED)
except:
self.log_msg("Could not retrieve app data for id '{}'".format(self.app.base_data.id), Fore.YELLOW)
traceback.print_exc()
time.sleep(0.5)
self.app.status = ApplicationStatus.READY
if self.persist:
self.manager.cache_to_disk(app=self.app, icon_bytes=None, only_icon=False)
def clone(self) -> "FlatpakAsyncDataLoader":
return FlatpakAsyncDataLoader(manager=self.manager,
api_cache=self.api_cache,
attempts=self.attempts,
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

@@ -67,14 +67,6 @@ flatpak.info.sdk=sdk
flatpak.info.subject=subject
flatpak.info.type=type
flatpak.info.version=version
snap.info.commands=commands
snap.info.contact=contact
snap.info.description=description
snap.info.license=license
snap.info.revision=revision
snap.info.tracking=tracking
snap.info.installed=installed
snap.info.publisher=publisher
about.info.desc=Non-official Flatpak / Snap application management graphical interface
about.info.link=More information at
about.info.license=Free license
@@ -100,5 +92,4 @@ version.latest=latest version
version.installed_outdated=the installed version is outdated
version.unknown=not informed
app.name=application name
warning=warning
snap.notification.snapd_unavailable=snapd seems not to be enabled. snap packages will not be available.
warning=warning

View File

@@ -68,14 +68,6 @@ flatpak.info.sdk=sdk
flatpak.info.subject=tema
flatpak.info.type=tipo
flatpak.info.version=versión
snap.info.commands=comandos
snap.info.contact=contacto
snap.info.description=descripción
snap.info.license=licencia
snap.info.revision=revisión
snap.info.tracking=tracking
snap.info.installed=instalado
snap.info.publisher=publicador
about.info.desc=Interfaz grafica no oficial para administración de aplicativos Flatpak / Snap
about.info.link=Mas informaciones en
about.info.license=Licencia gratuita
@@ -101,5 +93,4 @@ version.latest=versión más reciente
version.installed_outdated=la versión instalada está desactualizada
version.unknown=versión no informada
app.name=nombre del aplicativo
warning=aviso
snap.notification.snapd_unavailable=snapd no parece estar habilitado. los paquetes snap estarán indisponibles.
warning=aviso

View File

@@ -68,14 +68,6 @@ flatpak.info.sdk=sdk
flatpak.info.subject=assunto
flatpak.info.type=tipo
flatpak.info.version=versão
snap.info.commands=comandos
snap.info.contact=contato
snap.info.description=descrição
snap.info.license=licença
snap.info.revision=revisão
snap.info.tracking=tracking
snap.info.installed=instalado
snap.info.publisher=publicador
about.info.desc=Interface gráfica não oficial para gerenciamento de aplicativos Flatpak / Snap
about.info.link=Mais informações em
about.info.license=Licença gratuita
@@ -101,5 +93,4 @@ version.latest=versão mais recente
version.installed_outdated=a versão instalada está desatualizada
version.unknown=versão não informada
app.name=nome do aplicativo
warning=aviso
snap.notification.snapd_unavailable=snapd não parece estar habilitado. os pacotes snap estarão indisponíveis.
warning=aviso

View File

@@ -1,64 +0,0 @@
from datetime import datetime, timedelta
from threading import Lock
class Cache:
def __init__(self, expiration_time: int):
self.expiration_time = expiration_time
self._cache = {}
self.lock = Lock()
def is_enabled(self):
return self.expiration_time < 0 or self.expiration_time > 0
def add(self, key: str, val: object):
if key and self.is_enabled():
self.lock.acquire()
self._add(key, val)
self.lock.release()
def _add(self, key: str, val: object):
if key:
self._cache[key] = {'val': val, 'expires_at': datetime.utcnow() + timedelta(seconds=self.expiration_time) if self.expiration_time > 0 else None}
def add_non_existing(self, key: str, val: object):
if key and self. is_enabled():
self.lock.acquire()
cur_val = self.get(key)
if cur_val is None:
self._add(key, val)
self.lock.release()
def get(self, key: str):
if key and self.is_enabled():
val = self._cache.get(key)
if val:
expiration = val.get('expires_at')
if expiration and expiration <= datetime.utcnow():
self.lock.acquire()
del self._cache[key]
self.lock.release()
return None
return val['val']
def delete(self, key):
if key and self.is_enabled():
if key in self._cache:
self.lock.acquire()
del self._cache[key]
self.lock.release()
def keys(self):
return set(self._cache.keys()) if self.is_enabled() else set()
def clean_expired(self):
if self.is_enabled():
for key in self.keys():
self.get(key)

View File

@@ -2,7 +2,7 @@ import time
from threading import Thread
from typing import List
from fpakman.util.cache import Cache
from fpakman_api.util.cache import Cache
import gc

View File

@@ -7,7 +7,7 @@ import re
HTML_RE = re.compile(r'<[^>]+>')
def get_locale_keys(key: str = None):
def get_locale_keys(key: str = None, locale_dir: str = resource.get_path('locale')):
locale_path = None
@@ -19,8 +19,6 @@ def get_locale_keys(key: str = None):
if current_locale:
current_locale = current_locale[0]
locale_dir = resource.get_path('locale')
for locale_file in glob.glob(locale_dir + '/*'):
name = locale_file.split('/')[-1]

View File

@@ -10,7 +10,7 @@ from PyQt5.QtWidgets import QTableWidget, QTableView, QMenu, QAction, QTableWidg
from fpakman_api.abstract.model import ApplicationStatus
from fpakman.core import resource
from fpakman.util.cache import Cache
from fpakman_api.util.cache import Cache
from fpakman.view.qt import dialog
from fpakman.view.qt.view_model import ApplicationView, ApplicationViewStatus

View File

@@ -9,7 +9,7 @@ from fpakman_api.exception import NoInternetException
from fpakman_api.util.system import FpakmanProcess
from fpakman.core.controller import ApplicationManager
from fpakman.util.cache import Cache
from fpakman_api.util.cache import Cache
from fpakman.view.qt import dialog
from fpakman.view.qt.view_model import ApplicationView

View File

@@ -11,7 +11,7 @@ from fpakman_api.util import system
from fpakman.core import resource
from fpakman.core.controller import ApplicationManager
from fpakman.util.cache import Cache
from fpakman_api.util.cache import Cache
from fpakman.view.qt.apps_table import AppsTable
from fpakman.view.qt.history import HistoryDialog
from fpakman.view.qt.info import InfoDialog