mirror of
https://github.com/spalencsar/bearhub.git
synced 2026-07-07 01:14:15 +02:00
gem selector sketch
This commit is contained in:
214
bauh/api/abstract/controller.py
Normal file
214
bauh/api/abstract/controller.py
Normal file
@@ -0,0 +1,214 @@
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
from abc import ABC, abstractmethod
|
||||
from pathlib import Path
|
||||
from typing import List, Set, Type
|
||||
|
||||
from bauh.api.abstract.context import ApplicationContext
|
||||
from bauh.api.abstract.disk import DiskCacheLoader
|
||||
from bauh.api.abstract.handler import ProcessWatcher
|
||||
from bauh.api.abstract.model import SoftwarePackage, PackageUpdate, PackageHistory, PackageSuggestion, PackageAction
|
||||
|
||||
|
||||
class SearchResult:
|
||||
|
||||
def __init__(self, installed: List[SoftwarePackage], new: List[SoftwarePackage], total: int):
|
||||
"""
|
||||
:param installed: already installed packages
|
||||
:param new: new packages found
|
||||
:param total: total number of applications actually found
|
||||
"""
|
||||
self.installed = installed
|
||||
self.new = new
|
||||
self.total = total
|
||||
|
||||
|
||||
class SoftwareManager(ABC):
|
||||
|
||||
"""
|
||||
Base controller class that will be called by the graphical interface to execute operations.
|
||||
"""
|
||||
|
||||
def __init__(self, context: ApplicationContext):
|
||||
"""
|
||||
:param context:
|
||||
"""
|
||||
self.context = context
|
||||
|
||||
@abstractmethod
|
||||
def search(self, words: str, disk_loader: DiskCacheLoader, limit: int) -> SearchResult:
|
||||
"""
|
||||
:param words: the words typed by the user
|
||||
:param disk_loader: a running disk loader thread that loads package data from the disk asynchronously
|
||||
:param limit: the max number of packages to be retrieved. <= 1 should retrieve everything
|
||||
:return:
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def read_installed(self, disk_loader: DiskCacheLoader, limit: int, only_apps: bool, pkg_types: Set[Type[SoftwarePackage]]) -> SearchResult:
|
||||
"""
|
||||
:param disk_loader: a running disk loader thread that loads application data from the disk asynchronously
|
||||
:param limit: the max number of packages to be retrieved. <= 1 should retrieve everything
|
||||
:param only_apps: if only application packages should be retrieved
|
||||
:param pkg_types: use 'None' to bring any or specify some
|
||||
:return:
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def downgrade(self, pkg: SoftwarePackage, root_password: str, handler: ProcessWatcher) -> bool:
|
||||
"""
|
||||
downgrades a package version
|
||||
:param pkg:
|
||||
:param root_password: the root user password (if required)
|
||||
:param handler: a subprocess handler
|
||||
:return:
|
||||
"""
|
||||
pass
|
||||
|
||||
def clean_cache_for(self, pkg: SoftwarePackage):
|
||||
"""
|
||||
Cleans cached package cached data. This default implementation only cleans the cached data from the heard disk
|
||||
:param pkg:
|
||||
:return:
|
||||
"""
|
||||
if pkg.supports_disk_cache() and os.path.exists(pkg.get_disk_cache_path()):
|
||||
shutil.rmtree(pkg.get_disk_cache_path())
|
||||
|
||||
@abstractmethod
|
||||
def update(self, pkg: SoftwarePackage, root_password: str, watcher: ProcessWatcher) -> bool:
|
||||
"""
|
||||
:param pkg:
|
||||
:param root_password: the root user password (if required)
|
||||
:param watcher:
|
||||
:return:
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def uninstall(self, pkg: SoftwarePackage, root_password: str, watcher: ProcessWatcher) -> bool:
|
||||
"""
|
||||
:param pkg:
|
||||
:param root_password: the root user password (if required)
|
||||
:param watcher:
|
||||
:return: if the uninstall succeeded
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def get_managed_types(self) -> Set[Type[SoftwarePackage]]:
|
||||
"""
|
||||
:return: the managed package class type
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def get_info(self, pkg: SoftwarePackage) -> dict:
|
||||
"""
|
||||
retrieve the package information
|
||||
:param pkg:
|
||||
:return: a dictionary with the attributes to be shown
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def get_history(self, pkg: SoftwarePackage) -> PackageHistory:
|
||||
"""
|
||||
:param pkg:
|
||||
:return:
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def install(self, pkg: SoftwarePackage, root_password: str, watcher: ProcessWatcher) -> bool:
|
||||
"""
|
||||
:param pkg:
|
||||
:param root_password: the root user password (if required)
|
||||
:param watcher:
|
||||
:return: if the installation succeeded
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def is_enabled(self) -> bool:
|
||||
"""
|
||||
:return: if the instance is available to perform actions
|
||||
"""
|
||||
pass
|
||||
|
||||
def cache_to_disk(self, pkg: SoftwarePackage, icon_bytes: bytes, only_icon: bool):
|
||||
"""
|
||||
Saves the package data to the hard disk.
|
||||
:param pkg:
|
||||
:param icon_bytes:
|
||||
:param only_icon: if only the icon should be saved
|
||||
:return:
|
||||
"""
|
||||
if pkg.supports_disk_cache():
|
||||
|
||||
if not only_icon:
|
||||
Path(pkg.get_disk_cache_path()).mkdir(parents=True, exist_ok=True)
|
||||
data = pkg.get_data_to_cache()
|
||||
|
||||
if data:
|
||||
with open(pkg.get_disk_data_path(), 'w+') as f:
|
||||
f.write(json.dumps(data))
|
||||
|
||||
if icon_bytes:
|
||||
Path(pkg.get_disk_cache_path()).mkdir(parents=True, exist_ok=True)
|
||||
|
||||
with open(pkg.get_disk_icon_path(), 'wb+') as f:
|
||||
f.write(icon_bytes)
|
||||
|
||||
@abstractmethod
|
||||
def requires_root(self, action: str, pkg: SoftwarePackage):
|
||||
"""
|
||||
if a given action requires root privileges to be executed. Current actions are: 'install', 'uninstall', 'downgrade', 'search', 'refresh'
|
||||
:param action:
|
||||
:param pkg:
|
||||
:return:
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def prepare(self):
|
||||
"""
|
||||
It prepares the manager to start working. It will be called by GUI. Do not call it within.
|
||||
:return:
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def list_updates(self) -> List[PackageUpdate]:
|
||||
"""
|
||||
:return: available package updates
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def list_warnings(self) -> List[str]:
|
||||
"""
|
||||
:return: a list of warnings to be shown to the user
|
||||
"""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def list_suggestions(self, limit: int) -> List[PackageSuggestion]:
|
||||
"""
|
||||
:param limit: max suggestions to be returned. If limit < 0, it should not be considered
|
||||
:return: a list of package suggestions
|
||||
"""
|
||||
pass
|
||||
|
||||
def execute_custom_action(self, action: PackageAction, pkg: SoftwarePackage, root_password: str, watcher: ProcessWatcher) -> bool:
|
||||
"""
|
||||
At the moment the GUI implements this action. No need to implement it yourself.
|
||||
:param action:
|
||||
:param pkg:
|
||||
:param root_password:
|
||||
:param watcher:
|
||||
:return: if the action resulted in success
|
||||
"""
|
||||
pass
|
||||
Reference in New Issue
Block a user