From e09aec5d34f78c4aa4b40293c92bcc2cece8fe96 Mon Sep 17 00:00:00 2001 From: Bastian Germann Date: Mon, 28 Sep 2020 21:47:35 +0200 Subject: [PATCH 1/4] test_pdfcontroller: Get rid of platform specifics As system() called PDF controllers are removed, test_pdfcontroller can be simplified because PyMuPDF will use the mocked screen. Get rid of the platform-dependent screen size obtaining which gets rid of the Xlib dependency. --- scripts/check_dependencies.py | 1 - setup.py | 1 - .../presentations/test_pdfcontroller.py | 50 +++---------------- 3 files changed, 8 insertions(+), 44 deletions(-) diff --git a/scripts/check_dependencies.py b/scripts/check_dependencies.py index e265629a7..1dd5b3131 100755 --- a/scripts/check_dependencies.py +++ b/scripts/check_dependencies.py @@ -58,7 +58,6 @@ LINUX_MODULES = [ # Optical drive detection. 'dbus', 'distro', - 'Xlib', ] MACOSX_MODULES = [ diff --git a/setup.py b/setup.py index 223f2472f..bc433d883 100644 --- a/setup.py +++ b/setup.py @@ -138,7 +138,6 @@ using a computer and a data projector.""", 'pysword', 'pytest', 'pytest-qt', - 'python-xlib; platform_system=="Linux"', 'flake8', ] }, diff --git a/tests/functional/openlp_plugins/presentations/test_pdfcontroller.py b/tests/functional/openlp_plugins/presentations/test_pdfcontroller.py index bf84b5751..6cc7f9caa 100644 --- a/tests/functional/openlp_plugins/presentations/test_pdfcontroller.py +++ b/tests/functional/openlp_plugins/presentations/test_pdfcontroller.py @@ -26,12 +26,10 @@ import pytest from pathlib import Path from shutil import rmtree from tempfile import mkdtemp -from unittest import skipIf from unittest.mock import MagicMock from PyQt5 import QtCore, QtGui -from openlp.core.common import is_macosx, is_linux, is_win from openlp.core.display.screens import ScreenList from openlp.plugins.presentations.lib.pdfcontroller import PdfController, PdfDocument from tests.utils.constants import RESOURCE_PATH @@ -47,41 +45,11 @@ def pdf_env(settings, mock_plugin, mocked_qapp): mocked_qapp.primaryScreen = MagicMock() mocked_qapp.primaryScreen.return_value = mocked_screen ScreenList.create(mocked_qapp) - yield settings, mock_plugin, temp_folder_path, thumbnail_folder_path + yield mock_plugin, temp_folder_path, thumbnail_folder_path rmtree(thumbnail_folder_path) rmtree(temp_folder_path) -SCREEN = { - 'primary': False, - 'number': 1, - 'size': QtCore.QRect(0, 0, 1024, 768) -} -IS_CI = 'GITLAB_CI' in os.environ or 'APPVEYOR' in os.environ -IS_QT_QPA_PLATFORM_OFFSCREEN = 'QT_QPA_PLATFORM' in os.environ and os.environ['QT_QPA_PLATFORM'] == 'offscreen' - - -def get_screen_resolution(): - """ - Get the screen resolution - """ - if is_macosx(): - # Magic numbers... don't ask me why - return 1024, 768 - elif is_win(): - from win32api import GetSystemMetrics - return GetSystemMetrics(0), GetSystemMetrics(1) - elif is_linux(): - if IS_CI: - return 1024, 768 - else: - from Xlib.display import Display - resolution = Display().screen().root.get_geometry() - return resolution.width, resolution.height - else: - return 1024, 768 - - def test_constructor(settings, mock_plugin): """ Test the Constructor from the PdfController @@ -104,9 +72,9 @@ def load_pdf(pdf_env): test_file_path = RESOURCE_PATH / 'presentations' / 'pdf_test1.pdf' # WHEN: The Pdf is loaded - mock_plugin = pdf_env[1] - temp_folder_path = pdf_env[2] - thumbnail_folder_path = pdf_env[3] + mock_plugin = pdf_env[0] + temp_folder_path = pdf_env[1] + thumbnail_folder_path = pdf_env[2] controller = PdfController(plugin=mock_plugin) controller.temp_folder = temp_folder_path controller.thumbnail_folder = thumbnail_folder_path @@ -118,7 +86,6 @@ def load_pdf(pdf_env): assert 3 == document.get_slide_count(), 'The pagecount of the PDF should be 3.' -@skipIf(IS_QT_QPA_PLATFORM_OFFSCREEN, 'This test fails when QT_QPA_PLATFORM is set to "offscreen".') def load_pdf_pictures(pdf_env): """ Test loading a Pdf and check the generated pictures' size @@ -127,9 +94,9 @@ def load_pdf_pictures(pdf_env): test_file_path = RESOURCE_PATH / 'presentations' / 'pdf_test1.pdf' # WHEN: The Pdf is loaded - mock_plugin = pdf_env[1] - temp_folder_path = pdf_env[2] - thumbnail_folder_path = pdf_env[3] + mock_plugin = pdf_env[0] + temp_folder_path = pdf_env[1] + thumbnail_folder_path = pdf_env[2] controller = PdfController(plugin=mock_plugin) controller.temp_folder = temp_folder_path controller.thumbnail_folder = thumbnail_folder_path @@ -139,9 +106,8 @@ def load_pdf_pictures(pdf_env): # THEN: The load should succeed and pictures should be created and have been scaled to fit the screen assert loaded is True, 'The loading of the PDF should succeed.' image = QtGui.QImage(os.path.join(str(temp_folder_path), 'pdf_test1.pdf', 'mainslide001.png')) - # Based on the converter used the resolution will differ a bit - width, height = get_screen_resolution() # Calculate the width of the PDF based on the aspect ratio of the PDF + height = 768 width = int(round(height * 0.70703125, 0)) assert image.height() == height, 'The height should be {height}'.format(height=height) assert image.width() == width, 'The width should be {width}'.format(width=width) From 2caf9c0f94503e778a9dc14913a401e4262e01cf Mon Sep 17 00:00:00 2001 From: Bastian Germann Date: Mon, 28 Sep 2020 22:03:37 +0200 Subject: [PATCH 2/4] Install latest PyMuPDF --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index c33b15d24..c19ab1b15 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -30,7 +30,7 @@ install: # Update pip - python -m pip install --upgrade pip # Install generic dependencies from pypi - - python -m pip install sqlalchemy alembic appdirs chardet beautifulsoup4 lxml Mako mysql-connector-python pytest mock psycopg2-binary websockets asyncio waitress six webob requests QtAwesome PyQt5 PyQtWebEngine pymediainfo PyMuPDF==1.16.7 QDarkStyle python-vlc Pyro4 zeroconf flask-cors pytest-qt pyenchant pysword + - python -m pip install sqlalchemy alembic appdirs chardet beautifulsoup4 lxml Mako mysql-connector-python pytest mock psycopg2-binary websockets asyncio waitress six webob requests QtAwesome PyQt5 PyQtWebEngine pymediainfo PyMuPDF QDarkStyle python-vlc Pyro4 zeroconf flask-cors pytest-qt pyenchant pysword # Install Windows only dependencies - cmd: python -m pip install pyodbc pypiwin32 # Mac only dependencies From 04e3ef5d8644ecc5f16673de588cd24906cc28ee Mon Sep 17 00:00:00 2001 From: Bastian Germann Date: Mon, 28 Sep 2020 22:13:38 +0200 Subject: [PATCH 3/4] Clean pdfcontroller from mupdf/ghostscript --- .../presentations/lib/pdfcontroller.py | 31 ++----------------- 1 file changed, 3 insertions(+), 28 deletions(-) diff --git a/openlp/plugins/presentations/lib/pdfcontroller.py b/openlp/plugins/presentations/lib/pdfcontroller.py index 87086e16f..f9a76daa6 100644 --- a/openlp/plugins/presentations/lib/pdfcontroller.py +++ b/openlp/plugins/presentations/lib/pdfcontroller.py @@ -20,14 +20,10 @@ ########################################################################## import logging -from openlp.core.common import is_win from openlp.core.display.screens import ScreenList from openlp.plugins.presentations.lib.presentationcontroller import PresentationController, PresentationDocument -if is_win(): - from subprocess import STARTUPINFO, STARTF_USESHOWWINDOW - try: import fitz PYMUPDF_AVAILABLE = True @@ -55,31 +51,16 @@ class PdfController(PresentationController): super(PdfController, self).__init__(plugin, 'Pdf', PdfDocument) self.process = None self.supports = ['pdf'] - self.also_supports = [] - # Determine whether mudraw or ghostscript is used - self.check_installed() + self.also_supports = ['xps', 'oxps', 'epub', 'cbz', 'fb2'] def check_available(self): """ PdfController is able to run on this machine. - :return: True if program to open PDF-files was found, otherwise False. + :return: True if PyMuPDF is installed, otherwise False. """ log.debug('check_available Pdf') - return self.check_installed() - - def check_installed(self): - """ - Check the viewer is installed. - - :return: True if program to open PDF-files was found, otherwise False. - """ - log.debug('check_installed Pdf') - self.also_supports = [] - if PYMUPDF_AVAILABLE: - self.also_supports = ['xps', 'oxps', 'epub', 'cbz', 'fb2'] - return True - return False + return PYMUPDF_AVAILABLE def kill(self): """ @@ -111,12 +92,6 @@ class PdfDocument(PresentationDocument): self.hidden = False self.image_files = [] self.num_pages = -1 - # Setup startupinfo options for check_output to avoid console popping up on windows - if is_win(): - self.startupinfo = STARTUPINFO() - self.startupinfo.dwFlags |= STARTF_USESHOWWINDOW - else: - self.startupinfo = None def load_presentation(self): """ From 2c577e23823dcd8057687ee73a8b393a129c6d2d Mon Sep 17 00:00:00 2001 From: Bastian Germann Date: Mon, 28 Sep 2020 22:38:22 +0200 Subject: [PATCH 4/4] Remove unused check_binary_exists --- openlp/core/common/__init__.py | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/openlp/core/common/__init__.py b/openlp/core/common/__init__.py index 6039639ad..25a10ae3e 100644 --- a/openlp/core/common/__init__.py +++ b/openlp/core/common/__init__.py @@ -31,7 +31,6 @@ import sys import traceback from ipaddress import IPv4Address, IPv6Address, AddressValueError from shutil import which -from subprocess import check_output, CalledProcessError, STDOUT from PyQt5 import QtGui from PyQt5.QtCore import QCryptographicHash as QHash @@ -472,33 +471,6 @@ def clean_filename(filename): return INVALID_FILE_CHARS.sub('_', CONTROL_CHARS.sub('', filename)) -def check_binary_exists(program_path): - """ - Function that checks whether a binary exists. - - :param pathlib.Path program_path: The full path to the binary to check. - :return: program output to be parsed - :rtype: bytes - """ - log.debug('testing program_path: {text}'.format(text=program_path)) - try: - # Setup startupinfo options for check_output to avoid console popping up on windows - if is_win(): - from subprocess import STARTUPINFO, STARTF_USESHOWWINDOW - startupinfo = STARTUPINFO() - startupinfo.dwFlags |= STARTF_USESHOWWINDOW - else: - startupinfo = None - run_log = check_output([str(program_path), '--help'], stderr=STDOUT, startupinfo=startupinfo) - except CalledProcessError as e: - run_log = e.output - except Exception: - trace_error_handler(log) - run_log = '' - log.debug('check_output returned: {text}'.format(text=run_log)) - return run_log - - def get_file_encoding(file_path): """ Utility function to incrementally detect the file encoding.