def test_to_json(self): app_state = AppState() new_conf = DownloadConfiguration(number_of_images=9309, images_per_category=83, download_destination='481516') last_result = Result(failed_urls=['1', 'one'], succeeded_urls=['x']) progress_info = ProgressInfo(total_downloaded=192, total_failed=38, finished=False, last_result=last_result) position = Position(3, 1) counts = {'wnid1': 29, 'wnid10': 3} internal = InternalState(iterator_position=position, category_counts=counts, file_index=322) app_state.set_configuration(new_conf) app_state.set_progress_info(progress_info) app_state.set_internal_state(internal) app_state.add_error('Some error') state_data = json.loads(app_state.to_json()) self.assertEqual(state_data['downloadPath'], '481516') self.assertEqual(state_data['numberOfImages'], 9309) self.assertEqual(state_data['imagesPerCategory'], 83) self.assertNotEqual(state_data['timeLeft'], '') self.assertEqual(state_data['imagesLoaded'], 192) self.assertEqual(state_data['failures'], 38) self.assertEqual(state_data['failedUrls'], ['1', 'one']) self.assertEqual(state_data['succeededUrls'], ['x']) self.assertEqual(state_data['errors'], ['Some error']) self.assertAlmostEqual(state_data['progress'], 192.0 / 9309)
class StateManager(QtCore.QObject): stateChanged = QtCore.pyqtSignal() exceptionRaised = QtCore.pyqtSignal(str, arguments=['message']) def __init__(self): super().__init__() self._app_state = AppState() self._log_path = config.log_path if self._app_state.progress_info.finished: self._state = 'finished' elif self._app_state.inprogress: self._state = 'paused' else: self._state = 'initial' self._reset_log() self._strategy = self.get_strategy() self._connect_signals() def _connect_signals(self): def handle_loaded(urls): self.stateChanged.emit() def handle_failed(urls): self._log_failures(self._log_path, urls) self.stateChanged.emit() def handle_paused(): self._state = 'paused' self.stateChanged.emit() def handle_allDownloaded(): self._state = 'finished' self._app_state.mark_finished() self._app_state.save() self.stateChanged.emit() def handle_exception(message): self._state = 'error' self.exceptionRaised.emit(message) self._strategy.imagesLoaded.connect(handle_loaded) self._strategy.downloadFailed.connect(handle_failed) self._strategy.downloadPaused.connect(handle_paused) self._strategy.allDownloaded.connect(handle_allDownloaded) self._strategy.exceptionRaised.connect(handle_exception) def _reset_log(self): if not os.path.exists(config.app_data_folder): os.mkdir(config.app_data_folder) if os.path.isfile(self._log_path): os.remove(self._log_path) with open(self._log_path, 'w') as f: f.write('') def _log_failures(self, log_path, urls): with open(log_path, 'a') as f: lines = '\n'.join(urls) f.write(lines) def get_strategy(self): return DummyStrategy() @QtCore.pyqtSlot() def start_download(self): if self._state == 'ready': self._state = 'running' self.stateChanged.emit() self._strategy.start() @QtCore.pyqtSlot(str, int, int) def configure(self, destination, number_of_images, images_per_category): if self._state not in ['initial', 'ready']: return self._app_state.reset() conf = DownloadConfiguration(number_of_images=number_of_images, images_per_category=images_per_category, download_destination=destination, batch_size=config.default_batch_size) if conf.is_valid: self._state = 'ready' path = self._parse_url(destination) conf.download_destination = path self._app_state.set_configuration(conf) else: self._state = 'initial' self._generate_error_messages(conf) self.stateChanged.emit() def _generate_error_messages(self, download_conf): for e in download_conf.errors: self._app_state.add_error(e) def _parse_url(self, file_uri): p = urlparse(file_uri) return os.path.abspath(os.path.join(p.netloc, p.path)) @QtCore.pyqtSlot() def pause(self): if self._state == 'running': self._state = 'pausing' self.stateChanged.emit() self._strategy.pause_download() @QtCore.pyqtSlot() def resume(self): if self._state == 'paused': self._state = 'running' self._strategy.resume_download() self.stateChanged.emit() @QtCore.pyqtSlot() def reset(self): if self._state not in ['running', 'pausing']: self._state = 'initial' self._reset_log() self._app_state.reset() self._strategy.quit() self._strategy = self.get_strategy() self._connect_signals() self._app_state.save() self.stateChanged.emit() @QtCore.pyqtProperty(str) def download_state(self): return self._state @QtCore.pyqtProperty(str) def state_data_json(self): return self._app_state.to_json() @QtCore.pyqtProperty(str) def time_remaining(self): return self._app_state.time_remaining