screenshots panel improved

This commit is contained in:
Vinicius Moreira
2019-10-15 12:34:18 -03:00
parent 170155d9f6
commit 973440f433
10 changed files with 94 additions and 51 deletions

View File

@@ -7,7 +7,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [0.7.0]
### Features
- AppImage support ( see below )
- **Screenshots** button
- **Screenshots** button and panel
- **Categories** filter
### Improvements
@@ -29,8 +29,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### AppImage support
- Search, install, uninstall, downgrade, launch and retrieve the applications history
- Supported sources: [AppImageHub](https://appimage.github.io).
- Applications with no releases published to GitHub are not available
- Supported sources: [AppImageHub](https://appimage.github.io) ( **applications with no releases published to GitHub are currently not available** )
- Adds desktop entries ( menu shortcuts ) for the installed applications ( **~/.local/share/applications **)
## [0.6.4] 2019-10-13

View File

@@ -122,7 +122,7 @@ will be pre-downloaded faster ( it does **NOT** modify your **pacman** settings
### AppImage support ( appimage gem )
- The user is able to search, install, uninstall, downgrade, launch and retrieve the applications history
- Supported sources: [AppImageHub](https://appimage.github.io) ( **applications with no releases published to GitHub are not available yet** )
- Supported sources: [AppImageHub](https://appimage.github.io) ( **applications with no releases published to GitHub are currently not available** )
- Faster downloads if **aria2c** is installed. Same behavior described in the **AUR support** section.
- Installed applications are store at **~/.local/share/bauh/appimage/installed**
- Desktop entries ( menu shortcuts ) of the installed applications are stored at **~/.local/share/applications**

View File

@@ -72,6 +72,7 @@ def main():
config=user_config,
context=context,
http_client=http_client,
logger=logger,
notifications=bool(args.system_notifications))
if args.tray:

View File

@@ -130,6 +130,8 @@ class AppImageManager(SoftwareManager):
app.url_download_latest_version = tup[3]
break
except:
traceback.print_exc()
finally:
self._close_connection(DB_APPS_PATH, con)

View File

@@ -1,21 +1,32 @@
import logging
from threading import Thread
from typing import List
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QIcon, QPixmap
from PyQt5.QtWidgets import QDialog, QLabel, QGridLayout, QPushButton
from bauh.api.abstract.cache import MemoryCache
from bauh.api.http import HttpClient
from bauh.view.qt import qt_utils
from bauh.view.qt.view_model import PackageView
class ScreenshotsDialog(QDialog):
def __init__(self, pkg: PackageView, icon_cache: MemoryCache, i18n: dict, screenshots: List[QPixmap]):
MAX_HEIGHT = 600
MAX_WIDTH = 800
def __init__(self, pkg: PackageView, http_client: HttpClient, icon_cache: MemoryCache, i18n: dict, screenshots: List[QPixmap], logger: logging.Logger):
super(ScreenshotsDialog, self).__init__()
self.setWindowTitle(str(pkg))
self.screenshots = screenshots
self.logger = logger
self.loaded_imgs = []
self.download_threads = []
self.resize(1280, 720)
self.i18n = i18n
self.http_client = http_client
icon_data = icon_cache.get(pkg.model.icon_url)
@@ -36,30 +47,73 @@ class ScreenshotsDialog(QDialog):
self.img = QLabel()
self.layout().addWidget(self.img, 1, 1)
self.img_label = QLabel()
self.img_label.setStyleSheet('QLabel { font-weight: bold; text-align: center }')
self.layout().addWidget(self.img_label, 2, 1)
self.img_idx = 0
for idx, s in enumerate(self.screenshots):
t = Thread(target=self._download_img, args=(idx, s))
t.start()
self.idx = 0
self._load_img()
def _load_img(self):
pixmap = self.screenshots[self.idx]
self.img.setPixmap(pixmap)
if len(self.loaded_imgs) > self.img_idx:
img = self.loaded_imgs[self.img_idx]
if isinstance(img, QPixmap):
self.img_label.setText('')
self.img.setPixmap(img)
else:
self.img_label.setText(img)
self.img.setPixmap(QPixmap())
else:
self.img.setPixmap(QPixmap())
self.img_label.setText('...{}...'.format(self.i18n['screenshots,download.running']))
if len(self.screenshots) == 1:
self.bt_back.setVisible(False)
self.bt_next.setVisible(False)
else:
self.bt_back.setVisible(self.idx != 0)
self.bt_next.setVisible(self.idx != len(self.screenshots) - 1)
self.bt_back.setEnabled(self.img_idx != 0)
self.bt_next.setEnabled(self.img_idx != len(self.screenshots) - 1)
self.adjustSize()
qt_utils.centralize(self)
def _download_img(self, idx: int, url: str):
self.logger.info('Downloading image [{}] from {}'.format(idx, url))
res = self.http_client.get(url)
if res:
if not res.content:
self.logger.warning("Image [{}] from {} has no content".format(idx, url))
self.screenshots.append(self.i18n['screenshots.download.no_content'])
return
else:
self.logger.info('Image [{}] successfully downloaded'.format(idx))
pixmap = QPixmap()
pixmap.loadFromData(res.content)
if pixmap.size().height() > self.MAX_HEIGHT or pixmap.size().width() > self.MAX_WIDTH:
pixmap = pixmap.scaled(self.MAX_WIDTH, self.MAX_HEIGHT, Qt.KeepAspectRatio, Qt.SmoothTransformation)
self.loaded_imgs.append(pixmap)
if self.img_idx == idx:
self._load_img()
else:
self.logger.info("Could not retrieve image [{}] from {}".format(idx, url))
self.screenshots.append(self.i18n['screenshots.download.no_response'])
def back(self):
self.idx -= 1
self.img_idx -= 1
self._load_img()
def next(self):
self.idx += 1
self.img_idx += 1
self._load_img()

View File

@@ -1,12 +1,10 @@
import re
import time
from datetime import datetime, timedelta
from threading import Thread
from typing import List, Type, Set
import requests
from PyQt5.QtCore import QThread, pyqtSignal, Qt
from PyQt5.QtGui import QPixmap
from PyQt5.QtCore import QThread, pyqtSignal
from bauh.api.abstract.cache import MemoryCache
from bauh.api.abstract.controller import SoftwareManager
@@ -486,42 +484,14 @@ class CustomAction(AsyncAction):
class GetScreenshots(AsyncAction):
MAX_HEIGHT = 600
MAX_WIDTH = 800
def __init__(self, manager: SoftwareManager, http_client: HttpClient, pkg: PackageView = None):
def __init__(self, manager: SoftwareManager, pkg: PackageView = None):
super(GetScreenshots, self).__init__()
self.pkg = pkg
self.manager = manager
self.http_client = http_client
def _get_img(self, url: str, imgs: list):
res = self.http_client.get(url)
if res and res.status_code == 200 and res.content:
pixmap = QPixmap()
pixmap.loadFromData(res.content)
if pixmap.size().height() > self.MAX_HEIGHT or pixmap.size().width() > self.MAX_WIDTH:
pixmap = pixmap.scaled(self.MAX_WIDTH, self.MAX_HEIGHT, Qt.KeepAspectRatio, Qt.SmoothTransformation)
imgs.append(pixmap)
def run(self):
if self.pkg:
imgs = []
screenshots = self.manager.get_screenshots(self.pkg.model)
if screenshots:
threads = []
for url in screenshots:
t = Thread(target=self._get_img, args=(url, imgs))
t.start()
threads.append(t)
for t in threads:
t.join()
self.notify_finished({'pkg': self.pkg, 'screenshots': imgs})
self.notify_finished({'pkg': self.pkg, 'screenshots': self.manager.get_screenshots(self.pkg.model)})
self.pkg = None

View File

@@ -1,3 +1,4 @@
import logging
import operator
import time
from functools import reduce
@@ -51,9 +52,11 @@ class ManageWindow(QWidget):
def __init__(self, i18n: dict, icon_cache: MemoryCache, manager: SoftwareManager, disk_cache: bool,
download_icons: bool, screen_size, suggestions: bool, display_limit: int, config: Configuration,
context: ApplicationContext, notifications: bool, http_client: HttpClient, tray_icon=None):
context: ApplicationContext, notifications: bool, http_client: HttpClient, logger: logging.Logger,
tray_icon=None):
super(ManageWindow, self).__init__()
self.i18n = i18n
self.logger = logger
self.manager = manager
self.tray_icon = tray_icon
self.working = False # restrict the number of threaded actions
@@ -227,7 +230,7 @@ class ManageWindow(QWidget):
self.thread_suggestions = self._bind_async_action(FindSuggestions(man=self.manager), finished_call=self._finish_search, only_finished=True)
self.thread_run_app = self._bind_async_action(LaunchApp(self.manager), finished_call=self._finish_run_app, only_finished=False)
self.thread_custom_action = self._bind_async_action(CustomAction(manager=self.manager), finished_call=self._finish_custom_action)
self.thread_screenshots = self._bind_async_action(GetScreenshots(self.manager, http_client), finished_call=self._finish_get_screenshots)
self.thread_screenshots = self._bind_async_action(GetScreenshots(self.manager), finished_call=self._finish_get_screenshots)
self.thread_apply_filters = ApplyFilters()
self.thread_apply_filters.signal_finished.connect(self._finish_apply_filters_async)
@@ -868,7 +871,12 @@ class ManageWindow(QWidget):
self.finish_action()
if res.get('screenshots'):
diag = ScreenshotsDialog(pkg=res['pkg'], icon_cache=self.icon_cache, i18n=self.i18n, screenshots=res['screenshots'])
diag = ScreenshotsDialog(pkg=res['pkg'],
http_client=self.http_client,
icon_cache=self.icon_cache,
logger=self.logger,
i18n=self.i18n,
screenshots=res['screenshots'])
diag.exec_()
else:
dialog.show_message(title=self.i18n['error'],

View File

@@ -133,4 +133,7 @@ screenshots.bt_next.label=next
screenshots.bt_back.label=previous
instantmessaging=messaging
2dgraphics=2d graphics
vectorgraphics=vector graphics
vectorgraphics=vector graphics
screenshots,download.running=downloading image
screenshots.download.no_content=No content to display
screenshots.download.no_response=Image not found

View File

@@ -170,4 +170,7 @@ screenshots.bt_next.label=próxima
screenshots.bt_back.label=anterior
instantmessaging=mensajens
2dgraphics=gŕaficos 2d
vectorgraphics=gráficos vectoriales
vectorgraphics=gráficos vectoriales
screenshots,download.running=descargando imagen
screenshots.download.no_content=No hay contenido para mostrar
screenshots.download.no_response=Imagen no encontrada

View File

@@ -172,4 +172,7 @@ screenshots.bt_next.label=próxima
screenshots.bt_back.label=anterior
instantmessaging=mensagens
2dgraphics=gŕaficos 2d
vectorgraphics=gráficos vetoriais
vectorgraphics=gráficos vetoriais
screenshots,download.running=baixando imagem
screenshots.download.no_content=Sem conteúdo para exibir
screenshots.download.no_response=Imagem não encontrada