Skip to content

Commit

Permalink
Fix merge conflicts and out-of-sync function signatures.
Browse files Browse the repository at this point in the history
  • Loading branch information
ntoll committed Jan 27, 2020
2 parents 5037f3e + 0defbcf commit 4738bea
Show file tree
Hide file tree
Showing 12 changed files with 225 additions and 42 deletions.
30 changes: 15 additions & 15 deletions build-requirements.txt
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
alembic==1.0.2 --hash=sha256:14024bd47f71d8b51920721dcd63248d07d370fbd0f6afa9bec67b9edaf71f36
arrow==0.12.1 --hash=sha256:5ef4a593615dc61ed85e62070b1bd27c71f7266233f0f9f385b651370e8c6760
certifi==2018.10.15 --hash=sha256:a5471c55b011bd45d6155f5c3629310c1d2f1e1a5a899b7e438a223343de583d
chardet==3.0.4 --hash=sha256:9f178988ca4c86e8a319b51aac1185b6fe5192328eb5a163c286f4bf50b7b3d8
idna==2.7 --hash=sha256:954e65e127d0433a352981f43f291a438423d5b385ebf643c70fd740e0634111
mako==1.0.7 --hash=sha256:87ee3f74ba3ea544e683a5a22e7e34f4d1cf3ad34414b5f3858becf00facf1d6
markupsafe==1.0 --hash=sha256:6a7078a2fb4406458d6ae3579e4eb01a9bdc0a9a0686a28fa50c19a039e3fcb8 --hash=sha256:3c9bf8fb4c3cf7dd11fd465132156d4c3cddb926d39bdbd0f0bf5920fd8009a4
pathlib2==2.3.2 --hash=sha256:8e276e2bf50a9a06c36e20f03b050e59b63dfe0678e37164333deb87af03b6ad
python-dateutil==2.7.5 --hash=sha256:56f285e7fad54cde3e31dc68a31a861543bfee5ada9278da8e85ec20a8f72912
python-editor==1.0.3 --hash=sha256:44fc57a6db6e04c7922c37a04d0a86d0024a4f0f06245b6c57638cb322176202
requests==2.20.0 --hash=sha256:2a539dd6af40a611f3b8eb3f99d3567781352ece1698b2fab42bf4c2218705b5
securedrop-sdk==0.0.12 --hash=sha256:274beb38dccd91988b45517e6479863f80bb31e00953695e61dd8103509f2337
six==1.11.0 --hash=sha256:4663c7a1dbed033cfb294f2d534bd6151c0698dc12ecabb4eaa3cb041d758528
sqlalchemy==1.3.3 --hash=sha256:bd030ff97e7a4f3aa34aafa6b62898c7de6999784c8b4828b3e8b31cf69dae9c --hash=sha256:680b2ae6a728941c9fe661c85f2309a69408e7ec8ed8fa39d03e07595259b75b
urllib3==1.24.3 --hash=sha256:028309393606e28e640e2031edd27eb969c94f9364b0871912608aaa8e66c96e
alembic==1.0.2 --hash=sha256:99cc931e11dbef6e41e9376f18be62fc90fe4be9c541eac1b30a3455b3d655f3
arrow==0.12.1 --hash=sha256:fc8c8e0b587d00f38986bc161f4496e000acea033fe2ce25f4f5bffa9ae53a7c
certifi==2018.10.15 --hash=sha256:173b19dd31ca7faa50d1fcc0eaf30f5e32e8e99e17d8c7fd4cfc8bc8d94e18a6
chardet==3.0.4 --hash=sha256:f5632e583a4f61f1e16d0cc98127d241fb11c3c6ddfddee159307d4215186837
idna==2.7 --hash=sha256:491f674364ba3232ed1eb4c1eb7407887f62cef6c300aad7df6e01acd88ffb25
mako==1.0.7 --hash=sha256:614c22fe1a5b0a3f46f6c5c43ff2e6795e4e784328d559ec9dc49db0f06b3a75
markupsafe==1.0 --hash=sha256:c6b726d2e9d6300a044cf6a37627f10994268d6ac39464bc0d725126609311a5
pathlib2==2.3.2 --hash=sha256:460e67b14d0574b0529a0017b1eb05d10d9722681e303fec7077c2a628de60c1
python-dateutil==2.7.5 --hash=sha256:f6eb9c17acd5a6954e1a5f2f999a41de3e7e25b6bc41baf6344bd053ec25ceeb
python-editor==1.0.3 --hash=sha256:e47dcec4ea883853b8196fbd425b875d7ec791d4ede2e20cfc70b9a25365c65b
requests==2.20.0 --hash=sha256:d87b2085783d31d874ac7bc62660e287932aaee7059e80b41b76462eb18d35cc
securedrop-sdk==0.0.12 --hash=sha256:d05bb78652c8771e6aa1aefcd76ade1fef08c563d2641acbc5ac8e1d635e6a53
six==1.11.0 --hash=sha256:aa4ad34049ddff178b533062797fd1db9f0038b7c5c2461a7cde2244300b9f3d
sqlalchemy==1.3.3 --hash=sha256:bfb4cd0df5802a01acd738a080a19e60ff4700e030d497de273807f9a8bd4a0a
urllib3==1.24.3 --hash=sha256:3d440cbb168e2c963d5099232bdb3f7390bf031b6270dad1bc79751698a1399a
8 changes: 6 additions & 2 deletions securedrop_client/api_jobs/updatestar.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import logging
import sdclientapi

from typing import Tuple

from sdclientapi import API
from sqlalchemy.orm.session import Session

Expand All @@ -15,7 +17,7 @@ def __init__(self, source_uuid: str, star_status: bool) -> None:
self.source_uuid = source_uuid
self.star_status = star_status

def call_api(self, api_client: API, session: Session) -> str:
def call_api(self, api_client: API, session: Session) -> Tuple[str, bool]:
'''
Override ApiJob.
Expand All @@ -33,7 +35,9 @@ def call_api(self, api_client: API, session: Session) -> str:
else:
api_client.add_star(source_sdk_object)

return self.source_uuid
# Identify the source and *new* state of the star so the UI can be
# updated.
return self.source_uuid, not self.star_status
except Exception as e:
error_message = "Failed to update star on source {uuid} due to {exception}".format(
uuid=self.source_uuid, exception=repr(e))
Expand Down
47 changes: 39 additions & 8 deletions securedrop_client/gui/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
from securedrop_client.export import ExportStatus, ExportError
from securedrop_client.gui import SecureQLabel, SvgLabel, SvgPushButton, SvgToggleButton
from securedrop_client.logic import Controller
from securedrop_client.resources import load_icon, load_image
from securedrop_client.resources import load_icon, load_image, load_movie
from securedrop_client.utils import humanize_filesize

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -995,7 +995,7 @@ def __init__(self, source: Source):
summary_layout.setSpacing(0)
self.name = QLabel()
self.name.setObjectName('source_name')
self.preview = QLabel()
self.preview = SecureQLabel()
self.preview.setObjectName('preview')
self.preview.setFixedSize(QSize(self.PREVIEW_WIDTH, self.PREVIEW_HEIGHT))
self.preview.setWordWrap(True)
Expand Down Expand Up @@ -1044,7 +1044,7 @@ def update(self):
"""
Updates the displayed values with the current values from self.source.
"""
self.timestamp.setText(arrow.get(self.source.last_updated).format('DD MMM'))
self.timestamp.setText(_(arrow.get(self.source.last_updated).format('DD MMM')))
self.name.setText(self.source.journalist_designation)
if self.source.collection:
msg = str(self.source.collection[-1])
Expand Down Expand Up @@ -1107,7 +1107,7 @@ def on_toggle(self):
"""
Tell the controller to make an API call to update the source's starred field.
"""
self.controller.update_star(self.source)
self.controller.update_star(self.source, self.on_update)

def on_toggle_offline(self):
"""
Expand All @@ -1121,6 +1121,16 @@ def on_toggle_offline(self):
if self.source.is_starred:
self.set_icon(on='star_on.svg', off='star_on.svg')

def on_update(self, result):
"""
The result is a uuid for the source and boolean flag for the new state
of the star.
"""
enabled = result[1]
self.source.is_starred = enabled
self.controller.update_sources()
self.setChecked(enabled)


class DeleteSourceMessageBox:
"""Use this to display operation details and confirm user choice."""
Expand Down Expand Up @@ -1790,7 +1800,7 @@ class FileWidget(QWidget):
}
QPushButton#export_print {
border: none;
padding: 8px;
padding: 0px 8px;
font-family: 'Source Sans Pro';
font-weight: 500;
font-size: 13px;
Expand All @@ -1811,7 +1821,7 @@ class FileWidget(QWidget):
padding-right: 8px;
font-family: 'Source Sans Pro';
font-weight: 700;
font-size: 14px;
font-size: 13px;
color: #2a319d;
}
QLabel#no_file_name {
Expand Down Expand Up @@ -1888,6 +1898,7 @@ def __init__(
self.download_button.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
self.download_button.setIcon(load_icon('download_file.svg'))
self.download_button.setFont(file_buttons_font)
self.download_animation = load_movie("download_animation.gif")
self.export_button = QPushButton(_('EXPORT'))
self.export_button.setObjectName('export_print')
self.export_button.setFont(file_buttons_font)
Expand Down Expand Up @@ -2008,9 +2019,29 @@ def _on_left_click(self):
# Open the already downloaded file.
self.controller.on_file_open(self.file.uuid)
else:
if self.controller.api:
# Indicate in downloading state... but only after 0.3 seconds (i.e.
# this is taking a noticable amount of time to complete).
QTimer.singleShot(300, self.start_button_animation)
# Download the file.
self.controller.on_submission_download(File, self.file.uuid)

def start_button_animation(self):
"""
Update the download button to the animated "downloading" state.
"""
self.download_animation.frameChanged.connect(self.set_button_animation_frame)
self.download_animation.start()
self.download_button.setText(_(" DOWNLOADING "))
self.download_button.setStyleSheet("color: #05a6fe")

def set_button_animation_frame(self, frame_number):
"""
Sets the download button's icon to the current frame of the spinner
animation.
"""
self.download_button.setIcon(QIcon(self.download_animation.currentPixmap()))


class PrintDialog(QDialog):

Expand Down Expand Up @@ -2899,7 +2930,7 @@ class LastUpdatedLabel(QLabel):
'''

def __init__(self, last_updated):
super().__init__(_(_('{}').format(arrow.get(last_updated).humanize())))
super().__init__(last_updated)

# Set css id
self.setObjectName('conversation-title-date')
Expand Down Expand Up @@ -2949,7 +2980,7 @@ def __init__(self, source, controller):
header_layout.setContentsMargins(
self.MARGIN_LEFT, self.VERTICAL_MARGIN, self.MARGIN_RIGHT, self.VERTICAL_MARGIN)
title = TitleLabel(self.source.journalist_designation)
updated = LastUpdatedLabel(self.source.last_updated)
updated = LastUpdatedLabel(_(arrow.get(self.source.last_updated).format('DD MMM')))
menu = SourceMenuButton(self.source, self.controller)
header_layout.addWidget(title, alignment=Qt.AlignLeft)
header_layout.addStretch()
Expand Down
9 changes: 6 additions & 3 deletions securedrop_client/logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,6 @@ def on_update_star_success(self, result) -> None:
After we star a source, we should sync the API such that the local database is updated.
"""
self.gui.clear_error_status() # remove any permanent error status message
self.sync_api() # Syncing the API also updates the source list UI

def on_update_star_failure(self, result: UpdateStarJobException) -> None:
"""
Expand All @@ -482,7 +481,7 @@ def on_update_star_failure(self, result: UpdateStarJobException) -> None:
error = _('Failed to update star.')
self.gui.update_error_status(error)

def update_star(self, source_db_object):
def update_star(self, source_db_object, callback):
"""
Star or unstar. The callback here is the API sync as we first make sure
that we apply the change to the server, and then update locally.
Expand All @@ -493,6 +492,7 @@ def update_star(self, source_db_object):

job = UpdateStarJob(source_db_object.uuid, source_db_object.is_starred)
job.success_signal.connect(self.on_update_star_success, type=Qt.QueuedConnection)
job.success_signal.connect(callback, type=Qt.QueuedConnection)
job.failure_signal.connect(self.on_update_star_failure, type=Qt.QueuedConnection)

self.api_job_queue.enqueue(job)
Expand Down Expand Up @@ -752,8 +752,11 @@ def on_delete_source_success(self, result) -> None:
"""
Handler for when a source deletion succeeds.
"""
# Delete the local version of the source.
storage.delete_local_source_by_uuid(self.session, result)
self.gui.clear_error_status() # remove any permanent error status message
self.sync_api()
# Update the sources UI.
self.update_sources()

def on_delete_source_failure(self, result: Exception) -> None:
logging.info("failed to delete source at server")
Expand Down
9 changes: 8 additions & 1 deletion securedrop_client/resources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import os

from pkg_resources import resource_filename, resource_string
from PyQt5.QtGui import QPixmap, QIcon, QFontDatabase
from PyQt5.QtGui import QPixmap, QIcon, QFontDatabase, QMovie
from PyQt5.QtSvg import QSvgWidget
from PyQt5.QtCore import QDir

Expand Down Expand Up @@ -133,3 +133,10 @@ def load_css(name: str) -> str:
Return the contents of the referenced CSS file in the resources.
"""
return resource_string(__name__, "css/" + name).decode('utf-8')


def load_movie(name: str) -> str:
"""
Return a GIF animation to use in the UI.
"""
return QMovie(path(name))
11 changes: 11 additions & 0 deletions securedrop_client/resources/images/download_active.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions securedrop_client/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,17 @@ def get_local_sources(session: Session) -> List[Source]:
return session.query(Source).all()


def delete_local_source_by_uuid(session: Session, uuid: str) -> None:
"""
Delete the source with the referenced UUID.
"""
source = session.query(Source).filter_by(uuid=uuid).one_or_none()
if source:
session.delete(source)
session.commit()
logger.info("Deleted source with UUID {} from local database.".format(uuid))


def get_local_messages(session: Session) -> List[Message]:
"""
Return all submission objects from the local database.
Expand Down
Loading

0 comments on commit 4738bea

Please sign in to comment.