Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement correct export/print stages and dialog behavior #666

Merged
merged 33 commits into from
Feb 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
2a88327
add method to start export vm to Controller
Jan 9, 2020
bb961ec
connect gui to controller to start export vm
Jan 9, 2020
43d534f
create FramelessModal and polish dialog
Jan 9, 2020
8c12588
Update tests for export and print dialogs
Jan 13, 2020
e02884d
add error details section and resize dialog
Jan 14, 2020
d712fd1
reword print speedbump
Jan 14, 2020
6102edd
gracefully handle no active window case
Jan 14, 2020
d4839e7
qubes workaround: only allow one modal at a time
Jan 16, 2020
51ee7f8
run preflight on dialog startup
Jan 16, 2020
d123b26
Tweak printer dialog language for clarity
eloquence Jan 17, 2020
5cdefa9
refactor how we handle different Export VM codes
Jan 17, 2020
1e0a2cb
refactor export status code handling
Jan 17, 2020
dfed9f7
hide header line when asking for passphrase
Jan 17, 2020
9d2165e
update tests for export and print
Jan 17, 2020
2a0ec15
polish primary dialog button
Jan 17, 2020
64ef17d
remove disabled button text
Jan 17, 2020
f17a7aa
hold onto error status
Jan 17, 2020
3dedc99
show cancel and done buttons for generic errors
Jan 17, 2020
7b3a95d
wrap controller method
Jan 17, 2020
a374a57
wire up dialog after bad passphrase
Jan 17, 2020
bd71ffe
add printer and savetodisk icons
Jan 17, 2020
958fe5d
rename framelessmodal to framelessdialog
Jan 18, 2020
4f9694e
show error for bad passphrase
Jan 18, 2020
3ded5f2
add show/hide passphrase
Jan 18, 2020
54b1268
show when an export is successful in the client
Jan 21, 2020
a271358
fix mypy error default to empty string
Jan 21, 2020
dd0e72a
fix resize issue
Feb 19, 2020
8a46d51
Merge branch 'master' into applicationmodal
sssoleileraaa Feb 19, 2020
43b2ed3
sanitize filename on dialogs
Feb 20, 2020
2684b3b
break previous connection on continue button
Feb 21, 2020
05876cb
Merge branch 'master' into applicationmodal
sssoleileraaa Feb 21, 2020
0386dda
prevent more than one dialog at a time
Feb 24, 2020
640b3d9
center when the application window is off-center
Feb 24, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 38 additions & 4 deletions securedrop_client/export.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ class Export(QObject):
'device': 'usb-test'
}

PRINTER_PREFLIGHT_FN = 'printer-preflight.sd-export'
PRINTER_PREFLIGHT_METADATA = {
'device': 'printer-preflight'
}

DISK_TEST_FN = 'disk-test.sd-export'
DISK_TEST_METADATA = {
'device': 'disk-test'
Expand All @@ -74,23 +79,28 @@ class Export(QObject):
DISK_EXPORT_DIR = 'export_data'

# Set up signals for communication with the GUI thread
begin_preflight_check = pyqtSignal()
preflight_check_call_failure = pyqtSignal(object)
preflight_check_call_success = pyqtSignal(str)
preflight_check_call_success = pyqtSignal()
begin_usb_export = pyqtSignal(list, str)
begin_preflight_check = pyqtSignal()
export_usb_call_failure = pyqtSignal(object)
export_usb_call_success = pyqtSignal()
export_completed = pyqtSignal(list)

begin_printer_preflight = pyqtSignal()
printer_preflight_success = pyqtSignal()
printer_preflight_failure = pyqtSignal(object)
begin_print = pyqtSignal(list)
print_call_failure = pyqtSignal(object)
print_call_success = pyqtSignal()
export_completed = pyqtSignal(list)

def __init__(self) -> None:
super().__init__()

self.begin_preflight_check.connect(self.run_preflight_checks, type=Qt.QueuedConnection)
self.begin_usb_export.connect(self.send_file_to_usb_device, type=Qt.QueuedConnection)
self.begin_print.connect(self.print, type=Qt.QueuedConnection)
self.begin_printer_preflight.connect(self.run_printer_preflight, type=Qt.QueuedConnection)

def _export_archive(cls, archive_path: str) -> str:
'''
Expand Down Expand Up @@ -183,6 +193,17 @@ def _add_file_to_archive(cls, archive: tarfile.TarFile, filepath: str) -> None:
arcname = os.path.join(cls.DISK_EXPORT_DIR, filename)
archive.add(filepath, arcname=arcname, recursive=False)

def _run_printer_preflight(self, archive_dir: str) -> None:
'''
Make sure printer is ready.
'''
archive_path = self._create_archive(
archive_dir, self.PRINTER_PREFLIGHT_FN, self.PRINTER_PREFLIGHT_METADATA)

status = self._export_archive(archive_path)
if status:
raise ExportError(status)

def _run_usb_test(self, archive_dir: str) -> None:
'''
Run usb-test.
Expand Down Expand Up @@ -258,11 +279,24 @@ def run_preflight_checks(self) -> None:
self._run_usb_test(temp_dir)
self._run_disk_test(temp_dir)
logger.debug('completed preflight checks: success')
self.preflight_check_call_success.emit('success')
self.preflight_check_call_success.emit()
except ExportError as e:
logger.debug('completed preflight checks: failure')
self.preflight_check_call_failure.emit(e)

@pyqtSlot()
def run_printer_preflight(self) -> None:
'''
Make sure the Export VM is started.
'''
with TemporaryDirectory() as temp_dir:
try:
self._run_printer_preflight(temp_dir)
self.printer_preflight_success.emit()
except ExportError as e:
logger.error(e)
self.printer_preflight_failure.emit(e)

@pyqtSlot(list, str)
def send_file_to_usb_device(self, filepaths: List[str], passphrase: str) -> None:
'''
Expand Down
8 changes: 8 additions & 0 deletions securedrop_client/gui/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,14 @@ def __init__(self, filename: str, svg_size: str = None) -> None:
self.svg.setFixedSize(svg_size) if svg_size else self.svg.setFixedSize(QSize())
layout.addWidget(self.svg)

def update_image(self, filename: str, svg_size: str = None) -> None:
self.svg = load_svg(filename)
self.svg.setFixedSize(svg_size) if svg_size else self.svg.setFixedSize(QSize())
child = self.layout().takeAt(0)
if child and child.widget():
child.widget().deleteLater()
self.layout().addWidget(self.svg)


class SecureQLabel(QLabel):
def __init__(
Expand Down
Loading