Skip to content

Commit

Permalink
Merge python3/QT5 working branch (#165)
Browse files Browse the repository at this point in the history
  • Loading branch information
ndevenish committed Apr 14, 2021
2 parents 49d4923 + ba43a76 commit c188774
Show file tree
Hide file tree
Showing 29 changed files with 1,128 additions and 1,466 deletions.
12 changes: 12 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Configure flake8 with some defaults to reduce noise

[flake8]
# Black disagrees with flake8 on a few points. Ignore those.

ignore = E203, E266, E501, W503
# E203 whitespace before ':'
# E266 too many leading '#' for block comment
# E501 line too long
# W503 line break before binary operator

max-line-length = 88
2 changes: 2 additions & 0 deletions .isort.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[settings]
profile=black
12 changes: 7 additions & 5 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
repos:
- repo: https://github.com/ambv/black
rev: stable
- repo: https://github.com/PyCQA/isort.git
rev: 5.5.1
hooks:
- id: isort
- repo: https://github.com/psf/black
rev: 20.8b1
hooks:
- id: black
language_version: python3
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.0.0 # Use the ref you want to point at
rev: v2.0.0
hooks:
- id: flake8
- id: debug-statements
- id: check-ast
language_version: python3
27 changes: 22 additions & 5 deletions conftest.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""pytest configuration file"""

import os

import pytest

from dui.qt import QApplication, QPixmap, QStyleFactory
Expand All @@ -22,6 +23,10 @@ def pytest_collection_modifyitems(config, items):
item.add_marker(skip_gui)


def pytest_configure(config):
config.addinivalue_line("markers", "gui: Mark as a GUI test")


@pytest.fixture(params=list(QStyleFactory.keys()))
def qtstyles(request, qtbot):
"Runs tests with every different available style"
Expand All @@ -30,7 +35,13 @@ def qtstyles(request, qtbot):


@pytest.fixture
def screenshots(qtbot, request):
def qapp(qapp):
qapp.setStyle("Fusion")
return qapp


@pytest.fixture
def screenshots(qapp, qtbot, request):
"""Fixture to simplify making screenshots"""

# Find the repo root
Expand All @@ -40,7 +51,7 @@ def screenshots(qtbot, request):
if not os.path.isdir(ss_dir):
os.mkdir(ss_dir)

class SSSaver(object):
class SSSaver:
"""Returnable object to save test-context screenshots"""

def __init__(self, root_path):
Expand All @@ -52,7 +63,7 @@ def _filename(self):
test_file_name = os.path.splitext(
os.path.basename(request.node.parent.name)
)[0]
return "{}__{}_{}.png".format(test_file_name, request.node.name, self.count)
return f"{test_file_name}__{request.node.name}_{self.count}.png"

def saveWidget(self, widget, filename=None):
"""Save a widget screenshot."""
Expand All @@ -74,8 +85,14 @@ def saveWindow(self, window, filename=None):
window.raise_()
qtbot.waitForWindowShown(window)

desktop = QPixmap.grabWindow(QApplication.desktop().winId())
crop = desktop.copy(window.frameGeometry())
screen = qapp.primaryScreen()
geom = window.frameGeometry()
winid = QApplication.desktop().winId()
desktop = screen.grabWindow(
winid, geom.x(), geom.y(), geom.width(), geom.height()
)

crop = desktop
crop.save(full_path)

self.count += 1
Expand Down
10 changes: 6 additions & 4 deletions dui_app/write_setpath.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
from __future__ import print_function
import logging
import sys

logger = logging.getLogger(__name__)


def write_script(self_path):

logger.info("writing setpath.sh")
logger.info()

logger.info("self_path =", self_path)
logger.info(f"self_path = {self_path}")

py_gui_path = self_path[0:-8]
logger.info("py_gui_path =", py_gui_path)
logger.info(f"py_gui_path = {py_gui_path}")

lst_lin = []
lst_lin.append("# autogenerated setpath script\n")
Expand Down Expand Up @@ -49,4 +51,4 @@ def write_script(self_path):
else:
logger.info("no path to connect provided")

logger.info("setpath.sh generated with the path: ", self_path)
logger.info(f"setpath.sh generated with the path: {self_path}")
74 changes: 66 additions & 8 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,69 @@
from setuptools import setup
import os
import pathlib
import subprocess
import sys

from setuptools import Command, setup


def _read_version() -> str:
"""Read the DUI version out of a version file in the package"""
_ver_file = pathlib.Path(__file__).parent / "src" / "dui" / "_version.py"
_ver_locals = {}
exec(_ver_file.read_bytes(), _ver_locals)
return _ver_locals["__version__"]


DUI_VERSION = _read_version()


# Based off https://gist.github.com/ivanalejandro0/6758741
class BuildQt(Command):
"""Command for setup.py to build QT ui and resource files"""

# Source folders to search recursively
_UI_PATH = pathlib.Path("src") / "dui" / "resources"
_QRC_PATH = pathlib.Path("src") / "dui" / "resources"

user_options = [
("pyrcc=", None, "pyrcc command executable"),
("pyuic=", None, "pyuic command executable"),
]

def initialize_options(self):
self.pyrcc = "pyside2-rcc"
self.pyuic = "pyside2-uic"

def finalize_options(self):
pass

def _compile_ui(self, infile: pathlib.Path, outfile: pathlib.Path):
try:
subprocess.call([self.pyuic, str(infile), "-x", "-o", str(outfile)])
except OSError:
sys.exit(
f"uic command failed - make sure that {self.pyuic} is in your $PATH"
)

def _compile_rcc(self, infile: pathlib.Path, outfile: pathlib.Path):
try:
subprocess.call([self.pyrcc, str(infile), "-o", str(outfile)])
except OSError:
sys.exit(
f"rcc command failed - make sure that {self.pyrcc} is in your $PATH"
)

def run(self):
# Compile .ui files
for infile in self._UI_PATH.glob("**/*.ui"):
outfile = infile.parent / f"ui_{infile.stem}.py"
print(f"Compiling: {infile} -> {outfile}")
self._compile_ui(infile, outfile)
# Compile .qrc files
for infile in self._QRC_PATH.glob("**/*.qrc"):
outfile = infile.parent / f"rc_{infile.stem}.py"
print(f"Compiling: {infile} -> {outfile}")
self._compile_rcc(infile, outfile)

# Read the DUI version out of a version file in the package
_ver_file = os.path.join(os.path.dirname(__file__), "src", "dui", "_version.py")
_ver_locals = {}
exec(open(_ver_file).read(), _ver_locals)
DUI_VERSION = _ver_locals["__version__"]

setup(
name="dui",
Expand Down Expand Up @@ -57,12 +115,12 @@
"src/dui/resources/next_img.png",
"src/dui/resources/ffw_img.png",
"src/dui/resources/last_img.png",

],
)
],
include_package_data=True,
entry_points={"console_scripts": ["dui=dui.main_dui:main"]},
cmdclass={"build_qt": BuildQt},
)

# TODO(nick): Work out how to get requirements working, including non-pip like PyQT
Expand Down
5 changes: 2 additions & 3 deletions src/dui/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
copyright (c) CCP4 - DLS
"""

from __future__ import absolute_import, division, print_function

from ._version import __version__ # noqa F401

# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
Expand All @@ -23,5 +24,3 @@
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

from ._version import __version__ # noqa F401
53 changes: 22 additions & 31 deletions src/dui/cli_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@
copyright (c) CCP4 - DLS
"""
from __future__ import absolute_import, division, print_function

import json
import logging
import os
import subprocess

import libtbx.phil

# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
Expand All @@ -23,18 +29,11 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

import json
import logging
import os
import subprocess

import libtbx.phil
from six.moves import range

logger = logging.getLogger(__name__)


class SysArgvData(object):
class SysArgvData:
"""
Some data related to how the GUI gets launched from CLI
"""
Expand Down Expand Up @@ -100,15 +99,15 @@ def get_next_step(node_obj):
return None


class ScopeData(object):
class ScopeData:
"""
class conceived to store only data related to the scope Phil object
"""

pass


class tree_2_lineal(object):
class tree_2_lineal:

"""
Recursively navigates the Phil objects in a way that the final
Expand Down Expand Up @@ -273,13 +272,6 @@ def build_command_lst(node_obj, cmd_lst):
sol_num = 1

except BaseException as e:
# We don't want to catch bare exceptions but don't know
# what this was supposed to catch. Log it.
logger.info("\n reindex \n exeption:", e, "type:", type(e))

# getting to exeption: list index out of range
# type: <type 'exceptions.IndexError'>

logger.debug("Caught unknown exception type %s: %s", type(e).__name__, e)
sol_num = 1

Expand Down Expand Up @@ -387,7 +379,7 @@ def build_command_lst(node_obj, cmd_lst):

cmd_lst_to_run.append(lst_inner)

# logger.info("\n\n test:", cmd_lst_to_run, "\n")
# logger.info(f"\n\n test: {cmd_lst_to_run}\n")

return cmd_lst_to_run

Expand Down Expand Up @@ -490,7 +482,7 @@ def generate_report(node_obj):

tst_path = os.path.join(cwd_path, htm_fil)
if not (os.path.exists(tst_path)):
logger.debug("\n ___________________________ tst_path =", tst_path, "\n")
logger.debug("\n ___________________________ tst_path = %s", tst_path)
if node_obj.ll_command_lst[0][0] == "find_spots":
rep_cmd = "dials.report " + refl_inp + " " + deps_outp + " " + html_outp

Expand Down Expand Up @@ -539,7 +531,7 @@ def generate_report(node_obj):
return rep_out


class DialsCommand(object):
class DialsCommand:
def __init__(self):
logger.debug("creating new DialsCommand (obj)")
self.full_cmd_lst = [None]
Expand Down Expand Up @@ -574,7 +566,7 @@ def __call__(self, lst_cmd_to_run=None, ref_to_class=None):

cwd_path = os.path.join(sys_arg.directory, "dui_files")

#logger.info("\nRunning:", run_cmd, "\n")
# logger.info(f"\nRunning: {run_cmd}\n")

my_process = subprocess.Popen(
run_cmd,
Expand All @@ -587,13 +579,10 @@ def __call__(self, lst_cmd_to_run=None, ref_to_class=None):
self.my_pid = my_process.pid
for line in iter(my_process.stdout.readline, b""):
single_line = line[0 : len(line) - 1]
# logger.info(">>: ", single_line)
self.tmp_std_all.append(single_line)
try:
ref_to_class.emit_print_signal(single_line)

except AttributeError:
logger.info(">>: ", single_line)
if ref_to_class:
ref_to_class.emit_print_signal(single_line)

my_process.wait()
my_process.stdout.close()
Expand All @@ -603,7 +592,9 @@ def __call__(self, lst_cmd_to_run=None, ref_to_class=None):
else:
local_success = False
# TODO handle error outputs
logger.info("\n __________________ Failed ______________________ \n")
logger.info(
"\n __________________ Failed ______________________ \n"
)
try:
ref_to_class.emit_fail_signal()
return False
Expand Down Expand Up @@ -661,7 +652,7 @@ def print_list(lst, curr):
logger.info(stp_str)


class TreeShow(object):
class TreeShow:
def __init__(self):
self.ind_spc = " "
self.ind_lin = "------"
Expand All @@ -683,7 +674,7 @@ def __call__(self, my_runner):
self.add_tree(step=my_runner.step_list[0], indent=0)
self.tree_print(my_runner.current_line)
# TODO maybe here goes a print print function instead of logger ...
logger.info("---------------------" + self.max_indent * self.ind_lin)
logger.info("---------------------%s", self.max_indent * self.ind_lin)

def add_tree(self, step=None, indent=None):
if step.success is True:
Expand All @@ -693,7 +684,7 @@ def add_tree(self, step=None, indent=None):
else:
stp_prn = " N "

str_lin_num = "{0:3}".format(int(step.lin_num))
str_lin_num = "{:3}".format(int(step.lin_num))

stp_prn += str_lin_num + self.ind_spc * indent + r" \___"
stp_prn += str(step.ll_command_lst[0][0])
Expand Down
Loading

0 comments on commit c188774

Please sign in to comment.