class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): def __init__(self, path, config_dict, parent=None): QtWidgets.QMainWindow.__init__(self, parent) self.config_dict = config_dict self.config_path = path logging.info('mainwindow.py - UI initialization ...') self.setupUi(self) self.backup.clicked.connect(self.backup_configuration_file) self.check_downloader_update() self.check_file_folder() self.populate_folder_target() logging.info('mainwindow.py - UI initialized ...') logging.info('*****************************************') @QtCore.pyqtSlot() def on_actionExit_triggered(self): self.close() @QtCore.pyqtSlot() def on_actionAbout_triggered(self): self.open_about() @QtCore.pyqtSlot() def on_actionOptions_triggered(self): self.open_options() @QtCore.pyqtSlot() def on_actionUpdate_triggered(self): self.download_and_install_update() def populate_folder_target(self): logging.debug('mainwindow.py - populate_folder_target') self.label_3.setText(self.config_dict.get('CREDENTIALS', 'folder')) self.label_4.setText(self.config_dict.get('CREDENTIALS', 'target')) def backup_configuration_file(self): logging.debug('mainwindow.py - backup_configuration_file') target = self.config_dict.get('CREDENTIALS', 'target') if target: success = False failure_reason = '' nas_md5 = '' password = self.config_dict.get('CREDENTIALS', 'password') username = self.config_dict.get('CREDENTIALS', 'username') if not password or not username: logging.debug( 'mainwindow.py - backup_configuration_file - username/password missing' ) self.credentialsyWindow = MyCredentials(username, password) x1, y1, w1, h1 = self.geometry().getRect() _, _, w2, h2 = self.credentialsyWindow.geometry().getRect() x2 = x1 + w1 / 2 - w2 / 2 y2 = y1 + h1 / 2 - h2 / 2 self.credentialsyWindow.setGeometry(x2, y2, w2, h2) self.credentialsyWindow.exec_() if self.credentialsyWindow.username and self.credentialsyWindow.password: username = self.credentialsyWindow.username password = self.credentialsyWindow.password if username and password: folder = self.config_dict.get('CREDENTIALS', 'folder') port = self.config_dict.get('CREDENTIALS', 'target_port') y, m, d = str(datetime.datetime.now().year), str( datetime.datetime.now().month), str( datetime.datetime.now().day) h, mm, s = str(datetime.datetime.now().hour), str( datetime.datetime.now().minute), str( datetime.datetime.now().second) if len(m) == 1: m = '0' + m if len(d) == 1: d = '0' + d if len(h) == 1: h = '0' + h if len(mm) == 1: mm = '0' + mm if len(s) == 1: s = '0' + s filename = 'configuration_' + target + '_' + y + m + d + 'T' + h + mm + s + '.xml' try: try: logging.debug( 'mainwindow.py - backup_configuration_file - ssh connection...' ) ssh_client = paramiko.SSHClient() ssh_client.set_missing_host_key_policy( paramiko.AutoAddPolicy()) ssh_client.connect(hostname=target, username=username, password=password) logging.debug( 'mainwindow.py - backup_configuration_file - ssh connection established' ) stdin, stdout, stderr = ssh_client.exec_command( 'md5 /conf/config.xml') tmp = str(stdout.readlines()) if tmp != '[]': index1 = tmp.find('=') nas_md5 = tmp[index1 + 2:-4] logging.debug( 'mainwindow.py - backup_configuration_file - MD5 checksum generated' ) else: failure_reason = str(stderr.readlines())[2:-4] logging.debug( 'mainwindow.py - backup_configuration_file - MD5 checksum failed' ) if platform.system() == 'Windows': full_path = folder + '\\' + filename separator = '\\' elif platform.system() == 'Linux': full_path = folder + '/' + filename separator = '/' logging.debug( 'mainwindow.py - backup_configuration_file - opening sftp' ) ftp_client = ssh_client.open_sftp() logging.debug( 'mainwindow.py - backup_configuration_file - sftp opened, requesting file' ) ftp_client.get('/conf/config.xml', full_path) logging.debug( 'mainwindow.py - backup_configuration_file - file downloaded' ) ftp_client.close() ssh_client.close() success = True local_md5 = hashlib.md5(open(full_path, 'rb').read()).hexdigest() except paramiko.ssh_exception.AuthenticationException: failure_reason = 'Authentication seems to have failed. Please check the username and/or the password for authentication.' logging.exception( 'mainwindow.py - backup_configuration_file - AuthenticationException - authentication seems to have failed, check' + ' username and/or password.') except FileNotFoundError: failure_reason = 'The configuration file has not been found. Please check the path and/or the name of the file.' logging.exception( 'mainwindow.py - backup_configuration_file - FileNotFoundError - configuration file not found, check the path' + ' and/or the name of the file.') except PermissionError: failure_reason = 'The account linked to the username and password doesn\'t seem to have sufficient rights to access NAS by SSH.' logging.exception( 'mainwindow.py - backup_configuration_file - PermissionError - account with insufficient rights.' ) except Exception: failure_reason = 'Download of the configuration file failed for an unknown reason. Please check the log file for details.' logging.exception( 'mainwindow.py - backup_configuration_file - Exception - an exception has occured.' ) if not success: text = failure_reason else: if nas_md5 == local_md5 and nas_md5 != '': text = ( 'The configuration file has been well backed up in the folder:<br> <b>' + folder + '</b><br>' + 'with the file name:<br> <b>' + filename + '</b>.') else: if nas_md5 == '' and local_md5 == '': text = ( 'The configuration file has been downloaded in the folder:<br> <b>' + folder + '</b><br>' + 'with the file name:<br> <b>' + filename + '</b>.<br><br><span style=\" font-weight:600' + '; color:#c80000;\">The MD5 checksums of the original and downloaded files couldn\'t be checked. Please be car' + 'efull with this configuration file.</span>') else: if nas_md5 == '': text = ( 'The configuration file has been downloaded in the folder:<br> <b>' + folder + '</b><br>' + 'with the file name:<br> <b>' + filename + '</b>.<br><br><span style=\" font-weight:600' + '; color:#c80000;\">The MD5 checksum of the original file couldn\'t be checked. Please be carefull with this c' + 'onfiguration file.</span>') elif local_md5 == '': text = ( 'The configuration file has been downloaded in the folder:<br> <b>' + folder + '</b><br>' + 'with the file name:<br> <b>' + filename + '</b>.<br><br><span style=\" font-weight:600' + '; color:#c80000;\">The MD5 checksum of the downloaded file couldn\'t be checked. Please be carefull with this' + ' configuration file.</span>') else: text = ( 'The configuration file has been downloaded in the folder:<br> <b>' + folder + '</b><br>' + 'with the file name:<br> <b>' + filename + '</b>.<br><br><span style=\" font-weight:600; c' + 'olor:#c80000;\">The MD5 checksums of the original and downloaded files don\'t match. Please be carefull with thi' + 's configuration file, it can be corrupted.</span>' ) self.infoWindow = MyInfo(text) _, _, w, h = QtWidgets.QDesktopWidget().screenGeometry( -1).getRect() _, _, w2, h2 = self.infoWindow.geometry().getRect() self.infoWindow.setGeometry( w / 2 - w2 / 2, h / 2 - h2 / 2, 600, self.infoWindow.sizeHint().height()) self.infoWindow.setMinimumSize( QtCore.QSize(600, self.infoWindow.sizeHint().height())) self.infoWindow.setMaximumSize( QtCore.QSize(600, self.infoWindow.sizeHint().height())) self.infoWindow.exec_() def open_about(self): logging.debug('mainwindow.py - open_about') text = ( "The following software (v" + _backup_version + ") was developed by Olivier Henry, using Eclipse " + _eclipse_version + ", Python " + _py_version + " and PyQt " + _qt_version + ". It was designed to make a backup of the configuration file of XigmaNAS" + " using Python and scp commands.") self.aboutWindow = MyAbout(text) x1, y1, w1, h1 = self.geometry().getRect() _, _, w2, h2 = self.aboutWindow.geometry().getRect() x2 = x1 + w1 / 2 - w2 / 2 y2 = y1 + h1 / 2 - h2 / 2 self.aboutWindow.setGeometry(x2, y2, w2, h2) self.aboutWindow.setMinimumSize(QtCore.QSize(850, 450)) self.aboutWindow.setMaximumSize(QtCore.QSize(850, 450)) self.aboutWindow.exec_() def open_options(self): logging.debug('mainwindow.py - open_options') self.optionWindow = MyOptions(self.config_dict) x1, y1, w1, h1 = self.geometry().getRect() _, _, w2, h2 = self.optionWindow.geometry().getRect() x2 = x1 + w1 / 2 - w2 / 2 y2 = y1 + h1 / 2 - h2 / 2 self.optionWindow.setGeometry(x2, y2, w2, h2) self.optionWindow.exec_() if not self.optionWindow.cancel: self.config_dict = self.optionWindow.config_dict with open(os.path.join(self.config_path, 'xigmanas_backup.ini'), 'w') as config_file: self.config_dict.write(config_file) logging.getLogger().setLevel(self.config_dict.get('LOG', 'level')) self.check_downloader_update() self.populate_folder_target() def check_file_folder(self): logging.debug('mainwindow.py - check_file_folder') if not os.path.isdir(self.config_dict.get( 'CREDENTIALS', 'folder')) and self.config_dict.get( 'CREDENTIALS', 'folder'): logging.exception( 'mainwindow.py - check_file_folder - exception occured when the software checked the existence of the backup folder. ' + 'Please check that the folder exists. The folder option in the config file is going to be modified to the defa' + 'ult folder.') self.config_dict.set('CREDENTIALS', 'folder', '') with open(os.path.join(self.config_path, 'xigmanas_backup.ini'), 'w') as config_file: self.config_dict.write(config_file) text = ( 'The software has detected that the folder where XigmaNAS config files are saved doesn\'t exist anymore. It has been reseted in the config file' + ' to the default folder. Please check your options and set a new folder for backup.' ) self.infoWindow = MyInfo(text) _, _, w, h = QtWidgets.QDesktopWidget().screenGeometry( -1).getRect() _, _, w2, h2 = self.infoWindow.geometry().getRect() self.infoWindow.setGeometry(w / 2 - w2 / 2, h / 2 - h2 / 2, 450, self.infoWindow.sizeHint().height()) self.infoWindow.setMinimumSize( QtCore.QSize(450, self.infoWindow.sizeHint().height())) self.infoWindow.setMaximumSize( QtCore.QSize(450, self.infoWindow.sizeHint().height())) self.infoWindow.exec_() def check_downloader_update(self): logging.debug('mainwindow.py - check_downloader_update') self.actionUpdate.setEnabled(False) icon = QtGui.QIcon() icon.addPixmap(QtGui.QPixmap("icons/xigmanas_conf_backup_icon.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionUpdate.setIcon(icon) self.actionUpdate.setToolTip('') if self.config_dict['OPTIONS'].getboolean('check_update'): self.check_downloader = CheckXNASBackupOnline() self.check_downloader.start() self.check_downloader.finished.connect( self.parse_downloader_update) else: logging.info( 'mainwindow.py - check_downloader_update - from options, no update check' ) def parse_downloader_update(self, val): logging.debug('mainwindow.py - parse_downloader_update - val ' + str(val)) if val == 'no new version': self.actionUpdate.setEnabled(False) icon = QtGui.QIcon() icon.addPixmap( QtGui.QPixmap("icons/xigmanas_conf_backup_icon.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionUpdate.setIcon(icon) self.actionUpdate.setToolTip('No update available !') elif 'http' in val: self.actionUpdate.setEnabled(True) icon = QtGui.QIcon() icon.addPixmap( QtGui.QPixmap( "icons/xigmanas_conf_backup_update_available.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionUpdate.setIcon(icon) if getattr(sys, 'frozen', False): self.actionUpdate.setToolTip( 'A new update is available for XigmaNAS Conf Backup ! Click here to install it automatically.' ) else: self.actionUpdate.setToolTip( 'A new update is available for XigmaNAS Conf Backup ! Click here to download it.' ) self.link_latest_version = val def download_and_install_update(self): logging.debug( 'mainwindow.py - download_and_install_update - link_latest_version ' + str(self.link_latest_version)) if self.link_latest_version: frozen = False height = 250 if getattr(sys, 'frozen', False): frozen = True height = 200 self.updateWindow = MyWarningUpdate(frozen) x1, y1, w1, h1 = self.geometry().getRect() _, _, w2, h2 = self.updateWindow.geometry().getRect() x2 = x1 + w1 / 2 - w2 / 2 y2 = y1 + h1 / 2 - h2 / 2 self.updateWindow.setGeometry(x2, y2, w2, h2) self.updateWindow.setMinimumSize(QtCore.QSize(600, height)) self.updateWindow.setMaximumSize(QtCore.QSize(600, height)) self.updateWindow.exec_() try: if self.updateWindow.buttonName == 'update_button': if getattr(sys, 'frozen', False): temp_folder = tempfile.gettempdir() else: temp_folder = os.path.expanduser("~") + "/Downloads/" self.downloadWindow = MyUpdate(self.link_latest_version, temp_folder) x1, y1, w1, h1 = self.geometry().getRect() _, _, w2, h2 = self.downloadWindow.geometry().getRect() x2 = x1 + w1 / 2 - w2 / 2 y2 = y1 + h1 / 2 - h2 / 2 self.downloadWindow.setGeometry(x2, y2, w2, h2) self.downloadWindow.setMinimumSize( QtCore.QSize(500, self.downloadWindow.sizeHint().height())) self.downloadWindow.setMaximumSize( QtCore.QSize(500, self.downloadWindow.sizeHint().height())) self.downloadWindow.exec_() logging.debug( 'mainwindow.py - download_and_install_downloader_update - download finished' ) if not self.downloadWindow.cancel: if getattr(sys, 'frozen', False): filename = self.link_latest_version[ self.link_latest_version.rfind('/') + 1:] if platform.system() == 'Windows': os.startfile(temp_folder + '\\' + filename) time.sleep(0.1) self.close() elif platform.system() == 'Linux': shutil.copy('functions/unzip_update.py', temp_folder) install_folder = self.config_path + '/' command = 'python3 ' + temp_folder + '/unzip_update.py ' + temp_folder + '/' + filename + ' ' + install_folder os.system('x-terminal-emulator -e ' + command) time.sleep(0.1) self.close() else: time.sleep(0.1) self.close() except AttributeError: pass def closeEvent(self, event): logging.debug('mainwindow.py - closeEvent') logging.info('XigmaNAS Conf Backup ' + _backup_version + ' is closing ...') self.close()
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): def __init__(self, path, config_dict, parent=None): QtWidgets.QMainWindow.__init__(self, parent) logging.info('mainwindow.py - UI initialization ...') self.setupUi(self) self.config_dict = config_dict self.config_path = path object_init(self) info_button_text(self) dataset_data_information(self) itemDelegate = QtWidgets.QStyledItemDelegate() self.main_cb_1.setItemDelegate(itemDelegate) self.main_cb_2.setItemDelegate(itemDelegate) self.main_cb_3.setItemDelegate(itemDelegate) self.main_cb_4.setItemDelegate(itemDelegate) self.main_cb_5.setItemDelegate(itemDelegate) self.main_cb_6.setItemDelegate(itemDelegate) self.main_cb_7.setItemDelegate(itemDelegate) self.main_cb_8.setItemDelegate(itemDelegate) self.download_method.setItemDelegate(itemDelegate) for i in range(5): self.download_method.model().item(i + 1).setEnabled(False) self.downloadproduct.clicked.connect(lambda: self.download_product()) self.api_information() self.check_downloader_update() self.check_file_folder() self.prepare_datasets_database() self.main_cb_1.currentIndexChanged.connect( lambda: activate_type_cb(self)) self.product_info_button.clicked.connect(self.product_information) self.main_cb_6.currentIndexChanged.connect(self.set_modified) self.main_cb_7.currentIndexChanged.connect(self.set_modified) self.main_cb_8.currentIndexChanged.connect(self.set_modified) self.space_ln_north.textChanged.connect(self.set_modified) self.space_ln_south.textChanged.connect(self.set_modified) self.space_ln_west.textChanged.connect(self.set_modified) self.space_ln_east.textChanged.connect(self.set_modified) self.main_ln_1.textChanged.connect(self.set_modified) self.main_de_1.dateChanged.connect(self.set_modified) self.main_de_2.dateChanged.connect(self.set_modified) for button in self.info_button_list: button.clicked.connect(lambda: info_button(self)) self.make_window_title() logging.info('mainwindow.py - UI initialized ...') logging.info('*****************************************') @QtCore.pyqtSlot() def on_actionExit_triggered(self): self.close() @QtCore.pyqtSlot() def on_actionSave_triggered(self): self.save_document() @QtCore.pyqtSlot() def on_actionOpen_triggered(self): self.open_document() @QtCore.pyqtSlot() def on_actionExpert_triggered(self): self.open_expert_mode() @QtCore.pyqtSlot() def on_actionAbout_triggered(self): self.open_about() @QtCore.pyqtSlot() def on_actionOptions_triggered(self): self.open_options() @QtCore.pyqtSlot() def on_actionUpdate_triggered(self): self.download_and_install_update() def save_document(self): logging.debug('mainwindow.py - save_document') filename = self.get_file_name('save') if filename: save_xml_query(self, filename) def open_document(self): logging.debug('mainwindow.py - open_document') if self.modified: result = self.save_warning_window("Open") if result == "save_button": self.save_document() filename = self.get_file_name('open') if filename: open_xml_query(self, filename) elif result == "nosave_button": filename = self.get_file_name('open') if filename: open_xml_query(self, filename) else: filename = self.get_file_name('open') if filename: open_xml_query(self, filename) def open_expert_mode(self): logging.debug('mainwindow.py - open_expert_mode') self.expertWindow = MyExpert(self.info_button_text_dict) x1, y1, w1, h1 = self.geometry().getRect() _, _, w2, h2 = self.expertWindow.geometry().getRect() x2 = x1 + w1 / 2 - w2 / 2 y2 = y1 + h1 / 2 - h2 / 2 self.expertWindow.setGeometry(x2, y2, w2, h2) self.expertWindow.exec_() query, filename = self.expertWindow.query, self.expertWindow.filename action, suffix = self.expertWindow.action, self.expertWindow.suffix if query and filename and action and suffix: if suffix == 'FTP': self.download_product_ftp(query) else: self.launch_query(query, filename, action, suffix) def open_about(self): logging.debug('mainwindow.py - open_about') text = ( "The CMEMS Data Downloader v" + _downloader_version + " was developed by Olivier Henry" + ", using Eclipse " + _eclipse_version + ", Python " + _py_version + " and PyQt " + _qt_version + ". It was designed to help researchers to download data from CMEMS dif" + "ferent datasets by using the official CLS Motu API.") self.aboutWindow = MyAbout(text) x1, y1, w1, h1 = self.geometry().getRect() _, _, w2, h2 = self.aboutWindow.geometry().getRect() x2 = x1 + w1 / 2 - w2 / 2 y2 = y1 + h1 / 2 - h2 / 2 self.aboutWindow.setGeometry(x2, y2, w2, h2) self.aboutWindow.setMinimumSize(QtCore.QSize(850, 450)) self.aboutWindow.setMaximumSize(QtCore.QSize(850, 450)) self.aboutWindow.exec_() def open_options(self): logging.debug('mainwindow.py - open_options') self.optionWindow = MyOptions(self.config_dict, self.info_button_text_dict) x1, y1, w1, h1 = self.geometry().getRect() _, _, w2, h2 = self.optionWindow.geometry().getRect() x2 = x1 + w1 / 2 - w2 / 2 y2 = y1 + h1 / 2 - h2 / 2 self.optionWindow.setGeometry(x2, y2, w2, h2) self.optionWindow.exec_() if not self.optionWindow.cancel: self.config_dict = self.optionWindow.config_dict with open(os.path.join(self.config_path, 'cmems_downloader.ini'), 'w') as config_file: self.config_dict.write(config_file) logging.getLogger().setLevel(self.config_dict.get('LOG', 'level')) self.check_downloader_update() def api_information(self): logging.debug('mainwindow.py - api_information') if self.config_dict['OPTIONS'].getboolean('display_api_info'): self.apiWindow = MyApi() _, _, w, h = QtWidgets.QDesktopWidget().screenGeometry( -1).getRect() _, _, w2, h2 = self.apiWindow.geometry().getRect() self.apiWindow.setGeometry(w / 2 - w2 / 2, h / 2 - h2 / 2, w2, h2) self.apiWindow.setMinimumSize(QtCore.QSize(700, 550)) self.apiWindow.setMaximumSize(QtCore.QSize(700, 550)) self.apiWindow.exec_() if self.apiWindow.checkbox.isChecked(): if not self.config_dict['OPTIONS'].getboolean( 'display_api_info'): self.config_dict.set('OPTIONS', 'display_api_info', 'True') with open( os.path.join(self.config_path, 'cmems_downloader.ini'), 'w') as config_file: self.config_dict.write(config_file) else: if self.config_dict['OPTIONS'].getboolean('display_api_info'): self.config_dict.set('OPTIONS', 'display_api_info', 'False') with open( os.path.join(self.config_path, 'cmems_downloader.ini'), 'w') as config_file: self.config_dict.write(config_file) def check_file_folder(self): logging.debug('mainwindow.py - check_file_folder') if not os.path.isdir(self.config_dict.get( 'CREDENTIALS', 'folder')) and self.config_dict.get( 'CREDENTIALS', 'folder'): logging.exception( 'mainwindow.py - check_file_folder - exception occured when EDD checked the existence of the ECMWF file folder. ' + 'Please check that the folder exists. The folder option in the config file is going to be modified to the defa' + 'ult folder.') self.config_dict.set('CREDENTIALS', 'folder', '') with open(os.path.join(self.config_path, 'cmems_downloader.ini'), 'w') as config_file: self.config_dict.write(config_file) text = ( 'CDD has detected that the folder where ECMWF files are saved doesn\'t exist anymore. It has been reseted in the config file' + ' to the default folder. Please check your options and set a new folder for ECMWF files.' ) self.infoWindow = MyInfo(text) _, _, w, h = QtWidgets.QDesktopWidget().screenGeometry( -1).getRect() _, _, w2, h2 = self.infoWindow.geometry().getRect() self.infoWindow.setGeometry(w / 2 - w2 / 2, h / 2 - h2 / 2, 450, self.infoWindow.sizeHint().height()) self.infoWindow.setMinimumSize( QtCore.QSize(450, self.infoWindow.sizeHint().height())) self.infoWindow.setMaximumSize( QtCore.QSize(450, self.infoWindow.sizeHint().height())) self.infoWindow.exec_() def prepare_datasets_database(self): logging.debug('mainwindow.py - prepare_datasets_database') database_path = 'database/' file_nbr = 0 try: if os.path.isdir(database_path): self.product_database, self.dataset_database = {}, {} for file in os.listdir(database_path): if os.path.isfile( os.path.join(database_path, file) ) and file[ -4:] == '.dat' and file != 'PRODUCT_DATABASE.dat': domain, data_type, source, mode, product, short_description, description, resolution = None, None, None, None, None, None, None, None temporal_resolution, level, data_type, vertical, temporal, production, image, variables = None, None, None, None, None, None, None, None subset, swath, suffix, other_parameters = None, None, None, None name = file[:-4] f = open(database_path + file, 'r', encoding='utf-8') for line in f: if line[:3] != '###': index = line.find('=') parameter = line[:index] value = line[index + 1:].replace('\n', '') if parameter != 'version' and parameter != 'creation_date': if parameter == 'server_url': if value == 'None': server_url = None else: server_url = value if parameter == 'ftp_url': ftp_url = value if parameter == 'domain': domain = value if parameter == 'type': data_type = value if parameter == 'source': source = value if parameter == 'mode': mode = value if parameter == 'product': product = value if parameter == 'short_description': short_description = value if parameter == 'description': description = value if parameter == 'resolution': resolution = value if parameter == 'temporal_resolution': temporal_resolution = value if parameter == 'level': level = value if parameter == 'dataset_type': dataset_type = value if parameter == 'vertical': vertical = value if parameter == 'swath_vertical': swath_vertical_tmp = value if swath_vertical_tmp == 'None': swath_vertical = None else: swath_vertical = [] if '|' in swath_vertical_tmp: swath_vertical_tmp = swath_vertical_tmp.split( '|') for swath in swath_vertical_tmp: if 'to' in swath: index = swath.find( 'to') start = swath[: index].split( '/') end = swath[index + 2:].split( '/') swath_vertical.append( [start, end]) else: swath_vertical.append( [swath, swath]) else: index = swath_vertical_tmp.find( 'to') start = swath_vertical_tmp[: index].split( '/' ) end = swath_vertical_tmp[ index + 2:].split('/') swath_vertical.append( [start, end]) if parameter == 'temporal': temporal = value if parameter == 'production': production = value if parameter == 'image': image = value if parameter == 'variables': variables = value if variables == 'None': variables = None else: if '|' in variables: variables = variables.split( '|') for index, var in enumerate( variables): if ',' in var: var = var.split(',') else: var = [var] variables[index] = sorted( var) elif ',' in variables: variables = sorted( variables.split(',')) else: variables = [variables] if parameter == 'swath': swath = value if ',' in swath: swath = swath.split(',') if parameter == 'swath_temporal': swath_temporal = value if swath_temporal == 'None': swath_temporal = None else: if ',' in swath_temporal: swath_temporal = swath_temporal.split( ',') if parameter == 'swath_temporal_resolution': swath_temporal_resolution = value if swath_temporal_resolution == 'None': swath_temporal_resolution = None else: if ',' in swath_temporal_resolution: swath_temporal_resolution = swath_temporal_resolution.split( ',') if parameter == 'suffix': suffix = value if ',' in suffix: suffix = sorted(suffix.split(',')) else: suffix = [suffix] if parameter == 'other_parameters': if value != 'None': other_parameters = ast.literal_eval( value) else: other_parameters = None f.close() try: self.dataset_database[domain] except KeyError: self.dataset_database[domain] = {} try: self.dataset_database[domain][data_type] except KeyError: self.dataset_database[domain][data_type] = {} try: self.dataset_database[domain][data_type][source] except KeyError: self.dataset_database[domain][data_type][ source] = {} try: self.dataset_database[domain][data_type][source][ mode] except KeyError: self.dataset_database[domain][data_type][source][ mode] = [] self.dataset_database[domain][data_type][source][ mode].append(product) try: self.product_database[product] except KeyError: self.product_database[product] = {} self.product_database[product]['information'] = { 'short_description': short_description, 'description': description, 'spatial_resolution': resolution, 'temporal_resolution': temporal_resolution, 'level': level, 'product_type': dataset_type, 'vertical_coverage': vertical, 'temporal_coverage': temporal, 'production': production, 'image': image } self.product_database[product]['variables'] = variables self.product_database[product]['swath'] = swath self.product_database[product][ 'swath_temporal'] = swath_temporal self.product_database[product][ 'swath_temporal_resolution'] = swath_temporal_resolution self.product_database[product][ 'swath_vertical'] = swath_vertical self.product_database[product]['suffix'] = suffix self.product_database[product]['tree'] = [ domain, data_type, source, mode ] self.product_database[product][ 'server_url'] = server_url self.product_database[product]['ftp_url'] = ftp_url self.product_database[product][ 'other_parameters'] = other_parameters file_nbr += 1 domain_list = [] for key, _ in self.dataset_database.items(): domain_list.append(key) self.main_cb_1.clear() self.main_cb_1.addItem('Make a choice...') self.main_cb_1.addItems(sorted(domain_list)) logging.debug( 'mainwindow.py - prepare_datasets_database - database ready' ) logging.info('mainwindow.py - prepare_datasets_database - ' + str(file_nbr) + ' files have been read') except Exception: logging.exception( 'An exception occured during the reading of the .dat files') def product_information(self): logging.debug('mainwindow.py - product_information') if self.main_cb_5.currentText( ) != 'Make a choice...' and self.main_cb_5.currentText( ) != 'No product available...': self.productWindow = MyProduct( self.main_cb_5.currentText(), self.product_database[self.main_cb_5.currentText()]) x1, y1, w1, h1 = self.geometry().getRect() _, _, w2, h2 = self.productWindow.geometry().getRect() x2 = x1 + w1 / 2 - w2 / 2 y2 = y1 + h1 / 2 - h2 / 2 self.productWindow.setGeometry(x2, y2, w2, h2) self.productWindow.exec_() def download_product(self): if self.download_method.isEnabled(): if self.download_method.currentText() != 'Make a choice...': if 'FTP' in self.download_method.currentText(): self.download_product_ftp() else: if 'Check size' in self.download_method.currentText(): action = 'getSize' else: action = 'productdownload' if 'Query' in self.download_method.currentText(): suffix = '-TDS' elif 'Dataset' in self.download_method.currentText(): suffix = '-DGF' self.launch_query(action=action, suffix=suffix) def launch_query(self, query=None, filename=None, action=None, suffix=None): logging.info('mainwindow.py - launch_query') if query is None and filename is None: user = self.config_dict['CREDENTIALS'].get('user') password = self.config_dict['CREDENTIALS'].get('password') if not user or not password: self.credentialsyWindow = MyCredentials(user, password) x1, y1, w1, h1 = self.geometry().getRect() _, _, w2, h2 = self.credentialsyWindow.geometry().getRect() x2 = x1 + w1 / 2 - w2 / 2 y2 = y1 + h1 / 2 - h2 / 2 self.credentialsyWindow.setGeometry(x2, y2, w2, h2) self.credentialsyWindow.exec_() if self.credentialsyWindow.username and self.credentialsyWindow.password: user = self.credentialsyWindow.username password = self.credentialsyWindow.password if user and password: query, motu_url, folder, filename = self.prepare_query() query['service'] = query['service'] + suffix if suffix == '-DGF': try: del query['x_lo'] except KeyError: pass try: del query['x_hi'] except KeyError: pass try: del query['y_lo'] except KeyError: pass try: del query['y_hi'] except KeyError: pass try: del query['z_lo'] except KeyError: pass try: del query['z_hi'] except KeyError: pass try: del query['variable'] except KeyError: pass query['action'] = action self.queryWindow = MyQuery(query, motu_url, user, password, folder, filename) x1, y1, w1, h1 = self.geometry().getRect() _, _, w2, h2 = self.queryWindow.geometry().getRect() x2 = x1 + w1 / 2 - w2 / 2 y2 = y1 + h1 / 2 - h2 / 2 self.queryWindow.setGeometry(x2, y2, w2, h2) self.queryWindow.exec_() try: download_time = self.queryWindow.download_time file_path = self.queryWindow.file_path average_speed = self.queryWindow.average_speed self.successWindow = MySuccess(download_time, file_path, average_speed) x1, y1, w1, h1 = self.geometry().getRect() _, _, w2, h2 = self.successWindow.geometry().getRect() x2 = x1 + w1 / 2 - w2 / 2 y2 = y1 + h1 / 2 - h2 / 2 self.successWindow.setGeometry(x2, y2, w2, h2) self.successWindow.exec_() except AttributeError: pass else: user = self.config_dict['CREDENTIALS'].get('user') password = self.config_dict['CREDENTIALS'].get('password') if not user or not password: self.credentialsyWindow = MyCredentials(user, password) x1, y1, w1, h1 = self.geometry().getRect() _, _, w2, h2 = self.credentialsyWindow.geometry().getRect() x2 = x1 + w1 / 2 - w2 / 2 y2 = y1 + h1 / 2 - h2 / 2 self.credentialsyWindow.setGeometry(x2, y2, w2, h2) self.credentialsyWindow.exec_() if self.credentialsyWindow.username and self.credentialsyWindow.password: user = self.credentialsyWindow.username password = self.credentialsyWindow.password if user and password: folder = self.config_dict['CREDENTIALS'].get('folder') motu_url = query['url'] del query['url'] query['service'] = query['service'] + suffix if suffix == '-DGF': try: del query['x_lo'] except KeyError: pass try: del query['x_hi'] except KeyError: pass try: del query['y_lo'] except KeyError: pass try: del query['y_hi'] except KeyError: pass try: del query['z_lo'] except KeyError: pass try: del query['z_hi'] except KeyError: pass try: del query['variable'] except KeyError: pass query['action'] = action self.queryWindow = MyQuery(query, motu_url, user, password, folder, filename) x1, y1, w1, h1 = self.geometry().getRect() _, _, w2, h2 = self.queryWindow.geometry().getRect() x2 = x1 + w1 / 2 - w2 / 2 y2 = y1 + h1 / 2 - h2 / 2 self.queryWindow.setGeometry(x2, y2, w2, h2) self.queryWindow.exec_() try: download_time = self.queryWindow.download_time file_path = self.queryWindow.file_path average_speed = self.queryWindow.average_speed self.successWindow = MySuccess(download_time, file_path, average_speed) x1, y1, w1, h1 = self.geometry().getRect() _, _, w2, h2 = self.successWindow.geometry().getRect() x2 = x1 + w1 / 2 - w2 / 2 y2 = y1 + h1 / 2 - h2 / 2 self.successWindow.setGeometry(x2, y2, w2, h2) self.successWindow.exec_() except AttributeError: pass def download_product_ftp(self, query=None): user = self.config_dict['CREDENTIALS'].get('user') password = self.config_dict['CREDENTIALS'].get('password') if not user or not password: self.credentialsyWindow = MyCredentials(user, password) x1, y1, w1, h1 = self.geometry().getRect() _, _, w2, h2 = self.credentialsyWindow.geometry().getRect() x2 = x1 + w1 / 2 - w2 / 2 y2 = y1 + h1 / 2 - h2 / 2 self.credentialsyWindow.setGeometry(x2, y2, w2, h2) self.credentialsyWindow.exec_() if self.credentialsyWindow.username and self.credentialsyWindow.password: user = self.credentialsyWindow.username password = self.credentialsyWindow.password if user and password: folder = self.config_dict['CREDENTIALS'].get('folder') if query is None: product = str(self.main_cb_5.currentText()) dataset = str(self.main_cb_6.currentText()) ftp_url = self.product_database[product]['ftp_url'][6:] else: product = query['service'] dataset = query['product'] ftp_url = query['url'] self.ftpWindow = MyFTP(user, password, product, dataset, ftp_url, folder) self.ftpWindow.exec_() def check_downloader_update(self): logging.debug('mainwindow.py - check_downloader_update') self.actionUpdate.setEnabled(False) icon = QtGui.QIcon() icon.addPixmap(QtGui.QPixmap("icons/cmems_data_downloader_icon.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionUpdate.setIcon(icon) self.actionUpdate.setToolTip('') if self.config_dict['OPTIONS'].getboolean('check_update'): self.check_downloader = CheckCMEMSDownloaderOnline() self.check_downloader.start() self.check_downloader.finished.connect( self.parse_downloader_update) else: logging.info( 'mainwindow.py - check_downloader_update - from options, no update check' ) def parse_downloader_update(self, val): logging.debug('mainwindow.py - parse_downloader_update - val ' + str(val)) if val == 'no new version': if self.config_dict['OPTIONS'].getboolean('check_database'): self.check_database = CheckDatabaseVersion() self.check_database.start() self.check_database.finished.connect( self.parse_database_update) else: self.actionUpdate.setEnabled(False) icon = QtGui.QIcon() icon.addPixmap( QtGui.QPixmap("icons/cmems_data_downloader_icon.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionUpdate.setIcon(icon) self.actionUpdate.setToolTip('No update available !') elif 'http' in val: self.actionUpdate.setEnabled(True) icon = QtGui.QIcon() icon.addPixmap( QtGui.QPixmap("icons/cmems_data_downloader_update_icon.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionUpdate.setIcon(icon) if getattr(sys, 'frozen', False): self.actionUpdate.setToolTip( 'A new update is available for CMEMS Data Downloader ! Click here to install it automatically.' ) else: self.actionUpdate.setToolTip( 'A new update is available for CMEMS Data Downloader ! Click here to download it.' ) self.link_latest_version = val def download_and_install_update(self): logging.debug( 'mainwindow.py - download_and_install_update - link_latest_version ' + str(self.link_latest_version)) if self.link_latest_version: if isinstance(self.link_latest_version, dict): self.downloadWindow = MyDatabaseUpdate( self.link_latest_version) x1, y1, w1, h1 = self.geometry().getRect() _, _, w2, h2 = self.downloadWindow.geometry().getRect() x2 = x1 + w1 / 2 - w2 / 2 y2 = y1 + h1 / 2 - h2 / 2 self.downloadWindow.setGeometry(x2, y2, w2, h2) self.downloadWindow.setMinimumSize( QtCore.QSize(500, self.downloadWindow.sizeHint().height())) self.downloadWindow.setMaximumSize( QtCore.QSize(500, self.downloadWindow.sizeHint().height())) self.downloadWindow.exec_() if self.downloadWindow.done: self.prepare_datasets_database() self.actionUpdate.setEnabled(False) icon = QtGui.QIcon() icon.addPixmap( QtGui.QPixmap("icons/cmems_data_downloader_icon.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionUpdate.setIcon(icon) self.actionUpdate.setToolTip('') else: frozen = False height = 250 if getattr(sys, 'frozen', False): frozen = True height = 200 self.updateWindow = MyWarningUpdate(frozen) x1, y1, w1, h1 = self.geometry().getRect() _, _, w2, h2 = self.updateWindow.geometry().getRect() x2 = x1 + w1 / 2 - w2 / 2 y2 = y1 + h1 / 2 - h2 / 2 self.updateWindow.setGeometry(x2, y2, w2, h2) self.updateWindow.setMinimumSize(QtCore.QSize(600, height)) self.updateWindow.setMaximumSize(QtCore.QSize(600, height)) self.updateWindow.exec_() try: if self.updateWindow.buttonName == 'update_button': if getattr(sys, 'frozen', False): temp_folder = tempfile.gettempdir() else: temp_folder = os.path.expanduser( "~") + "/Downloads/" self.downloadWindow = MyUpdate( self.link_latest_version, temp_folder) x1, y1, w1, h1 = self.geometry().getRect() _, _, w2, h2 = self.downloadWindow.geometry().getRect() x2 = x1 + w1 / 2 - w2 / 2 y2 = y1 + h1 / 2 - h2 / 2 self.downloadWindow.setGeometry(x2, y2, w2, h2) self.downloadWindow.setMinimumSize( QtCore.QSize( 500, self.downloadWindow.sizeHint().height())) self.downloadWindow.setMaximumSize( QtCore.QSize( 500, self.downloadWindow.sizeHint().height())) self.downloadWindow.exec_() logging.debug( 'mainwindow.py - download_and_install_downloader_update - download finished' ) if not self.downloadWindow.cancel: if getattr(sys, 'frozen', False): filename = self.link_latest_version[ self.link_latest_version.rfind('/') + 1:] if platform.system() == 'Windows': os.startfile(temp_folder + '\\' + filename) time.sleep(0.1) self.close() elif platform.system() == 'Linux': shutil.copy('functions/unzip_update.py', temp_folder) install_folder = self.config_path + '/' command = 'python3 ' + temp_folder + '/unzip_update.py ' + temp_folder + '/' + filename + ' ' + install_folder os.system('x-terminal-emulator -e ' + command) time.sleep(0.1) self.close() else: time.sleep(0.1) self.close() except AttributeError: pass def parse_database_update(self, val): if val: self.actionUpdate.setEnabled(True) icon = QtGui.QIcon() icon.addPixmap( QtGui.QPixmap("icons/cmems_data_downloader_update_icon.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionUpdate.setIcon(icon) self.actionUpdate.setToolTip( 'New products are available for the product database. Click here to download them automatically.' ) self.link_latest_version = val def get_file_name(self, action): logging.debug('mainwindow.py - get_file_name') file_dialog = QtWidgets.QFileDialog() file_dialog.setDefaultSuffix('xml') if action == 'save': file_name, _ = file_dialog.getSaveFileName( self, 'Save XML File', '', filter='XML Files (*.xml)') elif action == 'open': file_name, _ = file_dialog.getOpenFileName( self, 'Open XML File', '', filter='XML Files (*.xml)') logging.debug('mainwindow.py - get_file_name - file_name ' + file_name) return file_name def set_modified(self): logging.debug('mainwindow.py - set_modified') if not self.modified: self.modified = True self.make_window_title() def make_window_title(self): logging.debug('mainwindow.py - make_window_title - self.modified ' + str(self.modified)) title_string = 'CMEMS Data Downloader v' + _downloader_version modified_string = '' if self.modified: modified_string = ' - modified' title_string = title_string + modified_string self.setWindowTitle(title_string) def save_warning_window(self, string): logging.debug('mainwindow.py - save_warning_window') self.presaveWindow = MyWarning(string) x1, y1, w1, h1 = self.geometry().getRect() _, _, w2, h2 = self.presaveWindow.geometry().getRect() x2 = x1 + w1 / 2 - w2 / 2 y2 = y1 + h1 / 2 - h2 / 2 self.presaveWindow.setGeometry(x2, y2, w2, h2) self.presaveWindow.setMinimumSize( QtCore.QSize(500, self.presaveWindow.sizeHint().height())) self.presaveWindow.setMaximumSize( QtCore.QSize(500, self.presaveWindow.sizeHint().height())) self.presaveWindow.exec_() return self.presaveWindow.buttonName def closeEvent(self, event): logging.debug('mainwindow.py - closeEvent - self.modified ' + str(self.modified)) if self.modified: result = self.save_warning_window("Close") if result == "save_button": self.save_document() logging.info('CMEMS Data Downloader ' + _downloader_version + ' is closing ...') self.close() elif result == "nosave_button": logging.info('CMEMS Data Downloader ' + _downloader_version + ' is closing ...') self.close() else: event.ignore() else: logging.info('CMEMS Data Downloader ' + _downloader_version + ' is closing ...') self.close() def prepare_query(self): logging.debug('mainwindow.py - prepare_query') query = {} motu_url, service, product, var, folder, filename, output = None, None, None, None, None, None, None lon_min, lon_max, lat_min, lat_max, date_min, date_max, depth_min, depth_max = None, None, None, None, None, None, None, None ### service service = str(self.main_cb_5.currentText()) ### product product = str(self.main_cb_6.currentText()) ### url motu_url = self.product_database[ self.main_cb_5.currentText()]['server_url'] ### longitude and latitude if self.space_ln_north.isEnabled(): if self.space_ln_north.text(): lat_max = self.space_ln_north.text() if self.space_ln_south.text(): lat_min = self.space_ln_south.text() if self.space_ln_west.text(): lon_min = self.space_ln_west.text() if self.space_ln_east.text(): lon_max = self.space_ln_east.text() ### depth if self.main_cb_7.isEnabled(): if self.main_cb_7.currentText( ) != 'Make a choice...' and self.main_cb_8.currentText( ) != 'Make a choice...': depth_min, depth_max = self.main_cb_7.currentText( ), self.main_cb_8.currentText() ### date date_min = self.main_de_1.date().toString(QtCore.Qt.ISODate) date_max = self.main_de_2.date().toString(QtCore.Qt.ISODate) # filename and folder if self.main_ln_1.text(): filename = str(self.main_ln_1.text()) else: now = datetime.datetime.now() y = str(now.year) m = str(now.month) d = str(now.day) h = str(now.hour) mn = str(now.minute) s = str(now.second) filename = 'query_' + y + '-' + m + '-' + d + 'T' + h + '-' + mn + '-' + s folder = self.config_dict['CREDENTIALS'].get('folder') # variables var_tmp = [] var_names = {v: k for k, v in self.variables_name.items()} checked_count = 0 if self.variables_cb: for cb in self.variables_cb: if cb.isChecked(): checked_count += 1 var_tmp.append(var_names[cb.text()[:cb.text().find('(') - 1]]) if var_tmp: if len(self.variables_cb) != checked_count: var = var_tmp # prepare dictionary parameter_list = [ service, product, lon_min, lon_max, lat_min, lat_max, date_min, date_max, depth_min, depth_max, var, output ] name_list = [ 'service', 'product', 'x_lo', 'x_hi', 'y_lo', 'y_hi', 't_lo', 't_hi', 'z_lo', 'z_hi', 'variable', 'output' ] for index, parameter in enumerate(parameter_list): if parameter != None: query[name_list[index]] = parameter query['scriptVersion'] = '1.5.00' query['mode'] = 'status' logging.debug('mainwindow.py - prepare_query - query ready: ' + str(query)) return query, motu_url, folder, filename
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow): def __init__(self, path, config_dict, parent=None): QtWidgets.QMainWindow.__init__(self, parent) self.config_dict = config_dict self.config_path = path logging.info('mainwindow.py - UI initialization ...') self.setupUi(self) object_init(self) info_button_text(self) dataset_data_information(self) hide_area_map(self) self.area_rb_1.setChecked(True) itemDelegate = QtWidgets.QStyledItemDelegate() self.area_cb_1.setItemDelegate(itemDelegate) self.area_cb_2.setItemDelegate(itemDelegate) self.period_cb_1.setItemDelegate(itemDelegate) for widget in self.dataset_gb_1.buttons(): widget.toggled.connect(lambda: populate_fields(self)) widget.toggled.connect(lambda: clean_stylesheet_dataset(self)) for widget in self.time_bg_1.buttons(): widget.toggled.connect(lambda: clean_stylesheet_time(self)) widget.toggled.connect(self.set_modified) for widget in self.step_bg_1.buttons(): widget.toggled.connect(lambda: clean_stylesheet_step(self)) widget.toggled.connect(self.set_modified) for widget in self.period_bg_1.buttons(): widget.toggled.connect(lambda: activate_period_elements(self)) widget.toggled.connect(lambda: clean_stylesheet_period(self)) widget.toggled.connect(self.set_modified) for widget in self.file_bg_1.buttons(): widget.toggled.connect(self.set_modified) for widget in self.info_buttons_list: widget.clicked.connect(lambda: info_button(self)) self.area_cb_1.currentIndexChanged.connect( lambda: set_visibility_area_map(self)) self.area_cb_1.currentIndexChanged.connect(self.set_modified) self.area_cb_2.currentIndexChanged.connect(self.set_modified) self.area_ln_5.textChanged.connect(self.set_modified) self.time_de_1.dateChanged.connect(self.set_modified) self.time_de_2.dateChanged.connect(self.set_modified) self.period_cb_1.currentIndexChanged.connect( lambda: populate_period_elements(self)) self.period_cb_1.currentIndexChanged.connect(self.set_modified) self.download_bt_1.clicked.connect(self.check_tabs_for_download) self.check_downloader_update() self.make_window_title() logging.info('mainwindow.py - UI initialized ...') logging.info('*****************************************') self.api_information() self.check_file_folder() @QtCore.pyqtSlot() def on_actionExit_triggered(self): self.close() @QtCore.pyqtSlot() def on_actionSave_triggered(self): self.save_document() @QtCore.pyqtSlot() def on_actionOpen_triggered(self): self.open_document() @QtCore.pyqtSlot() def on_actionExpert_triggered(self): self.open_expert_mode() @QtCore.pyqtSlot() def on_actionAbout_triggered(self): self.open_about() @QtCore.pyqtSlot() def on_actionOptions_triggered(self): self.open_options() @QtCore.pyqtSlot() def on_actionUpdate_triggered(self): self.download_and_install_downloader_update() def api_information(self): logging.debug('mainwindow.py - api_information') if self.config_dict['OPTIONS'].getboolean('display_api_info'): self.apiWindow = MyApi() _, _, w, h = QtWidgets.QDesktopWidget().screenGeometry( -1).getRect() _, _, w2, h2 = self.apiWindow.geometry().getRect() self.apiWindow.setGeometry(w / 2 - w2 / 2, h / 2 - h2 / 2, w2, h2) self.apiWindow.setMinimumSize(QtCore.QSize(700, 500)) self.apiWindow.setMaximumSize(QtCore.QSize(700, 500)) self.apiWindow.exec_() if self.apiWindow.checkbox.isChecked(): if not self.config_dict['OPTIONS'].getboolean( 'display_api_info'): self.config_dict.set('OPTIONS', 'display_api_info', 'True') with open( os.path.join(self.config_path, 'ecmwf_downloader.ini'), 'w') as config_file: self.config_dict.write(config_file) else: if self.config_dict['OPTIONS'].getboolean('display_api_info'): self.config_dict.set('OPTIONS', 'display_api_info', 'False') with open( os.path.join(self.config_path, 'ecmwf_downloader.ini'), 'w') as config_file: self.config_dict.write(config_file) def check_file_folder(self): logging.debug('mainwindow.py - check_file_folder') if not os.path.isdir(self.config_dict.get( 'CREDENTIALS', 'folder')) and self.config_dict.get( 'CREDENTIALS', 'folder'): logging.exception( 'mainwindow.py - check_file_folder - exception occured when EDD checked the existence of the ECMWF file folder. ' + 'Please check that the folder exists. The folder option in the config file is going to be modified to the defa' + 'ult folder.') self.config_dict.set('CREDENTIALS', 'folder', '') with open(os.path.join(self.config_path, 'ecmwf_downloader.ini'), 'w') as config_file: self.config_dict.write(config_file) text = ( 'EDD has detected that the folder where ECMWF files are saved doesn\'t exist anymore. It has been reseted in the config file' + ' to the default folder. Please check your options and set a new folder for ECMWF files.' ) self.infoWindow = MyInfo(text) _, _, w, h = QtWidgets.QDesktopWidget().screenGeometry( -1).getRect() _, _, w2, h2 = self.infoWindow.geometry().getRect() self.infoWindow.setGeometry(w / 2 - w2 / 2, h / 2 - h2 / 2, 450, self.infoWindow.sizeHint().height()) self.infoWindow.setMinimumSize( QtCore.QSize(450, self.infoWindow.sizeHint().height())) self.infoWindow.setMaximumSize( QtCore.QSize(450, self.infoWindow.sizeHint().height())) self.infoWindow.exec_() def open_about(self): logging.debug('mainwindow.py - open_about') text = ( "The ECMWF Data Downloader v" + _downloader_version + " was developed by Olivier Henry" + ", using Eclipse " + _eclipse_version + ", Python " + _py_version + " and PyQt " + _qt_version + ". It was designed to help researchers to download data from ECMWF dif" + "ferent projects by using the official ECMWF web API.") self.aboutWindow = MyAbout(text) x1, y1, w1, h1 = self.geometry().getRect() _, _, w2, h2 = self.aboutWindow.geometry().getRect() x2 = x1 + w1 / 2 - w2 / 2 y2 = y1 + h1 / 2 - h2 / 2 self.aboutWindow.setGeometry(x2, y2, w2, h2) self.aboutWindow.setMinimumSize(QtCore.QSize(850, 450)) self.aboutWindow.setMaximumSize(QtCore.QSize(850, 450)) self.aboutWindow.exec_() def open_options(self): logging.debug('mainwindow.py - open_options') self.optionWindow = MyOptions(self.config_dict, self.info_button_text_dict) x1, y1, w1, h1 = self.geometry().getRect() _, _, w2, h2 = self.optionWindow.geometry().getRect() x2 = x1 + w1 / 2 - w2 / 2 y2 = y1 + h1 / 2 - h2 / 2 self.optionWindow.setGeometry(x2, y2, w2, h2) self.optionWindow.exec_() if not self.optionWindow.cancel: self.config_dict = self.optionWindow.config_dict with open(os.path.join(self.config_path, 'ecmwf_downloader.ini'), 'w') as config_file: self.config_dict.write(config_file) logging.getLogger().setLevel(self.config_dict.get('LOG', 'level')) self.check_downloader_update() def save_document(self): logging.debug('mainwindow.py - save_document') filename = self.get_file_name('save') if filename: save_xml_query(self, filename) def open_document(self): logging.debug('mainwindow.py - open_document') if self.modified: result = self.save_warning_window("Open") if result == "save_button": self.save_document() filename = self.get_file_name('open') if filename: open_xml_query(self, filename) elif result == "nosave_button": filename = self.get_file_name('open') if filename: open_xml_query(self, filename) else: filename = self.get_file_name('open') if filename: open_xml_query(self, filename) def open_expert_mode(self): logging.debug('mainwindow.py - open_expert_mode') self.expertWindow = MyExpert(self.info_button_text_dict) x1, y1, w1, h1 = self.geometry().getRect() _, _, w2, h2 = self.expertWindow.geometry().getRect() x2 = x1 + w1 / 2 - w2 / 2 y2 = y1 + h1 / 2 - h2 / 2 self.expertWindow.setGeometry(x2, y2, w2, h2) self.expertWindow.exec_() query = self.expertWindow.query if query: self.download_ecmwf_data(query) def check_tabs_for_download(self): logging.debug('mainwindow.py - check_tabs_for_download') checking_passed = tabs_checking(self) if not checking_passed: self.selectionWindow = MySelect() x1, y1, w1, h1 = self.geometry().getRect() _, _, w2, h2 = self.selectionWindow.geometry().getRect() self.selectionWindow.setGeometry(x1 + w1 / 2 - w2 / 2, y1 + h1 / 2 - h2 / 2, w2, h2) self.selectionWindow.setMinimumSize( QtCore.QSize(500, self.selectionWindow.sizeHint().height())) self.selectionWindow.setMaximumSize( QtCore.QSize(500, self.selectionWindow.sizeHint().height())) self.selectionWindow.exec_() else: self.download_ecmwf_data() def download_ecmwf_data(self, query=None): logging.debug('mainwindow.py - download_ecmwf_data') if query == None: query = prepare_query(self) logging.debug('mainwindow.py - download_ecmwf_data - query ' + str(query)) self.queryWindow = MyQuery(query, self.config_dict) x1, y1, w1, h1 = self.geometry().getRect() _, _, w2, h2 = self.queryWindow.geometry().getRect() x2 = x1 + w1 / 2 - w2 / 2 y2 = y1 + h1 / 2 - h2 / 2 self.queryWindow.setGeometry(x2, y2, w2, h2) self.queryWindow.exec_() try: download_time = self.queryWindow.download_time file_path = self.queryWindow.file_path average_speed = self.queryWindow.average_speed self.successWindow = MySuccess(download_time, file_path, average_speed) x1, y1, w1, h1 = self.geometry().getRect() _, _, w2, h2 = self.successWindow.geometry().getRect() x2 = x1 + w1 / 2 - w2 / 2 y2 = y1 + h1 / 2 - h2 / 2 self.successWindow.setGeometry(x2, y2, w2, h2) self.successWindow.exec_() except AttributeError: pass def closeEvent(self, event): logging.debug('mainwindow.py - closeEvent - self.modified ' + str(self.modified)) if self.modified: result = self.save_warning_window("Close") if result == "save_button": self.save_document() logging.info('ECMWF Data Downloader ' + _downloader_version + ' is closing ...') self.close() elif result == "nosave_button": logging.info('ECMWF Data Downloader ' + _downloader_version + ' is closing ...') self.close() else: event.ignore() else: logging.info('ECMWF Data Downloader ' + _downloader_version + ' is closing ...') self.close() def make_window_title(self): logging.debug('mainwindow.py - make_window_title - self.modified ' + str(self.modified)) title_string = 'ECMWF Data Downloader v' + _downloader_version modified_string = '' if self.modified: modified_string = ' - modified' title_string = title_string + modified_string self.setWindowTitle(title_string) def set_modified(self): logging.debug('mainwindow.py - set_modified') if not self.modified: self.modified = True self.make_window_title() def check_downloader_update(self): logging.debug('mainwindow.py - check_downloader_update') if self.config_dict['OPTIONS'].getboolean('check_update'): self.check_downloader = CheckECMWFDownloaderOnline() self.check_downloader.start() self.check_downloader.finished.connect( self.parse_downloader_update) else: self.actionUpdate.setEnabled(False) icon = QtGui.QIcon() icon.addPixmap( QtGui.QPixmap("icons/downloader_update_off_icon.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionUpdate.setIcon(icon) self.actionUpdate.setToolTip('') logging.info( 'mainwindow.py - check_downloader_update - from options, no update check' ) def parse_downloader_update(self, val): logging.debug('mainwindow.py - parse_downloader_update - val ' + str(val)) if val == 'no new version': self.actionUpdate.setEnabled(False) icon = QtGui.QIcon() icon.addPixmap( QtGui.QPixmap("icons/downloader_update_off_icon.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionUpdate.setIcon(icon) self.actionUpdate.setToolTip('No update available !') elif 'http' in val: self.actionUpdate.setEnabled(True) icon = QtGui.QIcon() icon.addPixmap( QtGui.QPixmap("icons/downloader_update_on_icon.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionUpdate.setIcon(icon) if getattr(sys, 'frozen', False): self.actionUpdate.setToolTip( 'A new update is available for ECMWF Data Downloader ! Click here to install it automatically.' ) else: self.actionUpdate.setToolTip( 'A new update is available for ECMWF Data Downloader ! Click here to download it.' ) self.link_latest_version = val def download_and_install_downloader_update(self): logging.debug( 'mainwindow.py - download_and_install_downloader_update - link_latest_version ' + str(self.link_latest_version)) if self.link_latest_version: frozen = False height = 250 if getattr(sys, 'frozen', False): frozen = True height = 200 self.updateWindow = MyWarningUpdate(frozen) x1, y1, w1, h1 = self.geometry().getRect() _, _, w2, h2 = self.updateWindow.geometry().getRect() x2 = x1 + w1 / 2 - w2 / 2 y2 = y1 + h1 / 2 - h2 / 2 self.updateWindow.setGeometry(x2, y2, w2, h2) self.updateWindow.setMinimumSize(QtCore.QSize(600, height)) self.updateWindow.setMaximumSize(QtCore.QSize(600, height)) self.updateWindow.exec_() try: if self.updateWindow.buttonName == 'update_button': if getattr(sys, 'frozen', False): temp_folder = tempfile.gettempdir() else: temp_folder = os.path.expanduser("~") + "/Downloads/" self.downloadWindow = MyUpdate(self.link_latest_version, temp_folder) x1, y1, w1, h1 = self.geometry().getRect() _, _, w2, h2 = self.downloadWindow.geometry().getRect() x2 = x1 + w1 / 2 - w2 / 2 y2 = y1 + h1 / 2 - h2 / 2 self.downloadWindow.setGeometry(x2, y2, w2, h2) self.downloadWindow.setMinimumSize( QtCore.QSize(500, self.downloadWindow.sizeHint().height())) self.downloadWindow.setMaximumSize( QtCore.QSize(500, self.downloadWindow.sizeHint().height())) self.downloadWindow.exec_() logging.debug( 'mainwindow.py - download_and_install_downloader_update - download finished' ) if not self.downloadWindow.cancel: if getattr(sys, 'frozen', False): filename = self.link_latest_version[ self.link_latest_version.rfind('/') + 1:] if platform.system() == 'Windows': os.startfile(temp_folder + '\\' + filename) time.sleep(0.1) self.close() elif platform.system() == 'Linux': shutil.copy('functions/unzip_update.py', temp_folder) install_folder = self.config_path + '/test/' command = 'python3 ' + temp_folder + '/unzip_update.py ' + temp_folder + '/' + filename + ' ' + install_folder os.system('x-terminal-emulator -e ' + command) time.sleep(0.1) self.close() else: time.sleep(0.1) self.close() except AttributeError: pass def get_file_name(self, action): logging.debug('mainwindow.py - get_file_name') file_dialog = QtWidgets.QFileDialog() file_dialog.setDefaultSuffix('xml') if action == 'save': file_name, _ = file_dialog.getSaveFileName( self, 'Save XML File', '', filter='XML Files (*.xml)') elif action == 'open': file_name, _ = file_dialog.getOpenFileName( self, 'Open XML File', '', filter='XML Files (*.xml)') logging.debug('mainwindow.py - get_file_name - file_name ' + file_name) return file_name def save_warning_window(self, string): logging.debug('mainwindow.py - save_warning_window') self.presaveWindow = MyWarning(string) x1, y1, w1, h1 = self.geometry().getRect() _, _, w2, h2 = self.presaveWindow.geometry().getRect() x2 = x1 + w1 / 2 - w2 / 2 y2 = y1 + h1 / 2 - h2 / 2 self.presaveWindow.setGeometry(x2, y2, w2, h2) self.presaveWindow.setMinimumSize( QtCore.QSize(500, self.presaveWindow.sizeHint().height())) self.presaveWindow.setMaximumSize( QtCore.QSize(500, self.presaveWindow.sizeHint().height())) self.presaveWindow.exec_() return self.presaveWindow.buttonName