Refactor restore backups call to use HttpRequestManager

This commit is contained in:
Nino van Hooff 2020-02-28 16:25:43 +01:00
parent 234acf0904
commit 4f2827e1bf

View file

@ -17,7 +17,7 @@ from UM.TaskManagement.HttpRequestScope import JsonDecoratorScope
from cura.CuraApplication import CuraApplication from cura.CuraApplication import CuraApplication
from plugins.Toolbox.src.UltimakerCloudScope import UltimakerCloudScope from plugins.Toolbox.src.UltimakerCloudScope import UltimakerCloudScope
from PyQt5.QtNetwork import QNetworkReply from PyQt5.QtNetwork import QNetworkReply, QNetworkRequest
from .UploadBackupJob import UploadBackupJob from .UploadBackupJob import UploadBackupJob
from .Settings import Settings from .Settings import Settings
@ -30,6 +30,7 @@ catalog = i18nCatalog("cura")
@signalemitter @signalemitter
class DriveApiService: class DriveApiService:
BACKUP_URL = "{}/backups".format(Settings.DRIVE_API_URL) BACKUP_URL = "{}/backups".format(Settings.DRIVE_API_URL)
DISK_WRITE_BUFFER_SIZE = 512 * 1024
# Emit signal when restoring backup started or finished. # Emit signal when restoring backup started or finished.
restoringStateChanged = Signal() restoringStateChanged = Signal()
@ -40,9 +41,14 @@ class DriveApiService:
def __init__(self) -> None: def __init__(self) -> None:
self._cura_api = CuraApplication.getInstance().getCuraAPI() self._cura_api = CuraApplication.getInstance().getCuraAPI()
self._scope = JsonDecoratorScope(UltimakerCloudScope(CuraApplication.getInstance())) self._scope = JsonDecoratorScope(UltimakerCloudScope(CuraApplication.getInstance()))
self._in_progress_backup = None
def getBackups(self, changed: Callable): def getBackups(self, changed: Callable):
def callback(reply: QNetworkReply): def callback(reply: QNetworkReply, error: Optional["QNetworkReply.NetworkError"] = None):
if error is not None:
Logger.log("w", "Could not get backups: " + str(error))
changed([])
backup_list_response = HttpRequestManager.readJSON(reply) backup_list_response = HttpRequestManager.readJSON(reply)
if "data" not in backup_list_response: if "data" not in backup_list_response:
Logger.log("w", "Could not get backups from remote, actual response body was: %s", Logger.log("w", "Could not get backups from remote, actual response body was: %s",
@ -94,22 +100,32 @@ class DriveApiService:
# If there is no download URL, we can't restore the backup. # If there is no download URL, we can't restore the backup.
return self._emitRestoreError() return self._emitRestoreError()
try: def finishedCallback(reply: QNetworkReply, bu=backup) -> None:
download_package = requests.get(download_url, stream = True) self._onRestoreRequestCompleted(reply, None, bu)
except requests.exceptions.ConnectionError:
Logger.logException("e", "Unable to connect with the server")
return self._emitRestoreError()
if download_package.status_code >= 300: HttpRequestManager.getInstance().get(
# Something went wrong when attempting to download the backup. url = download_url,
Logger.log("w", "Could not download backup from url %s: %s", download_url, download_package.text) callback = finishedCallback,
return self._emitRestoreError() error_callback = self._onRestoreRequestCompleted
)
def _onRestoreRequestCompleted(self, reply: QNetworkReply, error: Optional["QNetworkReply.NetworkError"] = None, backup = None):
if error is not None or reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) != 200:
Logger.log("w",
"Requesting backup failed, response code %s while trying to connect to %s",
reply.attribute(QNetworkRequest.HttpStatusCodeAttribute), reply.url())
self._emitRestoreError()
return
# We store the file in a temporary path fist to ensure integrity. # We store the file in a temporary path fist to ensure integrity.
temporary_backup_file = NamedTemporaryFile(delete = False) temporary_backup_file = NamedTemporaryFile(delete = False)
with open(temporary_backup_file.name, "wb") as write_backup: with open(temporary_backup_file.name, "wb") as write_backup:
for chunk in download_package: app = CuraApplication.getInstance()
write_backup.write(chunk) bytes_read = reply.read(DriveApiService.DISK_WRITE_BUFFER_SIZE)
while bytes_read:
write_backup.write(bytes_read)
bytes_read = reply.read(DriveApiService.DISK_WRITE_BUFFER_SIZE)
app.processEvents()
if not self._verifyMd5Hash(temporary_backup_file.name, backup.get("md5_hash", "")): if not self._verifyMd5Hash(temporary_backup_file.name, backup.get("md5_hash", "")):
# Don't restore the backup if the MD5 hashes do not match. # Don't restore the backup if the MD5 hashes do not match.