def send_error_message(error_type): """ Send a standard error message informing the user of an issue. :param error_type: The type of error that occurred for the issue. """ if error_type == "download": critical_error_message_box( translate("BiblesPlugin.HTTPBible", "Download Error"), translate( "BiblesPlugin.HTTPBible", "There was a problem downloading your verse selection. Please check " "your Internet connection, and if this error continues to occur please consider reporting a bug" ".", ), ) elif error_type == "parse": critical_error_message_box( translate("BiblesPlugin.HTTPBible", "Parse Error"), translate( "BiblesPlugin.HTTPBible", "There was a problem extracting your verse selection. If this error " "continues to occur please consider reporting a bug.", ), )
def accept(self): """ Override the QDialog's accept() method to do some validation before the dialog can be closed. """ if not self.first_name_edit.text(): critical_error_message_box( message=translate('SongsPlugin.AuthorsForm', 'You need to type in the first name of the author.')) self.first_name_edit.setFocus() return False elif not self.last_name_edit.text(): critical_error_message_box( message=translate('SongsPlugin.AuthorsForm', 'You need to type in the last name of the author.')) self.last_name_edit.setFocus() return False elif not self.display_edit.text(): if critical_error_message_box( message=translate('SongsPlugin.AuthorsForm', 'You have not set a display name for the author, combine the first and last names?'), parent=self, question=True) == QtWidgets.QMessageBox.Yes: self.display_edit.setText(self.first_name_edit.text() + ' ' + self.last_name_edit.text()) return QtWidgets.QDialog.accept(self) else: self.display_edit.setFocus() return False else: return QtWidgets.QDialog.accept(self)
def accept(self): """ Ok was triggered so lets save the data and run the report """ log.debug('accept') path = self.file_line_edit.text() if not path: self.main_window.error_message( translate('SongUsagePlugin.SongUsageDetailForm', 'Output Path Not Selected'), translate( 'SongUsagePlugin.SongUsageDetailForm', 'You have not set a valid output location for your' ' song usage report. \nPlease select an existing path on your computer.' )) return check_directory_exists(path) file_name = translate('SongUsagePlugin.SongUsageDetailForm', 'usage_detail_%s_%s.txt') % \ (self.from_date_calendar.selectedDate().toString('ddMMyyyy'), self.to_date_calendar.selectedDate().toString('ddMMyyyy')) Settings().setValue(self.plugin.settings_section + '/from date', self.from_date_calendar.selectedDate()) Settings().setValue(self.plugin.settings_section + '/to date', self.to_date_calendar.selectedDate()) usage = self.plugin.manager.get_all_objects( SongUsageItem, and_( SongUsageItem.usagedate >= self.from_date_calendar.selectedDate().toPyDate(), SongUsageItem.usagedate < self.to_date_calendar.selectedDate().toPyDate()), [SongUsageItem.usagedate, SongUsageItem.usagetime]) report_file_name = os.path.join(path, file_name) file_handle = None try: file_handle = open(report_file_name, 'wb') for instance in usage: record = '\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",' \ '\"%s\",\"%s\"\n' % \ (instance.usagedate, instance.usagetime, instance.title, instance.copyright, instance.ccl_number, instance.authors, instance.plugin_name, instance.source) file_handle.write(record.encode('utf-8')) self.main_window.information_message( translate('SongUsagePlugin.SongUsageDetailForm', 'Report Creation'), translate('SongUsagePlugin.SongUsageDetailForm', 'Report \n%s \nhas been successfully created. ') % report_file_name) except OSError as ose: log.exception('Failed to write out song usage records') critical_error_message_box( translate('SongUsagePlugin.SongUsageDetailForm', 'Report Creation Failed'), translate('SongUsagePlugin.SongUsageDetailForm', 'An error occurred while creating the report: %s') % ose.strerror) finally: if file_handle: file_handle.close() self.close()
def validateAndLoad(self, files): """ Process a list for files either from the File Dialog or from Drag and Drop ``files`` The files to be loaded. """ names = [] full_list = [] for count in range(self.listView.count()): names.append(self.listView.item(count).text()) full_list.append(self.listView.item(count).data(QtCore.Qt.UserRole)) duplicates_found = False files_added = False for file in files: filename = os.path.split(unicode(file))[1] if filename in names: duplicates_found = True else: files_added = True full_list.append(file) if full_list and files_added: self.listView.clear() self.loadList(full_list) last_dir = os.path.split(unicode(files[0]))[0] Settings().setValue(self.settingsSection + u'/last directory', last_dir) Settings().setValue(u'%s/%s files' % (self.settingsSection, self.settingsSection), self.getFileList()) if duplicates_found: critical_error_message_box(UiStrings().Duplicate, translate('OpenLP.MediaManagerItem', 'Duplicate files were found on import and were ignored.'))
def validateCurrentPage(self): """ Re-implement the validateCurrentPage() method. Validate the current page before moving on to the next page. Provide each song format class with a chance to validate its input by overriding is_valid_source(). """ if self.currentPage() == self.welcome_page: return True elif self.currentPage() == self.source_page: this_format = self.current_format Settings().setValue('songs/last import type', this_format) select_mode, class_, error_msg = SongFormat.get(this_format, 'selectMode', 'class', 'invalidSourceMsg') if select_mode == SongFormatSelect.MultipleFiles: import_source = self.get_list_of_files(self.format_widgets[this_format]['file_list_widget']) error_title = UiStrings().IFSp focus_button = self.format_widgets[this_format]['addButton'] else: import_source = self.format_widgets[this_format]['file_path_edit'].text() error_title = (UiStrings().IFSs if select_mode == SongFormatSelect.SingleFile else UiStrings().IFdSs) focus_button = self.format_widgets[this_format]['browseButton'] if not class_.is_valid_source(import_source): critical_error_message_box(error_title, error_msg) focus_button.setFocus() return False return True elif self.currentPage() == self.progress_page: return True
def on_web_update_button_clicked(self): """ Download list of bibles from Crosswalk, BibleServer and BibleGateway. """ # Download from Crosswalk, BiblesGateway, BibleServer self.web_bible_list = {} self.web_source_combo_box.setEnabled(False) self.web_translation_combo_box.setEnabled(False) self.web_update_button.setEnabled(False) self.web_progress_bar.setVisible(True) self.web_progress_bar.setValue(0) proxy_server = self.field('proxy_server') for (download_type, extractor) in ((WebDownload.Crosswalk, CWExtract(proxy_server)), (WebDownload.BibleGateway, BGExtract(proxy_server)), (WebDownload.Bibleserver, BSExtract(proxy_server))): try: bibles = extractor.get_bibles_from_http() except (urllib.error.URLError, ConnectionError) as err: critical_error_message_box(translate('BiblesPlugin.ImportWizardForm', 'Error during download'), translate('BiblesPlugin.ImportWizardForm', 'An error occurred while downloading the list of bibles from %s.')) bibles = None if bibles: self.web_bible_list[download_type] = {} for (bible_name, bible_key, language_code) in bibles: self.web_bible_list[download_type][bible_name] = (bible_key, language_code) self.web_progress_bar.setValue(download_type + 1) # Update combo box if something got into the list if self.web_bible_list: self.on_web_source_combo_box_index_changed(0) self.web_source_combo_box.setEnabled(True) self.web_translation_combo_box.setEnabled(True) self.web_update_button.setEnabled(True) self.web_progress_bar.setVisible(False)
def media_length(self, service_item): """ Loads and starts a media item to obtain the media length :param service_item: The ServiceItem containing the details to be played. """ media_info = MediaInfo() media_info.volume = 0 media_info.file_info = QtCore.QFileInfo(service_item.get_frame_path()) # display = controller.preview_display suffix = '*.%s' % media_info.file_info.suffix().lower() used_players = get_media_players()[0] player = self.media_players[used_players[0]] if suffix not in player.video_extensions_list and suffix not in player.audio_extensions_list: # Media could not be loaded correctly critical_error_message_box( translate('MediaPlugin.MediaItem', 'Unsupported Media File'), translate('MediaPlugin.MediaItem', 'File %s not supported using player %s') % (service_item.get_frame_path(), used_players[0])) return False media_data = MediaInfoWrapper.parse(service_item.get_frame_path()) # duration returns in milli seconds service_item.set_media_length(media_data.tracks[0].duration) return True
def on_topic_add_button_clicked(self): item = int(self.topicsComboBox.currentIndex()) text = self.topicsComboBox.currentText() if item == 0 and text: if QtGui.QMessageBox.question(self, translate('SongsPlugin.EditSongForm', 'Add Topic'), translate('SongsPlugin.EditSongForm', 'This topic does not exist, do you want to add it?'), QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.Yes) == QtGui.QMessageBox.Yes: topic = Topic.populate(name=text) self.manager.save_object(topic) topic_item = QtGui.QListWidgetItem(str(topic.name)) topic_item.setData(QtCore.Qt.UserRole, topic.id) self.topics_list_view.addItem(topic_item) self.load_topics() self.topicsComboBox.setCurrentIndex(0) else: return elif item > 0: item_id = (self.topicsComboBox.itemData(item)) topic = self.manager.get_object(Topic, item_id) if self.topics_list_view.findItems(str(topic.name), QtCore.Qt.MatchExactly): critical_error_message_box( message=translate('SongsPlugin.EditSongForm', 'This topic is already in the list.')) else: topic_item = QtGui.QListWidgetItem(str(topic.name)) topic_item.setData(QtCore.Qt.UserRole, topic.id) self.topics_list_view.addItem(topic_item) self.topicsComboBox.setCurrentIndex(0) else: QtGui.QMessageBox.warning(self, UiStrings().NISs, translate('SongsPlugin.EditSongForm', 'You have not selected a valid topic. Either select a topic ' 'from the list, or type in a new topic and click the "Add Topic to Song" button to add the new topic.'))
def accept(self): if not self.language_combo_box.currentText(): critical_error_message_box(message=translate('BiblesPlugin.LanguageForm', 'You need to choose a language.')) self.language_combo_box.setFocus() return False else: return QDialog.accept(self)
def on_replace_click(self): """ Called to replace Live background with the image selected. """ if check_item_selected( self.list_view, translate('ImagePlugin.MediaItem', 'You must select an image to replace the background with.')): background = QtGui.QColor(Settings().value(self.settings_section + '/background color')) bitem = self.list_view.selectedItems()[0] if not isinstance(bitem.data(0, QtCore.Qt.UserRole), ImageFilenames): # Only continue when an image is selected. return filename = bitem.data(0, QtCore.Qt.UserRole).filename if os.path.exists(filename): if self.live_controller.display.direct_image(filename, background): self.reset_action.setVisible(True) else: critical_error_message_box( UiStrings().LiveBGError, translate('ImagePlugin.MediaItem', 'There was no display item to amend.')) else: critical_error_message_box( UiStrings().LiveBGError, translate('ImagePlugin.MediaItem', 'There was a problem replacing your background, ' 'the image file "%s" no longer exists.') % filename)
def _validate_verse_list(self, verse_order, verse_count): verses = [] invalid_verses = [] verse_names = [] order_names = str(verse_order).split() order = self._extract_verse_order(verse_order) for index in range(verse_count): verse = self.verse_list_widget.item(index, 0) verse = verse.data(QtCore.Qt.UserRole) if verse not in verse_names: verses.append(verse) verse_names.append('%s%s' % (VerseType.translated_tag(verse[0]), verse[1:])) for count, item in enumerate(order): if item not in verses: invalid_verses.append(order_names[count]) if invalid_verses: valid = create_separated_list(verse_names) if len(invalid_verses) > 1: msg = translate('SongsPlugin.EditSongForm', 'There are no verses corresponding to "%(invalid)s".' 'Valid entries are %(valid)s.\nPlease enter the verses seperated by spaces.') \ % {'invalid' : ', '.join(invalid_verses), 'valid' : valid} else: msg = translate('SongsPlugin.EditSongForm', 'There is no verse corresponding to "%(invalid)s".' 'Valid entries are %(valid)s.\nPlease enter the verses seperated by spaces.') \ % {'invalid' : invalid_verses[0], 'valid' : valid} critical_error_message_box(title=translate('SongsPlugin.EditSongForm', 'Invalid Verse Order'), message=msg) return len(invalid_verses) == 0
def validateCurrentPage(self): """ Re-implement the validateCurrentPage() method. Validate the current page before moving on to the next page. Provide each song format class with a chance to validate its input by overriding is_valid_source(). """ if self.currentPage() == self.welcome_page: return True elif self.currentPage() == self.source_page: this_format = self.current_format self.settings.setValue('songs/last import type', this_format) select_mode, class_, error_msg = SongFormat.get(this_format, 'selectMode', 'class', 'invalidSourceMsg') if select_mode == SongFormatSelect.MultipleFiles: import_source = self.get_list_of_paths(self.format_widgets[this_format]['file_list_widget']) error_title = UiStrings().IFSp focus_button = self.format_widgets[this_format]['addButton'] else: import_source = self.format_widgets[this_format]['path_edit'].path error_title = (UiStrings().IFSs if select_mode == SongFormatSelect.SingleFile else UiStrings().IFdSs) focus_button = self.format_widgets[this_format]['path_edit'] if not class_.is_valid_source(import_source): critical_error_message_box(error_title, error_msg) focus_button.setFocus() return False return True elif self.currentPage() == self.progress_page: return True
def on_add_group_click(self): """ Called to add a new group """ # Find out if a group must be pre-selected preselect_group = 0 selected_items = self.list_view.selectedItems() if selected_items: selected_item = selected_items[0] if isinstance(selected_item.data(0, QtCore.Qt.UserRole), ImageFilenames): selected_item = selected_item.parent() if isinstance(selected_item, QtGui.QTreeWidgetItem): if isinstance(selected_item.data(0, QtCore.Qt.UserRole), ImageGroups): preselect_group = selected_item.data(0, QtCore.Qt.UserRole).id # Show 'add group' dialog if self.add_group_form.exec_(show_top_level_group=True, selected_group=preselect_group): new_group = ImageGroups.populate(parent_id=self.add_group_form.parent_group_combobox.itemData( self.add_group_form.parent_group_combobox.currentIndex(), QtCore.Qt.UserRole), group_name=self.add_group_form.name_edit.text()) if not self.check_group_exists(new_group): if self.manager.save_object(new_group): self.load_full_list(self.manager.get_all_objects( ImageFilenames, order_by_ref=ImageFilenames.filename)) self.expand_group(new_group.id) self.fill_groups_combobox(self.choose_group_form.group_combobox) self.fill_groups_combobox(self.add_group_form.parent_group_combobox) else: critical_error_message_box( message=translate('ImagePlugin.AddGroupForm', 'Could not add the new group.')) else: critical_error_message_box(message=translate('ImagePlugin.AddGroupForm', 'This group already exists.'))
def accept(self): """ Lets save the theme as Finish has been triggered """ # Save the theme name self.theme.theme_name = self.field('name') if not self.theme.theme_name: critical_error_message_box( translate('OpenLP.ThemeWizard', 'Theme Name Missing'), translate( 'OpenLP.ThemeWizard', 'There is no name for this theme. Please enter one.')) return if self.theme.theme_name == '-1' or self.theme.theme_name == 'None': critical_error_message_box( translate('OpenLP.ThemeWizard', 'Theme Name Invalid'), translate('OpenLP.ThemeWizard', 'Invalid theme name. Please enter one.')) return save_from = None save_to = None if self.theme.background_type == BackgroundType.to_string( BackgroundType.Image): filename = os.path.split(str(self.theme.background_filename))[1] save_to = os.path.join(self.path, self.theme.theme_name, filename) save_from = self.theme.background_filename if not self.edit_mode and not self.theme_manager.check_if_theme_exists( self.theme.theme_name): return self.theme_manager.save_theme(self.theme, save_from, save_to) return QtGui.QDialog.accept(self)
def on_edit_topic_button_clicked(self): """ Edit a topic. """ topic_id = self._get_current_item_id(self.topics_list_widget) if topic_id == -1: return topic = self.manager.get_object(Topic, topic_id) self.topic_form.name = topic.name # Save the topic's name for the case that he has to be restored. temp_name = topic.name if self.topic_form.exec(False): topic.name = self.topic_form.name_edit.text() if self.check_topic_exists(topic, True): if self.manager.save_object(topic): self.reset_topics() else: critical_error_message_box( message=translate('SongsPlugin.SongMaintenanceForm', 'Could not save your changes.')) elif critical_error_message_box( message=translate('SongsPlugin.SongMaintenanceForm', 'The topic {original} already exists. Would you like to make songs with ' 'topic {new} use the existing topic {original}?').format(original=topic.name, new=temp_name), parent=self, question=True) == QtWidgets.QMessageBox.Yes: self._merge_objects(topic, self.merge_topics, self.reset_topics) else: # We restore the topics's old name. topic.name = temp_name critical_error_message_box( message=translate('SongsPlugin.SongMaintenanceForm', 'Could not save your modified topic, because it already exists.'))
def accept(self): """ When the dialog succeeds, this is run """ start = self.hour_spin_box.value() * 3600 + self.minute_spin_box.value( ) * 60 + self.second_spin_box.value() end = self.hour_finish_spin_box.value() * 3600 + \ self.minute_finish_spin_box.value() * 60 + self.second_finish_spin_box.value() if end > self.item['service_item'].media_length: critical_error_message_box( title=translate('OpenLP.StartTime_form', 'Time Validation Error'), message=translate( 'OpenLP.StartTime_form', 'Finish time is set after the end of the media item')) return elif start > end: critical_error_message_box( title=translate('OpenLP.StartTime_form', 'Time Validation Error'), message=translate( 'OpenLP.StartTime_form', 'Start time is after the finish time of the media item')) return self.item['service_item'].start_time = start self.item['service_item'].end_time = end return QtWidgets.QDialog.accept(self)
def media_length(self, service_item): """ Loads and starts a media item to obtain the media length :param service_item: The ServiceItem containing the details to be played. """ controller = self.display_controllers[DisplayControllerType.Plugin] log.debug('media_length') # stop running videos self.media_reset(controller) controller.media_info = MediaInfo() controller.media_info.volume = 0 controller.media_info.file_info = QtCore.QFileInfo( service_item.get_frame_path()) display = controller.preview_display if not self._check_file_type(controller, display, service_item): # Media could not be loaded correctly critical_error_message_box( translate('MediaPlugin.MediaItem', 'Unsupported File'), translate('MediaPlugin.MediaItem', 'Unsupported File')) return False if not self.media_play(controller): critical_error_message_box( translate('MediaPlugin.MediaItem', 'Unsupported File'), translate('MediaPlugin.MediaItem', 'Unsupported File')) return False service_item.set_media_length(controller.media_info.length) self.media_stop(controller) log.debug('use %s controller' % self.current_media_players[controller.controller_type]) return True
def accept(self): """ Override the QDialog's accept() method to do some validation before the dialog can be closed. """ if not self.first_name_edit.text(): critical_error_message_box( message=translate('SongsPlugin.AuthorsForm', 'You need to type in the first name of the author.')) self.first_name_edit.setFocus() return False elif not self.last_name_edit.text(): critical_error_message_box( message=translate('SongsPlugin.AuthorsForm', 'You need to type in the last name of the author.')) self.last_name_edit.setFocus() return False elif not self.display_edit.text(): if critical_error_message_box( message=translate('SongsPlugin.AuthorsForm', 'You have not set a display name for the author, combine the first and last names?'), parent=self, question=True) == QtWidgets.QMessageBox.Yes: self.display_edit.setText(self.first_name_edit.text() + ' ' + self.last_name_edit.text()) return QtWidgets.QDialog.accept(self) else: self.display_edit.setFocus() return False else: return QtWidgets.QDialog.accept(self)
def accept(self): """ Lets save the theme as Finish has been triggered """ # Save the theme name self.theme.theme_name = self.field('name') if not self.theme.theme_name: critical_error_message_box( translate('OpenLP.ThemeWizard', 'Theme Name Missing'), translate( 'OpenLP.ThemeWizard', 'There is no name for this theme. Please enter one.')) return if self.theme.theme_name == '-1' or self.theme.theme_name == 'None': critical_error_message_box( translate('OpenLP.ThemeWizard', 'Theme Name Invalid'), translate('OpenLP.ThemeWizard', 'Invalid theme name. Please enter one.')) return source_path = None destination_path = None if self.theme.background_type == BackgroundType.to_string(BackgroundType.Image) or \ self.theme.background_type == BackgroundType.to_string(BackgroundType.Video): file_name = self.theme.background_filename.name destination_path = self.path / self.theme.theme_name / file_name source_path = self.theme.background_filename if not self.edit_mode and not self.theme_manager.check_if_theme_exists( self.theme.theme_name): return self.theme_manager.save_theme(self.theme, source_path, destination_path) return QtWidgets.QDialog.accept(self)
def accept(self): """ Lets save the theme as Finish has been triggered """ # Save the theme name self.theme.theme_name = self.field('name') if not self.theme.theme_name: critical_error_message_box( translate('OpenLP.ThemeWizard', 'Theme Name Missing'), translate('OpenLP.ThemeWizard', 'There is no name for this theme. Please enter one.')) return if self.theme.theme_name == '-1' or self.theme.theme_name == 'None': critical_error_message_box( translate('OpenLP.ThemeWizard', 'Theme Name Invalid'), translate('OpenLP.ThemeWizard', 'Invalid theme name. Please enter one.')) return save_from = None save_to = None if self.theme.background_type == BackgroundType.to_string(BackgroundType.Image) or \ self.theme.background_type == BackgroundType.to_string(BackgroundType.Video): filename = os.path.split(str(self.theme.background_filename))[1] save_to = os.path.join(self.path, self.theme.theme_name, filename) save_from = self.theme.background_filename if not self.edit_mode and not self.theme_manager.check_if_theme_exists(self.theme.theme_name): return self.theme_manager.save_theme(self.theme, save_from, save_to) return QtWidgets.QDialog.accept(self)
def _export_theme(self, path, theme): """ Create the zipfile with the theme contents. :param path: Location where the zip file will be placed :param theme: The name of the theme to be exported """ theme_path = os.path.join(path, theme + '.otz') theme_zip = None try: theme_zip = zipfile.ZipFile(theme_path, 'w') source = os.path.join(self.path, theme) for files in os.walk(source): for name in files[2]: theme_zip.write(os.path.join(source, name), os.path.join(theme, name)) theme_zip.close() return True except OSError as ose: self.log_exception('Export Theme Failed') critical_error_message_box( translate('OpenLP.ThemeManager', 'Theme Export Failed'), translate( 'OpenLP.ThemeManager', 'The theme export failed because this error ' 'occurred: %s') % ose.strerror) if theme_zip: theme_zip.close() shutil.rmtree(theme_path, True) return False
def validate_and_load(self, files, target_group=None): """ Process a list for files either from the File Dialog or from Drag and Drop :param files: The files to be loaded. :param target_group: The QTreeWidgetItem of the group that will be the parent of the added files """ names = [] full_list = [] for count in range(self.list_view.count()): names.append(self.list_view.item(count).text()) full_list.append(self.list_view.item(count).data(QtCore.Qt.UserRole)) duplicates_found = False files_added = False for file_path in files: if file_path in full_list: duplicates_found = True else: files_added = True full_list.append(file_path) if full_list and files_added: if target_group is None: self.list_view.clear() self.load_list(full_list, target_group) last_dir = os.path.split(files[0])[0] Settings().setValue(self.settings_section + '/last directory', last_dir) Settings().setValue('{section}/{section} files'.format(section=self.settings_section), self.get_file_list()) if duplicates_found: critical_error_message_box(UiStrings().Duplicate, translate('OpenLP.MediaManagerItem', 'Duplicate files were found on import and were ignored.'))
def on_edit_topic_button_clicked(self): """ Edit a topic. """ topic_id = self._get_current_item_id(self.topics_list_widget) if topic_id == -1: return topic = self.manager.get_object(Topic, topic_id) self.topic_form.name = topic.name # Save the topic's name for the case that he has to be restored. temp_name = topic.name if self.topic_form.exec_(False): topic.name = self.topic_form.name_edit.text() if self.check_topic_exists(topic, True): if self.manager.save_object(topic): self.reset_topics() else: critical_error_message_box( message=translate('SongsPlugin.SongMaintenanceForm', 'Could not save your changes.')) elif critical_error_message_box( message=translate('SongsPlugin.SongMaintenanceForm', 'The topic %s already exists. Would you like to make songs with topic %s use the ' 'existing topic %s?') % (topic.name, temp_name, topic.name), parent=self, question=True) == QtGui.QMessageBox.Yes: self._merge_objects(topic, self.merge_topics, self.reset_topics) else: # We restore the topics's old name. topic.name = temp_name critical_error_message_box( message=translate('SongsPlugin.SongMaintenanceForm', 'Could not save your modified topic, because it already exists.'))
def on_export_theme(self, field=None): """ Export the theme in a zip file :param field: """ item = self.theme_list_widget.currentItem() if item is None: critical_error_message_box(message=translate( 'OpenLP.ThemeManager', 'You have not selected a theme.')) return theme = item.data(QtCore.Qt.UserRole) path = QtWidgets.QFileDialog.getExistingDirectory( self, translate('OpenLP.ThemeManager', 'Save Theme - (%s)') % theme, Settings().value(self.settings_section + '/last directory export')) self.application.set_busy_cursor() if path: Settings().setValue( self.settings_section + '/last directory export', path) if self._export_theme(path, theme): QtWidgets.QMessageBox.information( self, translate('OpenLP.ThemeManager', 'Theme Exported'), translate('OpenLP.ThemeManager', 'Your theme has been successfully exported.')) self.application.set_normal_cursor()
def _perform_wizard(self): """ Run the tasks in the wizard. """ # Set plugin states self._increment_progress_bar(translate('OpenLP.FirstTimeWizard', 'Enabling selected plugins...')) self._set_plugin_status(self.songs_check_box, 'songs/status') self._set_plugin_status(self.bible_check_box, 'bibles/status') self._set_plugin_status(self.presentation_check_box, 'presentations/status') self._set_plugin_status(self.image_check_box, 'images/status') self._set_plugin_status(self.media_check_box, 'media/status') self._set_plugin_status(self.remote_check_box, 'remotes/status') self._set_plugin_status(self.custom_check_box, 'custom/status') self._set_plugin_status(self.song_usage_check_box, 'songusage/status') self._set_plugin_status(self.alert_check_box, 'alerts/status') if self.web_access: if not self._download_selected(): critical_error_message_box(translate('OpenLP.FirstTimeWizard', 'Download Error'), translate('OpenLP.FirstTimeWizard', 'There was a connection problem while ' 'downloading, so further downloads will be skipped. Try to re-run ' 'the First Time Wizard later.')) # Set Default Display if self.display_combo_box.currentIndex() != -1: Settings().setValue('core/monitor', self.display_combo_box.currentIndex()) self.screens.set_current_display(self.display_combo_box.currentIndex()) # Set Global Theme if self.theme_combo_box.currentIndex() != -1: Settings().setValue('themes/global theme', self.theme_combo_box.currentText())
def generate_slide_data(self, service_item, item=None, xml_version=False, remote=False, context=ServiceItemContext.Service): """ Generate the slide data. Needs to be implemented by the plugin. :param service_item: The service item to be built on :param item: The Song item to be used :param xml_version: The xml version (not used) :param remote: Triggered from remote :param context: Why is it being generated """ if item is None: item = self.list_view.currentItem() if item is None: return False filename = item.data(QtCore.Qt.UserRole) # Special handling if the filename is a optical clip if filename.startswith('optical:'): (name, title, audio_track, subtitle_track, start, end, clip_name) = parse_optical_path(filename) if not os.path.exists(name): if not remote: # Optical disc is no longer present critical_error_message_box( translate('MediaPlugin.MediaItem', 'Missing Media File'), translate('MediaPlugin.MediaItem', 'The optical disc %s is no longer available.') % name) return False service_item.processor = self.display_type_combo_box.currentText() service_item.add_from_command(filename, name, CLAPPERBOARD) service_item.title = clip_name # Set the length self.media_controller.media_setup_optical(name, title, audio_track, subtitle_track, start, end, None, None) service_item.set_media_length((end - start) / 1000) service_item.start_time = start / 1000 service_item.end_time = end / 1000 service_item.add_capability(ItemCapabilities.IsOptical) else: if not os.path.exists(filename): if not remote: # File is no longer present critical_error_message_box( translate('MediaPlugin.MediaItem', 'Missing Media File'), translate('MediaPlugin.MediaItem', 'The file %s no longer exists.') % filename) return False (path, name) = os.path.split(filename) service_item.title = name service_item.processor = self.display_type_combo_box.currentText() service_item.add_from_command(path, name, CLAPPERBOARD) # Only get start and end times if going to a service if context == ServiceItemContext.Service: # Start media and obtain the length if not self.media_controller.media_length(service_item): return False service_item.add_capability(ItemCapabilities.CanAutoStartForLive) service_item.add_capability(ItemCapabilities.CanEditTitle) service_item.add_capability(ItemCapabilities.RequiresMedia) if Settings().value(self.settings_section + '/media auto start') == QtCore.Qt.Checked: service_item.will_auto_start = True # force a non-existent theme service_item.theme = -1 return True
def _export_theme(self, theme_path, theme_name): """ Create the zipfile with the theme contents. :param Path theme_path: Location where the zip file will be placed :param str theme_name: The name of the theme to be exported :return: The success of creating the zip file :rtype: bool """ try: with zipfile.ZipFile(theme_path, 'w') as theme_zip: source_path = self.theme_path / theme_name for file_path in source_path.iterdir(): theme_zip.write(file_path, Path(theme_name, file_path.name)) return True except OSError as ose: self.log_exception('Export Theme Failed') critical_error_message_box( translate('OpenLP.ThemeManager', 'Theme Export Failed'), translate( 'OpenLP.ThemeManager', 'The {theme_name} export failed because this error occurred: {err}' ).format(theme_name=theme_name, err=ose.strerror)) if theme_path.exists(): shutil.rmtree(theme_path, ignore_errors=True) return False
def validate_xml_file(self, filename, tag): """ Validate the supplied file :param filename: The supplied file :param tag: The expected root tag type :return: True if valid. ValidationError is raised otherwise. """ if BibleImport.is_compressed(filename): raise ValidationError(msg='Compressed file') bible = self.parse_xml(filename, use_objectify=True) if bible is None: raise ValidationError(msg='Error when opening file') root_tag = bible.tag.lower() bible_type = translate( 'BiblesPlugin.BibleImport', 'unknown type of', 'This looks like an unknown type of XML bible.') if root_tag == tag: return True elif root_tag == 'bible': bible_type = "OpenSong" elif root_tag == '{http://www.bibletechnologies.net/2003/osis/namespace}osis': bible_type = 'OSIS' elif root_tag == 'xmlbible': bible_type = 'Zefania' critical_error_message_box(message=translate( 'BiblesPlugin.BibleImport', 'Incorrect Bible file type supplied. This looks like an {bible_type} XML bible.' .format(bible_type=bible_type))) raise ValidationError(msg='Invalid xml.')
def _validate_theme_action(self, select_text, confirm_title, confirm_text, test_plugin=True, confirm=True): """ Check to see if theme has been selected and the destructive action is allowed. :param select_text: Text for message box if no item selected. :param confirm_title: Confirm message title to be displayed. :param confirm_text: Confirm message text to be displayed. :param test_plugin: Do we check the plugins for theme usage. :param confirm: Do we display a confirm box before run checks. :return: True or False depending on the validity. """ self.global_theme = Settings().value(self.settings_section + '/global theme') if check_item_selected(self.theme_list_widget, select_text): item = self.theme_list_widget.currentItem() theme = item.text() # confirm deletion if confirm: answer = QtWidgets.QMessageBox.question( self, confirm_title, confirm_text.format(theme_name=theme), defaultButton=QtWidgets.QMessageBox.No) if answer == QtWidgets.QMessageBox.No: return False # should be the same unless default if theme != item.data(QtCore.Qt.UserRole): critical_error_message_box(message=translate( 'OpenLP.ThemeManager', 'You are unable to delete the default theme.')) return False # check for use in the system else where. if test_plugin: plugin_usage = "" for plugin in State().list_plugins(): used_count = plugin.uses_theme(theme) if used_count: plugin_usage = "{plug}{text}".format( plug=plugin_usage, text=(translate( 'OpenLP.ThemeManager', '{count} time(s) by {plugin}').format( name=used_count, plugin=plugin.name))) plugin_usage = "{text}\n".format(text=plugin_usage) if plugin_usage: critical_error_message_box( translate('OpenLP.ThemeManager', 'Unable to delete theme'), translate('OpenLP.ThemeManager', 'Theme is currently used \n\n{text}').format( text=plugin_usage)) return False return True return False
def on_export_theme(self, checked=None): """ Export the theme to a zip file :param bool checked: Sent by the QAction.triggered signal. It's not used in this method. :rtype: None """ item = self.theme_list_widget.currentItem() if item is None: critical_error_message_box(message=translate( 'OpenLP.ThemeManager', 'You have not selected a theme.')) return theme_name = item.data(QtCore.Qt.UserRole) export_path, filter_used = \ FileDialog.getSaveFileName(self.main_window, translate('OpenLP.ThemeManager', 'Save Theme - ({name})').format(name=theme_name), Settings().value(self.settings_section + '/last directory export'), translate('OpenLP.ThemeManager', 'OpenLP Themes (*.otz)'), translate('OpenLP.ThemeManager', 'OpenLP Themes (*.otz)')) self.application.set_busy_cursor() if export_path: Settings().setValue( self.settings_section + '/last directory export', export_path.parent) if self._export_theme(export_path.with_suffix('.otz'), theme_name): QtWidgets.QMessageBox.information( self, translate('OpenLP.ThemeManager', 'Theme Exported'), translate('OpenLP.ThemeManager', 'Your theme has been successfully exported.')) self.application.set_normal_cursor()
def generate_slide_data(self, service_item, item=None, xml_version=False, remote=False, context=ServiceItemContext.Live): """ Generate the slide data. Needs to be implemented by the plugin. """ if item is None: item = self.list_view.currentItem() if item is None: return False filename = item.data(QtCore.Qt.UserRole) if not os.path.exists(filename): if not remote: # File is no longer present critical_error_message_box( translate('MediaPlugin.MediaItem', 'Missing Media File'), translate('MediaPlugin.MediaItem', 'The file %s no longer exists.') % filename) return False (path, name) = os.path.split(filename) service_item.title = name service_item.processor = self.display_type_combo_box.currentText() service_item.add_from_command(path, name, CLAPPERBOARD) # Only get start and end times if going to a service if context == ServiceItemContext.Service: # Start media and obtain the length if not self.media_controller.media_length(service_item): return False service_item.add_capability(ItemCapabilities.CanAutoStartForLive) service_item.add_capability(ItemCapabilities.CanEditTitle) service_item.add_capability(ItemCapabilities.RequiresMedia) if Settings().value(self.settings_section + '/media auto start') == QtCore.Qt.Checked: service_item.will_auto_start = True # force a non-existent theme service_item.theme = -1 return True
def validateCurrentPage(self): """ Validate the current page before moving on to the next page. """ if self.currentPage() == self.welcome_page: return True elif self.currentPage() == self.available_songs_page: items = [ item for item in self._find_list_widget_items(self.available_list_widget) if item.checkState() ] if not items: critical_error_message_box( UiStrings().NISp, translate('SongsPlugin.ExportWizardForm', 'You need to add at least one Song to export.')) return False self.selected_list_widget.clear() # Add the songs to the list of selected songs. for item in items: song = QtGui.QListWidgetItem(item.text()) song.setData(QtCore.Qt.UserRole, item.data(QtCore.Qt.UserRole)) song.setFlags(QtCore.Qt.ItemIsEnabled) self.selected_list_widget.addItem(song) return True elif self.currentPage() == self.export_song_page: if not self.directory_line_edit.text(): critical_error_message_box( translate('SongsPlugin.ExportWizardForm', 'No Save Location specified'), translate('SongsPlugin.ExportWizardForm', 'You need to specify a directory.')) return False return True elif self.currentPage() == self.progress_page: self.available_list_widget.clear() self.selected_list_widget.clear() return True
def validate_and_load(self, file_paths, target_group=None): """ Process a list for files either from the File Dialog or from Drag and Drop :param list[openlp.core.common.path.Path] file_paths: The files to be loaded. :param target_group: The QTreeWidgetItem of the group that will be the parent of the added files """ full_list = [] for count in range(self.list_view.count()): full_list.append( self.list_view.item(count).data(QtCore.Qt.UserRole)) duplicates_found = False files_added = False for file_path in file_paths: if path_to_str(file_path) in full_list: duplicates_found = True else: files_added = True full_list.append(path_to_str(file_path)) if full_list and files_added: if target_group is None: self.list_view.clear() self.load_list(full_list, target_group) Settings().setValue(self.settings_section + '/last directory', file_paths[0].parent) Settings().setValue( '{section}/{section} files'.format( section=self.settings_section), self.get_file_list()) if duplicates_found: critical_error_message_box( UiStrings().Duplicate, translate( 'OpenLP.MediaManagerItem', 'Duplicate files were found on import and were ignored.'))
def load_file(self, data): """ Turn file from Drag and Drop into an array so the Validate code can run it. :param data: A dictionary containing the list of files to be loaded and the target """ new_file_paths = [] error_shown = False for file_path in data['file_paths']: if file_path.suffix[1:].lower() not in self.on_new_file_masks: if not error_shown: critical_error_message_box( translate('OpenLP.MediaManagerItem', 'Invalid File Type'), translate( 'OpenLP.MediaManagerItem', 'Invalid File {file_path}.\nFile extension not supported' ).format(file_path=file_path)) error_shown = True else: new_file_paths.append(file_path) if new_file_paths: if 'target' in data: self.validate_and_load(new_file_paths, data['target']) self.validate_and_load(new_file_paths)
def on_edit_book_button_clicked(self): """ Edit a book. """ book_id = self._get_current_item_id(self.song_books_list_widget) if book_id == -1: return book = self.manager.get_object(Book, book_id) if book.publisher is None: book.publisher = '' self.song_book_form.name_edit.setText(book.name) self.song_book_form.publisher_edit.setText(book.publisher) # Save the book's name and publisher for the case that they have to # be restored. temp_name = book.name temp_publisher = book.publisher if self.song_book_form.exec_(False): book.name = self.song_book_form.name_edit.text() book.publisher = self.song_book_form.publisher_edit.text() if self.check_song_book_exists(book, True): if self.manager.save_object(book): self.reset_song_books() else: critical_error_message_box( message=translate('SongsPlugin.SongMaintenanceForm', 'Could not save your changes.')) elif critical_error_message_box( message=translate('SongsPlugin.SongMaintenanceForm', 'The book %s already exists. Would you like to make ' 'songs with book %s use the existing book %s?') % (book.name, temp_name, book.name), parent=self, question=True) == QtGui.QMessageBox.Yes: self._merge_objects(book, self.merge_song_books, self.reset_song_books) else: # We restore the book's old name and publisher. book.name = temp_name book.publisher = temp_publisher
def validateCurrentPage(self): """ Validate the current page before moving on to the next page. """ if self.currentPage() == self.welcome_page: return True elif self.currentPage() == self.available_songs_page: items = [ item for item in find_list_widget_items(self.available_list_widget) if item.checkState() ] if not items: critical_error_message_box( UiStrings().NISp, translate('SongsPlugin.ExportWizardForm', 'You need to add at least one Song to export.')) return False self.selected_list_widget.clear() # Add the songs to the list of selected songs. for item in items: song = QtWidgets.QListWidgetItem(item.text()) song.setData(QtCore.Qt.UserRole, item.data(QtCore.Qt.UserRole)) song.setFlags(QtCore.Qt.ItemIsEnabled) self.selected_list_widget.addItem(song) return True elif self.currentPage() == self.export_song_page: if not self.directory_line_edit.text(): critical_error_message_box( translate('SongsPlugin.ExportWizardForm', 'No Save Location specified'), translate('SongsPlugin.ExportWizardForm', 'You need to specify a directory.')) return False return True elif self.currentPage() == self.progress_page: self.available_list_widget.clear() self.selected_list_widget.clear() return True
def media_length(self, service_item): """ Loads and starts a media item to obtain the media length :param service_item: The ServiceItem containing the details to be played. """ controller = self.display_controllers[DisplayControllerType.Plugin] log.debug('media_length') # stop running videos self.media_reset(controller) controller.media_info = MediaInfo() controller.media_info.volume = 0 controller.media_info.file_info = QtCore.QFileInfo(service_item.get_frame_path()) display = controller.preview_display if not self._check_file_type(controller, display, service_item): # Media could not be loaded correctly critical_error_message_box(translate('MediaPlugin.MediaItem', 'Unsupported File'), translate('MediaPlugin.MediaItem', 'Unsupported File')) return False if not self.media_play(controller): critical_error_message_box(translate('MediaPlugin.MediaItem', 'Unsupported File'), translate('MediaPlugin.MediaItem', 'Unsupported File')) return False service_item.set_media_length(controller.media_info.length) self.media_stop(controller) log.debug('use %s controller' % self.current_media_players[controller.controller_type]) return True
def parse_xml(self, filename, use_objectify=False, elements=None, tags=None): """ Parse and clean the supplied file by removing any elements or tags we don't use. :param filename: The filename of the xml file to parse. Str :param use_objectify: Use the objectify parser rather than the etree parser. (Bool) :param elements: A tuple of element names (Str) to remove along with their content. :param tags: A tuple of element names (Str) to remove, preserving their content. :return: The root element of the xml document """ try: with open(filename, 'rb') as import_file: # NOTE: We don't need to do any of the normal encoding detection here, because lxml does it's own # encoding detection, and the two mechanisms together interfere with each other. if not use_objectify: tree = etree.parse(import_file, parser=etree.XMLParser(recover=True)) else: tree = objectify.parse(import_file, parser=objectify.makeparser(recover=True)) if elements or tags: self.wizard.increment_progress_bar( translate('BiblesPlugin.OsisImport', 'Removing unused tags (this may take a few minutes)...')) if elements: # Strip tags we don't use - remove content etree.strip_elements(tree, elements, with_tail=False) if tags: # Strip tags we don't use - keep content etree.strip_tags(tree, tags) return tree.getroot() except OSError as e: self.log_exception('Opening {file_name} failed.'.format(file_name=e.filename)) critical_error_message_box( title='An Error Occured When Opening A File', message='The following error occurred when trying to open\n{file_name}:\n\n{error}' .format(file_name=e.filename, error=e.strerror)) return None
def on_replace_click(self): """ Called to replace Live background with the media selected. """ if check_item_selected(self.list_view, translate('MediaPlugin.MediaItem', 'You must select a media file to replace the background with.')): item = self.list_view.currentItem() filename = item.data(QtCore.Qt.UserRole) if os.path.exists(filename): service_item = ServiceItem() service_item.title = 'webkit' service_item.processor = 'webkit' (path, name) = os.path.split(filename) service_item.add_from_command(path, name, CLAPPERBOARD) if self.media_controller.video(DisplayControllerType.Live, service_item, video_behind_text=True): self.reset_action.setVisible(True) else: critical_error_message_box(UiStrings().LiveBGError, translate('MediaPlugin.MediaItem', 'There was no display item to amend.')) else: critical_error_message_box(UiStrings().LiveBGError, translate('MediaPlugin.MediaItem', 'There was a problem replacing your background, ' 'the media file "%s" no longer exists.') % filename)
def validate_xml_file(self, filename, tag): """ Validate the supplied file :param filename: The supplied file :param tag: The expected root tag type :return: True if valid. ValidationError is raised otherwise. """ if BibleImport.is_compressed(filename): raise ValidationError(msg='Compressed file') bible = self.parse_xml(filename, use_objectify=True) if bible is None: raise ValidationError(msg='Error when opening file') root_tag = bible.tag.lower() bible_type = translate('BiblesPlugin.BibleImport', 'unknown type of', 'This looks like an unknown type of XML bible.') if root_tag == tag: return True elif root_tag == 'bible': bible_type = "OpenSong" elif root_tag == '{http://www.bibletechnologies.net/2003/osis/namespace}osis': bible_type = 'OSIS' elif root_tag == 'xmlbible': bible_type = 'Zefania' critical_error_message_box( message=translate('BiblesPlugin.BibleImport', 'Incorrect Bible file type supplied. This looks like an {bible_type} XML bible.' .format(bible_type=bible_type))) raise ValidationError(msg='Invalid xml.')
def on_replace_click(self): """ Called to replace Live background with the image selected. """ if check_item_selected( self.list_view, translate( 'ImagePlugin.MediaItem', 'You must select an image to replace the background with.') ): background = QtGui.QColor(Settings().value(self.settings_section + '/background color')) bitem = self.list_view.selectedItems()[0] if not isinstance(bitem.data(0, QtCore.Qt.UserRole), ImageFilenames): # Only continue when an image is selected. return filename = bitem.data(0, QtCore.Qt.UserRole).filename if os.path.exists(filename): if self.live_controller.display.direct_image( filename, background): self.reset_action.setVisible(True) else: critical_error_message_box( UiStrings().LiveBGError, translate('ImagePlugin.MediaItem', 'There was no display item to amend.')) else: critical_error_message_box( UiStrings().LiveBGError, translate( 'ImagePlugin.MediaItem', 'There was a problem replacing your background, ' 'the image file "%s" no longer exists.') % filename)
def _perform_wizard(self): """ Run the tasks in the wizard. """ # Set plugin states self._increment_progress_bar(translate('OpenLP.FirstTimeWizard', 'Enabling selected plugins...')) self._set_plugin_status(self.songs_check_box, 'songs/status') self._set_plugin_status(self.bible_check_box, 'bibles/status') self._set_plugin_status(self.presentation_check_box, 'presentations/status') self._set_plugin_status(self.image_check_box, 'images/status') self._set_plugin_status(self.media_check_box, 'media/status') self._set_plugin_status(self.remote_check_box, 'remotes/status') self._set_plugin_status(self.custom_check_box, 'custom/status') self._set_plugin_status(self.song_usage_check_box, 'songusage/status') self._set_plugin_status(self.alert_check_box, 'alerts/status') if self.web_access: if not self._download_selected(): critical_error_message_box(translate('OpenLP.FirstTimeWizard', 'Download Error'), translate('OpenLP.FirstTimeWizard', 'There was a connection problem while ' 'downloading, so further downloads will be skipped. Try to re-run ' 'the First Time Wizard later.')) # Set Default Display if self.display_combo_box.currentIndex() != -1: Settings().setValue('core/monitor', self.display_combo_box.currentIndex()) self.screens.set_current_display(self.display_combo_box.currentIndex()) # Set Global Theme if self.theme_combo_box.currentIndex() != -1: Settings().setValue('themes/global theme', self.theme_combo_box.currentText())
def _export_theme(self, path, theme): """ Create the zipfile with the theme contents. :param path: Location where the zip file will be placed :param theme: The name of the theme to be exported """ theme_path = os.path.join(path, theme + '.otz') theme_zip = None try: theme_zip = zipfile.ZipFile(theme_path, 'w') source = os.path.join(self.path, theme) for files in os.walk(source): for name in files[2]: theme_zip.write(os.path.join(source, name), os.path.join(theme, name)) theme_zip.close() return True except OSError as ose: self.log_exception('Export Theme Failed') critical_error_message_box(translate('OpenLP.ThemeManager', 'Theme Export Failed'), translate('OpenLP.ThemeManager', 'The theme export failed because this error ' 'occurred: {err}').format(err=ose.strerror)) if theme_zip: theme_zip.close() shutil.rmtree(theme_path, True) return False
def on_replace_click(self): """ Called to replace Live background with the media selected. """ if check_item_selected( self.list_view, translate( 'MediaPlugin.MediaItem', 'You must select a media file to replace the background with.' )): item = self.list_view.currentItem() filename = item.data(QtCore.Qt.UserRole) if os.path.exists(filename): service_item = ServiceItem() service_item.title = 'webkit' service_item.processor = 'webkit' (path, name) = os.path.split(filename) service_item.add_from_command(path, name, CLAPPERBOARD) if self.media_controller.video(DisplayControllerType.Live, service_item, video_behind_text=True): self.reset_action.setVisible(True) else: critical_error_message_box( UiStrings().LiveBGError, translate('MediaPlugin.MediaItem', 'There was no display item to amend.')) else: critical_error_message_box( UiStrings().LiveBGError, translate( 'MediaPlugin.MediaItem', 'There was a problem replacing your background, ' 'the media file "%s" no longer exists.') % filename)
def validateCurrentPage(self): """ Validate the current page before moving on to the next page. """ if self.currentPage() == self.welcome_page: return True elif self.currentPage() == self.backup_page: if not self.noBackupCheckBox.checkState() == QtCore.Qt.Checked: backup_path = self.backupDirectoryEdit.text() if not backup_path: critical_error_message_box(UiStrings().EmptyField, translate('BiblesPlugin.UpgradeWizardForm', 'You need to specify a backup directory for your Bibles.')) self.backupDirectoryEdit.setFocus() return False else: if not self.backupOldBibles(backup_path): critical_error_message_box(UiStrings().Error, translate('BiblesPlugin.UpgradeWizardForm', 'The backup was not successful.\nTo backup your ' 'Bibles you need permission to write to the given directory.')) return False return True elif self.currentPage() == self.selectPage: check_directory_exists(self.temp_dir) for number, filename in enumerate(self.files): if not self.checkBox[number].checkState() == QtCore.Qt.Checked: continue # Move bibles to temp dir. if not os.path.exists(os.path.join(self.temp_dir, filename[0])): shutil.move(os.path.join(self.path, filename[0]), self.temp_dir) else: delete_file(os.path.join(self.path, filename[0])) return True if self.currentPage() == self.progress_page: return True
def _pre_wizard(self): """ Prepare the UI for the process. """ self.max_progress = 0 self.finish_button.setVisible(False) self.application.process_events() try: # Loop through the songs list and increase for each selected item for i in range(self.songs_list_widget.count()): self.application.process_events() item = self.songs_list_widget.item(i) if item.checkState() == QtCore.Qt.Checked: filename, sha256 = item.data(QtCore.Qt.UserRole) size = self._get_file_size('%s%s' % (self.songs_url, filename)) self.max_progress += size # Loop through the Bibles list and increase for each selected item iterator = QtWidgets.QTreeWidgetItemIterator(self.bibles_tree_widget) while iterator.value(): self.application.process_events() item = iterator.value() if item.parent() and item.checkState(0) == QtCore.Qt.Checked: filename, sha256 = item.data(0, QtCore.Qt.UserRole) size = self._get_file_size('%s%s' % (self.bibles_url, filename)) self.max_progress += size iterator += 1 # Loop through the themes list and increase for each selected item for i in range(self.themes_list_widget.count()): self.application.process_events() item = self.themes_list_widget.item(i) if item.checkState() == QtCore.Qt.Checked: filename, sha256 = item.data(QtCore.Qt.UserRole) size = self._get_file_size('%s%s' % (self.themes_url, filename)) self.max_progress += size except urllib.error.URLError: trace_error_handler(log) critical_error_message_box(translate('OpenLP.FirstTimeWizard', 'Download Error'), translate('OpenLP.FirstTimeWizard', 'There was a connection problem during ' 'download, so further downloads will be skipped. Try to re-run the ' 'First Time Wizard later.')) self.max_progress = 0 self.web_access = None if self.max_progress: # Add on 2 for plugins status setting plus a "finished" point. self.max_progress += 2 self.progress_bar.setValue(0) self.progress_bar.setMinimum(0) self.progress_bar.setMaximum(self.max_progress) self.progress_page.setTitle(translate('OpenLP.FirstTimeWizard', 'Setting Up And Downloading')) self.progress_page.setSubTitle( translate('OpenLP.FirstTimeWizard', 'Please wait while OpenLP is set up and your data is downloaded.')) else: self.progress_bar.setVisible(False) self.progress_page.setTitle(translate('OpenLP.FirstTimeWizard', 'Setting Up')) self.progress_page.setSubTitle('Setup complete.') self.repaint() self.application.process_events() # Try to give the wizard a chance to repaint itself time.sleep(0.1)
def _pre_wizard(self): """ Prepare the UI for the process. """ self.max_progress = 0 self.finish_button.setVisible(False) self.application.process_events() try: # Loop through the songs list and increase for each selected item for i in range(self.songs_list_widget.count()): self.application.process_events() item = self.songs_list_widget.item(i) if item.checkState() == QtCore.Qt.Checked: filename, sha256 = item.data(QtCore.Qt.UserRole) size = self._get_file_size('%s%s' % (self.songs_url, filename)) self.max_progress += size # Loop through the Bibles list and increase for each selected item iterator = QtGui.QTreeWidgetItemIterator(self.bibles_tree_widget) while iterator.value(): self.application.process_events() item = iterator.value() if item.parent() and item.checkState(0) == QtCore.Qt.Checked: filename, sha256 = item.data(0, QtCore.Qt.UserRole) size = self._get_file_size('%s%s' % (self.bibles_url, filename)) self.max_progress += size iterator += 1 # Loop through the themes list and increase for each selected item for i in range(self.themes_list_widget.count()): self.application.process_events() item = self.themes_list_widget.item(i) if item.checkState() == QtCore.Qt.Checked: filename, sha256 = item.data(QtCore.Qt.UserRole) size = self._get_file_size('%s%s' % (self.themes_url, filename)) self.max_progress += size except urllib.error.URLError: trace_error_handler(log) critical_error_message_box(translate('OpenLP.FirstTimeWizard', 'Download Error'), translate('OpenLP.FirstTimeWizard', 'There was a connection problem during ' 'download, so further downloads will be skipped. Try to re-run the ' 'First Time Wizard later.')) self.max_progress = 0 self.web_access = None if self.max_progress: # Add on 2 for plugins status setting plus a "finished" point. self.max_progress += 2 self.progress_bar.setValue(0) self.progress_bar.setMinimum(0) self.progress_bar.setMaximum(self.max_progress) self.progress_page.setTitle(translate('OpenLP.FirstTimeWizard', 'Setting Up And Downloading')) self.progress_page.setSubTitle( translate('OpenLP.FirstTimeWizard', 'Please wait while OpenLP is set up and your data is downloaded.')) else: self.progress_bar.setVisible(False) self.progress_page.setTitle(translate('OpenLP.FirstTimeWizard', 'Setting Up')) self.progress_page.setSubTitle('Setup complete.') self.repaint() self.application.process_events() # Try to give the wizard a chance to repaint itself time.sleep(0.1)
def accept(self): if not self.language_combo_box.currentText(): critical_error_message_box(message=translate( 'BiblesPlugin.LanguageForm', 'You need to choose a language.')) self.language_combo_box.setFocus() return False else: return QDialog.accept(self)
def media_setup_optical(self, filename, title, audio_track, subtitle_track, start, end, display, controller): """ Setup playback of optical media :param filename: Path of the optical device/drive. :param title: The main/title track to play. :param audio_track: The audio track to play. :param subtitle_track: The subtitle track to play. :param start: Start position in miliseconds. :param end: End position in miliseconds. :param display: The display to play the media. :param controller: The media contraoller. :return: True if setup succeded else False. """ log.debug('media_setup_optical') if controller is None: controller = self.display_controllers[DisplayControllerType.Plugin] # stop running videos self.media_reset(controller) # Setup media info controller.media_info = MediaInfo() controller.media_info.file_info = QtCore.QFileInfo(filename) if audio_track == -1 and subtitle_track == -1: controller.media_info.media_type = MediaType.CD else: controller.media_info.media_type = MediaType.DVD controller.media_info.start_time = start / 1000 controller.media_info.end_time = end / 1000 controller.media_info.length = (end - start) / 1000 controller.media_info.title_track = title controller.media_info.audio_track = audio_track controller.media_info.subtitle_track = subtitle_track # When called from mediaitem display is None if display is None: display = controller.preview_display # Find vlc player used_players = get_media_players()[0] vlc_player = None for title in used_players: player = self.media_players[title] if player.name == 'vlc': vlc_player = player if vlc_player is None: critical_error_message_box( translate('MediaPlugin.MediaItem', 'VLC player required'), translate( 'MediaPlugin.MediaItem', 'VLC player required for playback of optical devices')) return False vlc_player.load(display) self.resize(display, vlc_player) self.current_media_players[controller.controller_type] = vlc_player if audio_track == -1 and subtitle_track == -1: controller.media_info.media_type = MediaType.CD else: controller.media_info.media_type = MediaType.DVD return True
def do_import(self, bible_name=None): """ Loads a Bible from file. """ log.debug('Starting Zefania import from "{name}"'.format(name=self.filename)) success = True try: xmlbible = self.parse_xml(self.filename, elements=REMOVABLE_ELEMENTS, tags=REMOVABLE_TAGS) # Find bible language language = xmlbible.xpath("/XMLBIBLE/INFORMATION/language/text()") language_id = self.get_language_id(language[0] if language else None, bible_name=self.filename) if not language_id: return False no_of_books = int(xmlbible.xpath('count(//BIBLEBOOK)')) self.wizard.progress_bar.setMaximum(int(xmlbible.xpath('count(//CHAPTER)'))) for BIBLEBOOK in xmlbible: if self.stop_import_flag: break bname = BIBLEBOOK.get('bname') bnumber = BIBLEBOOK.get('bnumber') if not bname and not bnumber: continue if bname: book_ref_id = self.get_book_ref_id_by_name(bname, no_of_books, language_id) else: log.debug('Could not find a name, will use number, basically a guess.') book_ref_id = int(bnumber) if not book_ref_id: log.error('Importing books from "{name}" failed'.format(name=self.filename)) return False book_details = BiblesResourcesDB.get_book_by_id(book_ref_id) db_book = self.create_book(book_details['name'], book_ref_id, book_details['testament_id']) for CHAPTER in BIBLEBOOK: if self.stop_import_flag: break chapter_number = CHAPTER.get("cnumber") for VERS in CHAPTER: verse_number = VERS.get("vnumber") self.create_verse( db_book.id, int(chapter_number), int(verse_number), VERS.text.replace('<BR/>', '\n')) self.wizard.increment_progress_bar( translate('BiblesPlugin.Zefnia', 'Importing {book} {chapter}...').format(book=db_book.name, chapter=chapter_number)) self.session.commit() self.application.process_events() except Exception as e: critical_error_message_box( message=translate('BiblesPlugin.ZefaniaImport', 'Incorrect Bible file type supplied. Zefania Bibles may be ' 'compressed. You must decompress them before import.')) log.exception(str(e)) success = False if self.stop_import_flag: return False else: return success
def do_import(self, bible_name=None): """ Loads a Bible from file. """ log.debug('Starting Zefania import from "{name}"'.format(name=self.file_path)) success = True try: xmlbible = self.parse_xml(self.file_path, elements=REMOVABLE_ELEMENTS, tags=REMOVABLE_TAGS) # Find bible language language = xmlbible.xpath("/XMLBIBLE/INFORMATION/language/text()") language_id = self.get_language_id(language[0] if language else None, bible_name=str(self.file_path)) if not language_id: return False no_of_books = int(xmlbible.xpath('count(//BIBLEBOOK)')) self.wizard.progress_bar.setMaximum(int(xmlbible.xpath('count(//CHAPTER)'))) for BIBLEBOOK in xmlbible: if self.stop_import_flag: break bname = BIBLEBOOK.get('bname') bnumber = BIBLEBOOK.get('bnumber') if not bname and not bnumber: continue if bname: book_ref_id = self.get_book_ref_id_by_name(bname, no_of_books, language_id) else: log.debug('Could not find a name, will use number, basically a guess.') book_ref_id = int(bnumber) if not book_ref_id: log.error('Importing books from "{name}" failed'.format(name=self.file_path)) return False book_details = BiblesResourcesDB.get_book_by_id(book_ref_id) db_book = self.create_book(book_details['name'], book_ref_id, book_details['testament_id']) for CHAPTER in BIBLEBOOK: if self.stop_import_flag: break chapter_number = CHAPTER.get("cnumber") for VERS in CHAPTER: verse_number = VERS.get("vnumber") self.create_verse( db_book.id, int(chapter_number), int(verse_number), VERS.text.replace('<BR/>', '\n')) self.wizard.increment_progress_bar( translate('BiblesPlugin.Zefnia', 'Importing {book} {chapter}...').format(book=db_book.name, chapter=chapter_number)) self.session.commit() self.application.process_events() except Exception as e: critical_error_message_box( message=translate('BiblesPlugin.ZefaniaImport', 'Incorrect Bible file type supplied. Zefania Bibles may be ' 'compressed. You must decompress them before import.')) log.exception(str(e)) success = False if self.stop_import_flag: return False else: return success
def __init__(self, plugin_name, init_schema, db_file_name=None, upgrade_mod=None): """ Runs the initialisation process that includes creating the connection to the database and the tables if they do not exist. ``plugin_name`` The name to setup paths and settings section names ``init_schema`` The init_schema function for this database ``upgrade_schema`` The upgrade_schema function for this database ``db_file_name`` The file name to use for this database. Defaults to None resulting in the plugin_name being used. """ settings = Settings() settings.beginGroup(plugin_name) self.db_url = '' self.is_dirty = False self.session = None db_type = settings.value('db type') if db_type == 'sqlite': if db_file_name: self.db_url = 'sqlite:///%s/%s' % (AppLocation.get_section_data_path(plugin_name), db_file_name) else: self.db_url = 'sqlite:///%s/%s.sqlite' % (AppLocation.get_section_data_path(plugin_name), plugin_name) else: self.db_url = '%s://%s:%s@%s/%s' % (db_type, urlquote(settings.value('db username')), urlquote(settings.value('db password')), urlquote(settings.value('db hostname')), urlquote(settings.value('db database'))) if db_type == 'mysql': db_encoding = settings.value('db encoding') self.db_url += '?charset=%s' % urlquote(db_encoding) settings.endGroup() if upgrade_mod: db_ver, up_ver = upgrade_db(self.db_url, upgrade_mod) if db_ver > up_ver: critical_error_message_box( translate('OpenLP.Manager', 'Database Error'), translate('OpenLP.Manager', 'The database being loaded was created in a more recent version of ' 'OpenLP. The database is version %d, while OpenLP expects version %d. The database will not ' 'be loaded.\n\nDatabase: %s') % (db_ver, up_ver, self.db_url) ) return try: self.session = init_schema(self.db_url) except (SQLAlchemyError, DBAPIError): log.exception('Error loading database: %s', self.db_url) critical_error_message_box( translate('OpenLP.Manager', 'Database Error'), translate('OpenLP.Manager', 'OpenLP cannot load your database.\n\nDatabase: %s') % self.db_url )
def test_critical_error_message_box(self, MockRegistry): """ Test the critical_error_message_box() function """ # GIVEN: A mocked Registry # WHEN: critical_error_message_box() is called critical_error_message_box('Error', 'This is an error') # THEN: The error_message() method on the main window should be called MockRegistry.return_value.get.return_value.error_message.assert_called_once_with('Error', 'This is an error')
def media_setup_optical(self, filename, title, audio_track, subtitle_track, start, end, display, controller): """ Setup playback of optical media :param filename: Path of the optical device/drive. :param title: The main/title track to play. :param audio_track: The audio track to play. :param subtitle_track: The subtitle track to play. :param start: Start position in miliseconds. :param end: End position in miliseconds. :param display: The display to play the media. :param controller: The media contraoller. :return: True if setup succeded else False. """ log.debug('media_setup_optical') if controller is None: controller = self.display_controllers[DisplayControllerType.Plugin] # stop running videos self.media_reset(controller) # Setup media info controller.media_info = MediaInfo() controller.media_info.file_info = QtCore.QFileInfo(filename) if audio_track == -1 and subtitle_track == -1: controller.media_info.media_type = MediaType.CD else: controller.media_info.media_type = MediaType.DVD controller.media_info.start_time = start/1000 controller.media_info.end_time = end/1000 controller.media_info.length = (end - start)/1000 controller.media_info.title_track = title controller.media_info.audio_track = audio_track controller.media_info.subtitle_track = subtitle_track # When called from mediaitem display is None if display is None: display = controller.preview_display # Find vlc player used_players = get_media_players()[0] vlc_player = None for title in used_players: player = self.media_players[title] if player.name == 'vlc': vlc_player = player if vlc_player is None: critical_error_message_box(translate('MediaPlugin.MediaItem', 'VLC player required'), translate('MediaPlugin.MediaItem', 'VLC player required for playback of optical devices')) return False vlc_player.load(display) self.resize(display, vlc_player) self.current_media_players[controller.controller_type] = vlc_player if audio_track == -1 and subtitle_track == -1: controller.media_info.media_type = MediaType.CD else: controller.media_info.media_type = MediaType.DVD return True
def accept(self): """ Override the inherited method to check before we close. """ if not self.nameEdit.text(): critical_error_message_box(message=translate('SongsPlugin.TopicsForm', 'You need to type in a topic name.')) self.nameEdit.setFocus() return False else: return QtGui.QDialog.accept(self)
def accept(self): """ Override the accept() method from QDialog to make sure something is entered in the text input box. """ if not self.name_edit.text(): critical_error_message_box(message=translate('ImagePlugin.AddGroupForm', 'You need to type in a group name.')) self.name_edit.setFocus() return False else: return QtGui.QDialog.accept(self)
def accept(self): """ Override the inherited method to check that the name of the book has been typed in. """ if not self.name_edit.text(): critical_error_message_box( message=translate('SongsPlugin.SongBookForm', 'You need to type in a name for the book.')) self.name_edit.setFocus() return False else: return QtGui.QDialog.accept(self)
def _perform_wizard(self): """ Run the tasks in the wizard. """ if self.has_web_access: if not self._download_selected(): critical_error_message_box(translate('OpenLP.FirstTimeWizard', 'Download Error'), translate('OpenLP.FirstTimeWizard', 'There was a connection problem while ' 'downloading, so further downloads will be skipped. Try to re-run ' 'the First Time Wizard later.'))
def accept(self): """ Override the inherited method to check that the name of the book has been typed in. """ if not self.name_edit.text(): critical_error_message_box( message=translate('SongsPlugin.SongBookForm', 'You need to type in a name for the book.')) self.name_edit.setFocus() return False else: return QtWidgets.QDialog.accept(self)