def create_thumbnails(self): """ Create thumbnail images for presentation """ log.debug(u'create thumbnails OpenOffice') if self.check_thumbnails(): return if os.name == u'nt': thumbdirurl = u'file:///' + self.get_temp_folder().replace(u'\\', u'/') \ .replace(u':', u'|').replace(u' ', u'%20') else: thumbdirurl = uno.systemPathToFileUrl(self.get_temp_folder()) props = [] props.append(self.create_property(u'FilterName', u'impress_png_Export')) props = tuple(props) doc = self.document pages = doc.getDrawPages() if not pages: return if not os.path.isdir(self.get_temp_folder()): os.makedirs(self.get_temp_folder()) for idx in range(pages.getCount()): page = pages.getByIndex(idx) doc.getCurrentController().setCurrentPage(page) urlpath = u'%s/%s.png' % (thumbdirurl, unicode(idx + 1)) path = os.path.join(self.get_temp_folder(), unicode(idx + 1) + u'.png') try: doc.storeToURL(urlpath, props) self.convert_thumbnail(path, idx + 1) delete_file(path) except ErrorCodeIOException, exception: log.exception(u'ERROR! ErrorCodeIOException %d' % exception.ErrCode) except:
def create_thumbnails(self): """ Create thumbnail images for presentation. """ log.debug('create thumbnails OpenOffice') if self.check_thumbnails(): return if os.name == 'nt': thumb_dir_url = 'file:///' + self.get_temp_folder().replace('\\', '/') \ .replace(':', '|').replace(' ', '%20') else: thumb_dir_url = uno.systemPathToFileUrl(self.get_temp_folder()) properties = [] properties.append(self.create_property('FilterName', 'impress_png_Export')) properties = tuple(properties) doc = self.document pages = doc.getDrawPages() if not pages: return if not os.path.isdir(self.get_temp_folder()): os.makedirs(self.get_temp_folder()) for index in range(pages.getCount()): page = pages.getByIndex(index) doc.getCurrentController().setCurrentPage(page) url_path = '%s/%s.png' % (thumb_dir_url, str(index + 1)) path = os.path.join(self.get_temp_folder(), str(index + 1) + '.png') try: doc.storeToURL(url_path, properties) self.convert_thumbnail(path, index + 1) delete_file(path) except ErrorCodeIOException as exception: log.exception('ERROR! ErrorCodeIOException %d' % exception.ErrCode) except: log.exception('%s - Unable to store openoffice preview' % path)
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 create_thumbnails(self): """ Create thumbnail images for presentation. """ log.debug('create thumbnails OpenOffice') if self.check_thumbnails(): return if is_win(): thumb_dir_url = 'file:///' + self.get_temp_folder().replace('\\', '/') \ .replace(':', '|').replace(' ', '%20') else: thumb_dir_url = uno.systemPathToFileUrl(self.get_temp_folder()) properties = [] properties.append(self.create_property('FilterName', 'impress_png_Export')) properties = tuple(properties) doc = self.document pages = doc.getDrawPages() if not pages: return if not os.path.isdir(self.get_temp_folder()): os.makedirs(self.get_temp_folder()) for index in range(pages.getCount()): page = pages.getByIndex(index) doc.getCurrentController().setCurrentPage(page) url_path = '%s/%s.png' % (thumb_dir_url, str(index + 1)) path = os.path.join(self.get_temp_folder(), str(index + 1) + '.png') try: doc.storeToURL(url_path, properties) self.convert_thumbnail(path, index + 1) delete_file(path) except ErrorCodeIOException as exception: log.exception('ERROR! ErrorCodeIOException %d' % exception.ErrCode) except: log.exception('%s - Unable to store openoffice preview' % path)
def post_wizard(self): """ Clean up the UI after the import has finished. """ successful_import = 0 failed_import = 0 for number, filename in enumerate(self.files): if self.success.get(number): successful_import += 1 elif self.checkBox[number].checkState() == QtCore.Qt.Checked: failed_import += 1 # Delete upgraded (but not complete, corrupted, ...) bible. delete_file(os.path.join(self.path, filename[0])) # Copy not upgraded bible back. shutil.move(os.path.join(self.temp_dir, filename[0]), self.path) if failed_import > 0: failed_import_text = translate('BiblesPlugin.UpgradeWizardForm', ', %s failed') % failed_import else: failed_import_text = '' if successful_import > 0: if self.includeWebBible: self.progress_label.setText(translate('BiblesPlugin.UpgradeWizardForm', 'Upgrading Bible(s): %s successful%s\nPlease note that verses from Web Bibles will be downloaded ' 'on demand and so an Internet connection is required.') % (successful_import, failed_import_text)) else: self.progress_label.setText(translate('BiblesPlugin.UpgradeWizardForm', 'Upgrading Bible(s): %s successful%s') % (successful_import, failed_import_text)) else: self.progress_label.setText(translate('BiblesPlugin.UpgradeWizardForm', 'Upgrade failed.')) # Remove temp directory. shutil.rmtree(self.temp_dir, True) super(BibleUpgradeForm, self).post_wizard()
def on_delete_click(self): """ Remove an image item from the list. """ # Turn off auto preview triggers. self.list_view.blockSignals(True) if check_item_selected( self.list_view, translate('ImagePlugin.MediaItem', 'You must select an image or group to delete.')): item_list = self.list_view.selectedItems() self.application.set_busy_cursor() self.main_window.display_progress_bar(len(item_list)) for row_item in item_list: if row_item: item_data = row_item.data(0, QtCore.Qt.UserRole) if isinstance(item_data, ImageFilenames): delete_file( os.path.join(self.service_path, row_item.text(0))) delete_file(self.generate_thumbnail_path(item_data)) if item_data.group_id == 0: self.list_view.takeTopLevelItem( self.list_view.indexOfTopLevelItem(row_item)) else: row_item.parent().removeChild(row_item) self.manager.delete_object( ImageFilenames, row_item.data(0, QtCore.Qt.UserRole).id) elif isinstance(item_data, ImageGroups): if QtWidgets.QMessageBox.question( self.list_view.parent(), translate('ImagePlugin.MediaItem', 'Remove group'), translate( 'ImagePlugin.MediaItem', 'Are you sure you want to remove "%s" and everything in it?' ) % item_data.group_name, QtWidgets.QMessageBox.StandardButtons( QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No) ) == QtWidgets.QMessageBox.Yes: self.recursively_delete_group(item_data) self.manager.delete_object( ImageGroups, row_item.data(0, QtCore.Qt.UserRole).id) if item_data.parent_id == 0: self.list_view.takeTopLevelItem( self.list_view.indexOfTopLevelItem( row_item)) else: row_item.parent().removeChild(row_item) self.fill_groups_combobox( self.choose_group_form.group_combobox) self.fill_groups_combobox( self.add_group_form.parent_group_combobox) self.main_window.increment_progress_bar() self.main_window.finished_progress_bar() self.application.set_normal_cursor() self.list_view.blockSignals(False)
def recursively_delete_group(self, image_group): """ Recursively deletes a group and all groups and images in it. :param image_group: The ImageGroups instance of the group that will be deleted. """ images = self.manager.get_all_objects(ImageFilenames, ImageFilenames.group_id == image_group.id) for image in images: delete_file(os.path.join(self.service_path, os.path.split(image.filename)[1])) delete_file(self.generate_thumbnail_path(image)) self.manager.delete_object(ImageFilenames, image.id) image_groups = self.manager.get_all_objects(ImageGroups, ImageGroups.parent_id == image_group.id) for group in image_groups: self.recursively_delete_group(group) self.manager.delete_object(ImageGroups, group.id)
def reload_bibles(self): """ Reloads the Bibles from the available Bible databases on disk. If a web Bible is encountered, an instance of HTTPBible is loaded instead of the BibleDB class. """ log.debug('Reload bibles') files = AppLocation.get_files(self.settings_section, self.suffix) if 'alternative_book_names.sqlite' in files: files.remove('alternative_book_names.sqlite') log.debug('Bible Files %s', files) self.db_cache = {} self.old_bible_databases = [] for filename in files: bible = BibleDB(self.parent, path=self.path, file=filename) if not bible.session: continue name = bible.get_name() # Remove corrupted files. if name is None: bible.session.close() delete_file(os.path.join(self.path, filename)) continue # Find old database versions. if bible.is_old_database(): self.old_bible_databases.append([filename, name]) bible.session.close() continue log.debug('Bible Name: "%s"', name) self.db_cache[name] = bible # Look to see if lazy load bible exists and get create getter. source = self.db_cache[name].get_object(BibleMeta, 'download_source') if source: download_name = self.db_cache[name].get_object( BibleMeta, 'download_name').value meta_proxy = self.db_cache[name].get_object( BibleMeta, 'proxy_server') web_bible = HTTPBible(self.parent, path=self.path, file=filename, download_source=source.value, download_name=download_name) if meta_proxy: web_bible.proxy_server = meta_proxy.value self.db_cache[name] = web_bible log.debug('Bibles reloaded')
def load_first_time_themes(self): """ Imports any themes on start up and makes sure there is at least one theme """ self.application.set_busy_cursor() files = AppLocation.get_files(self.settings_section, '.otz') for theme_file in files: theme_file = os.path.join(self.path, theme_file) self.unzip_theme(theme_file, self.path) delete_file(theme_file) files = AppLocation.get_files(self.settings_section, '.png') # No themes have been found so create one if not files: theme = ThemeXML() theme.theme_name = UiStrings().Default self._write_theme(theme, None, None) Settings().setValue(self.settings_section + '/global theme', theme.theme_name) self.application.set_normal_cursor()
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.backup_old_bibles(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 on_delete_click(self): """ Remove an image item from the list. """ # Turn off auto preview triggers. self.list_view.blockSignals(True) if check_item_selected(self.list_view, translate('ImagePlugin.MediaItem', 'You must select an image or group to delete.')): item_list = self.list_view.selectedItems() self.application.set_busy_cursor() self.main_window.display_progress_bar(len(item_list)) for row_item in item_list: if row_item: item_data = row_item.data(0, QtCore.Qt.UserRole) if isinstance(item_data, ImageFilenames): delete_file(os.path.join(self.service_path, row_item.text(0))) delete_file(self.generate_thumbnail_path(item_data)) if item_data.group_id == 0: self.list_view.takeTopLevelItem(self.list_view.indexOfTopLevelItem(row_item)) else: row_item.parent().removeChild(row_item) self.manager.delete_object(ImageFilenames, row_item.data(0, QtCore.Qt.UserRole).id) elif isinstance(item_data, ImageGroups): if QtGui.QMessageBox.question( self.list_view.parent(), translate('ImagePlugin.MediaItem', 'Remove group'), translate('ImagePlugin.MediaItem', 'Are you sure you want to remove "%s" and everything in it?') % item_data.group_name, QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)) == QtGui.QMessageBox.Yes: self.recursively_delete_group(item_data) self.manager.delete_object(ImageGroups, row_item.data(0, QtCore.Qt.UserRole).id) if item_data.parent_id == 0: self.list_view.takeTopLevelItem(self.list_view.indexOfTopLevelItem(row_item)) else: row_item.parent().removeChild(row_item) self.fill_groups_combobox(self.choose_group_form.group_combobox) self.fill_groups_combobox(self.add_group_form.parent_group_combobox) self.main_window.increment_progress_bar() self.main_window.finished_progress_bar() self.application.set_normal_cursor() self.list_view.blockSignals(False)
def delete_file_no_path_test(self): """ Test the delete_file function when called with out a valid path """ # GIVEN: A blank path # WEHN: Calling delete_file result = delete_file('') # THEN: delete_file should return False self.assertFalse(result, "delete_file should return False when called with ''")
def post_wizard(self): """ Clean up the UI after the import has finished. """ successful_import = 0 failed_import = 0 for number, filename in enumerate(self.files): if self.success.get(number): successful_import += 1 elif self.checkBox[number].checkState() == QtCore.Qt.Checked: failed_import += 1 # Delete upgraded (but not complete, corrupted, ...) bible. delete_file(os.path.join(self.path, filename[0])) # Copy not upgraded bible back. shutil.move(os.path.join(self.temp_dir, filename[0]), self.path) if failed_import > 0: failed_import_text = translate('BiblesPlugin.UpgradeWizardForm', ', %s failed') % failed_import else: failed_import_text = '' if successful_import > 0: if self.includeWebBible: self.progress_label.setText( translate( 'BiblesPlugin.UpgradeWizardForm', 'Upgrading Bible(s): %(success)d successful%(failed_text)s\nPlease note that verses ' 'from Web Bibles will be downloaded on demand and so an Internet connection is required.' ) % { 'success': successful_import, 'failed_text': failed_import_text }) else: self.progress_label.setText( translate('BiblesPlugin.UpgradeWizardForm', 'Upgrading Bible(s): %s successful%s') % (successful_import, failed_import_text)) else: self.progress_label.setText( translate('BiblesPlugin.UpgradeWizardForm', 'Upgrade failed.')) # Remove temp directory. shutil.rmtree(self.temp_dir, True) super(BibleUpgradeForm, self).post_wizard()
def delete_file_no_path_test(self): """ Test the delete_file function when called with out a valid path """ # GIVEN: A blank path # WEHN: Calling delete_file result = delete_file('') # THEN: delete_file should return False self.assertFalse( result, "delete_file should return False when called with ''")
def delete_theme(self, theme): """ Delete a theme. :param theme: The theme to delete. """ self.theme_list.remove(theme) thumb = '%s.png' % theme delete_file(os.path.join(self.path, thumb)) delete_file(os.path.join(self.thumb_path, thumb)) try: # Windows is always unicode, so no need to encode filenames if is_win(): shutil.rmtree(os.path.join(self.path, theme)) else: encoding = get_filesystem_encoding() shutil.rmtree(os.path.join(self.path, theme).encode(encoding)) except OSError as os_error: shutil.Error = os_error self.log_exception('Error deleting theme %s' % theme)
def delete_bible(self, name): """ Delete a bible completely. :param name: The name of the bible. """ log.debug('BibleManager.delete_bible("%s")', name) bible = self.db_cache[name] bible.session.close() bible.session = None return delete_file(os.path.join(bible.path, bible.file))
def delete_bible(self, name): """ Delete a bible completely. :param name: The name of the bible. """ log.debug('BibleManager.delete_bible("%s")', name) bible = self.db_cache[name] bible.session.close_all() bible.session = None return delete_file(os.path.join(bible.path, bible.file))
def delete_database(plugin_name, db_file_name=None): """ Remove a database file from the system. :param plugin_name: The name of the plugin to remove the database for :param db_file_name: The database file name. Defaults to None resulting in the plugin_name being used. """ if db_file_name: db_file_path = os.path.join(AppLocation.get_section_data_path(plugin_name), db_file_name) else: db_file_path = os.path.join(AppLocation.get_section_data_path(plugin_name), plugin_name) return delete_file(db_file_path)
def delete_file_path_success_test(self): """ Test the delete_file function when it successfully deletes a file """ # GIVEN: A mocked os which returns True when os.path.exists is called with patch('openlp.core.utils.os', **{'path.exists.return_value': False}): # WHEN: Calling delete_file with a file path result = delete_file('path/file.ext') # THEN: delete_file should return True self.assertTrue(result, 'delete_file should return True when it successfully deletes a file')
def delete_file_path_no_file_exists_test(self): """ Test the delete_file function when the file to remove does not exist """ # GIVEN: A mocked os which returns False when os.path.exists is called with patch('openlp.core.utils.os', **{'path.exists.return_value': False}): # WHEN: Calling delete_file with a file path result = delete_file('path/file.ext') # THEN: delete_file should return True self.assertTrue(result, 'delete_file should return True when the file doesnt exist')
def reload_bibles(self): """ Reloads the Bibles from the available Bible databases on disk. If a web Bible is encountered, an instance of HTTPBible is loaded instead of the BibleDB class. """ log.debug('Reload bibles') files = AppLocation.get_files(self.settings_section, self.suffix) if 'alternative_book_names.sqlite' in files: files.remove('alternative_book_names.sqlite') log.debug('Bible Files %s', files) self.db_cache = {} self.old_bible_databases = [] for filename in files: bible = BibleDB(self.parent, path=self.path, file=filename) if not bible.session: continue name = bible.get_name() # Remove corrupted files. if name is None: bible.session.close() delete_file(os.path.join(self.path, filename)) continue # Find old database versions. if bible.is_old_database(): self.old_bible_databases.append([filename, name]) bible.session.close() continue log.debug('Bible Name: "%s"', name) self.db_cache[name] = bible # Look to see if lazy load bible exists and get create getter. source = self.db_cache[name].get_object(BibleMeta, 'download_source') if source: download_name = self.db_cache[name].get_object(BibleMeta, 'download_name').value meta_proxy = self.db_cache[name].get_object(BibleMeta, 'proxy_server') web_bible = HTTPBible(self.parent, path=self.path, file=filename, download_source=source.value, download_name=download_name) if meta_proxy: web_bible.proxy_server = meta_proxy.value self.db_cache[name] = web_bible log.debug('Bibles reloaded')
def _write_theme(self, theme, image_from, image_to): """ Writes the theme to the disk and handles the background image if necessary :param theme: The theme data object. :param image_from: Where the theme image is currently located. :param image_to: Where the Theme Image is to be saved to """ name = theme.theme_name theme_pretty_xml = theme.extract_formatted_xml() theme_dir = os.path.join(self.path, name) check_directory_exists(theme_dir) theme_file = os.path.join(theme_dir, name + '.xml') if self.old_background_image and image_to != self.old_background_image: delete_file(self.old_background_image) out_file = None try: out_file = open(theme_file, 'w', encoding='utf-8') out_file.write(theme_pretty_xml.decode('utf-8')) except IOError: self.log_exception('Saving theme to file failed') finally: if out_file: out_file.close() if image_from and os.path.abspath(image_from) != os.path.abspath( image_to): try: # Windows is always unicode, so no need to encode filenames if is_win(): shutil.copyfile(image_from, image_to) else: encoding = get_filesystem_encoding() shutil.copyfile(image_from.encode(encoding), image_to.encode(encoding)) except IOError as xxx_todo_changeme: shutil.Error = xxx_todo_changeme self.log_exception('Failed to save theme image') self.generate_and_save_image(name, theme)
def delete_database(plugin_name, db_file_name=None): """ Remove a database file from the system. :param plugin_name: The name of the plugin to remove the database for :param db_file_name: The database file name. Defaults to None resulting in the plugin_name being used. """ if db_file_name: db_file_path = os.path.join( AppLocation.get_section_data_path(plugin_name), db_file_name) else: db_file_path = os.path.join( AppLocation.get_section_data_path(plugin_name), plugin_name) return delete_file(db_file_path)
def _write_theme(self, theme, image_from, image_to): """ Writes the theme to the disk and handles the background image if necessary :param theme: The theme data object. :param image_from: Where the theme image is currently located. :param image_to: Where the Theme Image is to be saved to """ name = theme.theme_name theme_pretty_xml = theme.extract_formatted_xml() theme_dir = os.path.join(self.path, name) check_directory_exists(theme_dir) theme_file = os.path.join(theme_dir, name + '.xml') if self.old_background_image and image_to != self.old_background_image: delete_file(self.old_background_image) out_file = None try: out_file = open(theme_file, 'w', encoding='utf-8') out_file.write(theme_pretty_xml.decode('utf-8')) except IOError: self.log_exception('Saving theme to file failed') finally: if out_file: out_file.close() if image_from and os.path.abspath(image_from) != os.path.abspath(image_to): try: # Windows is always unicode, so no need to encode filenames if is_win(): shutil.copyfile(image_from, image_to) else: encoding = get_filesystem_encoding() shutil.copyfile(image_from.encode(encoding), image_to.encode(encoding)) except IOError as xxx_todo_changeme: shutil.Error = xxx_todo_changeme self.log_exception('Failed to save theme image') self.generate_and_save_image(name, theme)
def delete_file_path_no_file_exists_test(self): """ Test the delete_file function when the file to remove does not exist """ # GIVEN: A mocked os which returns False when os.path.exists is called with patch('openlp.core.utils.os', **{'path.exists.return_value': False}): # WHEN: Calling delete_file with a file path result = delete_file('path/file.ext') # THEN: delete_file should return True self.assertTrue( result, 'delete_file should return True when the file doesnt exist')
def delete_file_path_exception_test(self): """ Test the delete_file function when os.remove raises an exception """ # GIVEN: A mocked os which returns True when os.path.exists is called and raises an OSError when os.remove is # called. with patch('openlp.core.utils.os', **{'path.exists.return_value': True, 'path.exists.side_effect': OSError}), \ patch('openlp.core.utils.log') as mocked_log: # WHEN: Calling delete_file with a file path result = delete_file('path/file.ext') # THEN: delete_file should log and exception and return False self.assertEqual(mocked_log.exception.call_count, 1) self.assertFalse(result, 'delete_file should return False when os.remove raises an OSError')
def delete_file_path_success_test(self): """ Test the delete_file function when it successfully deletes a file """ # GIVEN: A mocked os which returns True when os.path.exists is called with patch('openlp.core.utils.os', **{'path.exists.return_value': False}): # WHEN: Calling delete_file with a file path result = delete_file('path/file.ext') # THEN: delete_file should return True self.assertTrue( result, 'delete_file should return True when it successfully deletes a file' )
def delete_file_path_exception_test(self): """ Test the delete_file function when os.remove raises an exception """ # GIVEN: A mocked os which returns True when os.path.exists is called and raises an OSError when os.remove is # called. with patch('openlp.core.utils.os', **{'path.exists.return_value': True, 'path.exists.side_effect': OSError}), \ patch('openlp.core.utils.log') as mocked_log: # WHEN: Calling delete_file with a file path result = delete_file('path/file.ext') # THEN: delete_file should log and exception and return False self.assertEqual(mocked_log.exception.call_count, 1) self.assertFalse( result, 'delete_file should return False when os.remove raises an OSError' )