From e8c2d7e805c79d4191409582495c214bde301f10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Armin=20K=C3=B6hler?= Date: Tue, 19 Apr 2011 22:25:27 +0200 Subject: [PATCH] add reimportwizard for older bible databases --- openlp/plugins/bibles/bibleplugin.py | 33 +- openlp/plugins/bibles/forms/__init__.py | 1 + .../plugins/bibles/forms/biblereimportform.py | 697 ++++++++++++++++++ openlp/plugins/bibles/lib/db.py | 122 +++ openlp/plugins/bibles/lib/mediaitem.py | 12 +- resources/images/bibles_reimport_alert.png | Bin 0 -> 762 bytes 6 files changed, 862 insertions(+), 3 deletions(-) create mode 100644 openlp/plugins/bibles/forms/biblereimportform.py create mode 100644 resources/images/bibles_reimport_alert.png diff --git a/openlp/plugins/bibles/bibleplugin.py b/openlp/plugins/bibles/bibleplugin.py index 5a631bf00..13b5924d7 100644 --- a/openlp/plugins/bibles/bibleplugin.py +++ b/openlp/plugins/bibles/bibleplugin.py @@ -58,6 +58,7 @@ class BiblePlugin(Plugin): #action_list.add_action(self.exportBibleItem, UiStrings().Export) # Set to invisible until we can export bibles self.exportBibleItem.setVisible(False) + self.toolsReimportItem.setVisible(True) def finalise(self): """ @@ -87,6 +88,36 @@ class BiblePlugin(Plugin): export_menu.addAction(self.exportBibleItem) self.exportBibleItem.setVisible(False) + def addToolsMenuItem(self, tools_menu): + """ + Give the alerts plugin the opportunity to add items to the + **Tools** menu. + + ``tools_menu`` + The actual **Tools** menu item, so that your actions can + use it as their parent. + """ + log.info(u'add tools menu') + self.toolsReimportItem = QtGui.QAction(tools_menu) + self.toolsReimportItem.setObjectName(u'toolsReimportItem') + self.toolsReimportItem.setText( + translate('BiblePlugin', 'Re-&import older bible databases')) + self.toolsReimportItem.setStatusTip( + translate('BiblePlugin', 'Re-import the bible databases to addapt ' + 'the database scheme.')) + tools_menu.addAction(self.toolsReimportItem) + QtCore.QObject.connect(self.toolsReimportItem, + QtCore.SIGNAL(u'triggered()'), self.onToolsReimportItemTriggered) + self.toolsReimportItem.setVisible(False) + + def onToolsReimportItemTriggered(self): + """ + Re-import older bible databases. + """ + #self.manager.import_old_bible_databases() + if self.mediaItem: + self.mediaItem.onReImportClick() + def onBibleImportClick(self): if self.mediaItem: self.mediaItem.onImportClick() @@ -146,4 +177,4 @@ class BiblePlugin(Plugin): u'service': translate('BiblesPlugin', 'Add the selected Bible to the service') } - self.setPluginUiTextStrings(tooltips) \ No newline at end of file + self.setPluginUiTextStrings(tooltips) diff --git a/openlp/plugins/bibles/forms/__init__.py b/openlp/plugins/bibles/forms/__init__.py index 561944563..bd7ba3828 100644 --- a/openlp/plugins/bibles/forms/__init__.py +++ b/openlp/plugins/bibles/forms/__init__.py @@ -53,5 +53,6 @@ from the .ui files later if necessary. from booknameform import BookNameForm from languageform import LanguageForm from bibleimportform import BibleImportForm +from biblereimportform import BibleReImportForm __all__ = ['BibleImportForm'] diff --git a/openlp/plugins/bibles/forms/biblereimportform.py b/openlp/plugins/bibles/forms/biblereimportform.py new file mode 100644 index 000000000..5a311f017 --- /dev/null +++ b/openlp/plugins/bibles/forms/biblereimportform.py @@ -0,0 +1,697 @@ +# -*- coding: utf-8 -*- +# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 + +############################################################################### +# OpenLP - Open Source Lyrics Projection # +# --------------------------------------------------------------------------- # +# Copyright (c) 2008-2011 Raoul Snyman # +# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael # +# Gorven, Scott Guerrieri, Matthias Hub, Meinert Jordan, Armin Köhler, # +# Andreas Preikschat, Mattias Põldaru, Christian Richter, Philip Ridout, # +# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Frode Woldsund # +# --------------------------------------------------------------------------- # +# This program is free software; you can redistribute it and/or modify it # +# under the terms of the GNU General Public License as published by the Free # +# Software Foundation; version 2 of the License. # +# # +# This program is distributed in the hope that it will be useful, but WITHOUT # +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # +# more details. # +# # +# You should have received a copy of the GNU General Public License along # +# with this program; if not, write to the Free Software Foundation, Inc., 59 # +# Temple Place, Suite 330, Boston, MA 02111-1307 USA # +############################################################################### +""" +The bible import functions for OpenLP +""" +import logging +import os +import os.path +import re + +from PyQt4 import QtCore, QtGui + +from openlp.core.lib import Receiver, SettingsManager, translate +from openlp.core.lib.db import delete_database +from openlp.core.lib.ui import UiStrings, critical_error_message_box +from openlp.core.ui.wizard import OpenLPWizard, WizardStrings +from openlp.core.utils import AppLocation, delete_file +from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta, OldBibleDB,\ + BiblesResourcesDB +from openlp.plugins.bibles.lib.http import BSExtract, BGExtract, CWExtract + +log = logging.getLogger(__name__) + + +class BibleReImportForm(OpenLPWizard): + """ + This is the Bible ReImport Wizard, which allows easy importing of Bibles + into OpenLP from older OpenLP2 database versions. + """ + log.info(u'BibleReImportForm loaded') + + def __init__(self, parent, manager, bibleplugin): + """ + Instantiate the wizard, and run any extra setup we need to. + + ``parent`` + The QWidget-derived parent of the wizard. + + ``manager`` + The Bible manager. + + ``bibleplugin`` + The Bible plugin. + """ + self.manager = manager + self.parent = parent + self.suffix = u'.sqlite' + self.settingsSection = u'bibles/bibles' + self.oldsettingsSection = u'bibles' + self.oldpath = AppLocation.get_section_data_path( + self.oldsettingsSection) + self.newpath = AppLocation.get_section_data_path( + self.settingsSection) + self.files = SettingsManager.get_files(self.oldsettingsSection, + self.suffix) + self.success = {} + self.newbibles = {} + self.maxBibles = len(self.files) + self.stop_import_flag = False + OpenLPWizard.__init__(self, parent, bibleplugin, u'bibleImportWizard', + u':/wizards/wizard_importbible.bmp') + + def setupUi(self, image): + """ + Set up the UI for the bible wizard. + """ + OpenLPWizard.setupUi(self, image) + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'openlp_stop_wizard'), self.stop_import) + + def stop_import(self): + """ + Stops the import of the Bible. + """ + log.debug(u'Stopping import') + self.stop_import_flag = True + + def clean_filename(self, old_filename): + """ + Clean up the version name of the Bible and convert it into a valid + file name. + + ``old_filename`` + The "dirty" file name or version name. + """ + if not isinstance(old_filename, unicode): + old_filename = unicode(old_filename, u'utf-8') + old_filename = re.sub(r'[^\w]+', u'_', old_filename).strip(u'_') + return old_filename + u'.sqlite' + + def onCheckBoxIndexChanged(self, index): + ''' + Some cleanup while finishing + ''' + for number, filename in enumerate(self.files): + if not self.checkBox[number].checkState() == 2: + self.verticalWidget[number].hide() + self.formWidget[number].hide() + else: + if os.path.exists(os.path.join(self.newpath, filename)): + self.verticalWidget[number].setVisible(1) + self.formWidget[number].setVisible(1) + + def reject(self): + """ + Stop the wizard on cancel button, close button or ESC key. + """ + log.debug(u'Wizard cancelled by user') + if self.currentPage() == self.progressPage: + Receiver.send_message(u'openlp_stop_wizard') + for bible in self.newbibles.itervalues(): + delete_database(self.newpath, bible.clean_filename( + bible.get_name())) + self.done(QtGui.QDialog.Rejected) + + def onCurrentIdChanged(self, pageId): + """ + Perform necessary functions depending on which wizard page is active. + """ + if self.page(pageId) == self.progressPage: + self.preWizard() + self.performWizard() + self.postWizard() + elif self.page(pageId) == self.selectPage and self.maxBibles == 0: + self.next() + + def onFinishButton(self): + ''' + Some cleanup while finishing + ''' + if self.deleteCheckBox.checkState() == 2 or \ + self.deleteAllCheckBox.checkState() == 2: + for number, filename in enumerate(self.files): + if self.deleteAllCheckBox.checkState() == 2 or \ + (self.checkBox[number].checkState() == 2 and \ + self.success[number] == True): + delete_file(os.path.join(self.oldpath, filename)) + + def customInit(self): + """ + Perform any custom initialisation for bible importing. + """ + self.manager.set_process_dialog(self) + self.restart() + + def customSignals(self): + """ + Set up the signals used in the bible importer. + """ + for number, filename in enumerate(self.files): + QtCore.QObject.connect(self.checkBox[number], + QtCore.SIGNAL(u'stateChanged(int)'), + self.onCheckBoxIndexChanged) + QtCore.QObject.connect(self.finishButton, + QtCore.SIGNAL(u'clicked()'), self.onFinishButton) + + def addCustomPages(self): + """ + Add the bible import specific wizard pages. + """ + self.selectPage = QtGui.QWizardPage() + self.selectPage.setObjectName(u'SelectPage') + self.pageLayout = QtGui.QVBoxLayout(self.selectPage) + self.pageLayout.setObjectName(u'pageLayout') + self.scrollArea = QtGui.QScrollArea(self.selectPage) + self.scrollArea.setWidgetResizable(True) + self.scrollArea.setObjectName(u'scrollArea') + self.scrollArea.setHorizontalScrollBarPolicy( + QtCore.Qt.ScrollBarAlwaysOff) + self.scrollAreaContents = QtGui.QWidget(self.scrollArea) + self.scrollAreaContents.setObjectName(u'scrollAreaContents') + self.formLayout = QtGui.QVBoxLayout(self.scrollAreaContents) + self.formLayout.setSpacing(2) + self.formLayout.setObjectName(u'formLayout') + self.addScrollArea() + self.pageLayout.addWidget(self.scrollArea) + self.addPage(self.selectPage) + + def addScrollArea(self): + """ + Add the content to the scrollArea. + """ + self.checkBox = {} + self.versionNameEdit = {} + self.versionNameLabel = {} + self.versionInfoLabel = {} + self.versionInfoPixmap = {} + self.verticalWidget = {} + self.horizontalLayout = {} + self.formWidget = {} + self.formLayoutAttention = {} + for number, filename in enumerate(self.files): + bible = OldBibleDB(self.parent, path=self.oldpath, file=filename) + self.checkBox[number] = QtGui.QCheckBox(self.scrollAreaContents) + checkBoxName = u'checkBox['+unicode(number)+u']' + self.checkBox[number].setObjectName(checkBoxName) + self.checkBox[number].setText(bible.get_name()) + self.checkBox[number].setCheckState(2) + self.formLayout.addWidget(self.checkBox[number]) + self.verticalWidget[number] = QtGui.QWidget(self.scrollAreaContents) + verticalWidgetName = u'verticalWidget['+unicode(number)+u']' + self.verticalWidget[number].setObjectName(verticalWidgetName) + self.horizontalLayout[number] = QtGui.QHBoxLayout( + self.verticalWidget[number]) + self.horizontalLayout[number].setContentsMargins(25, 0, 0, 0) + horizontalLayoutName = u'horizontalLayout['+unicode(number)+u']' + self.horizontalLayout[number].setObjectName(horizontalLayoutName) + self.versionInfoPixmap[number] = QtGui.QLabel( + self.verticalWidget[number]) + versionInfoPixmapName = u'versionInfoPixmap['+unicode(number)+u']' + self.versionInfoPixmap[number].setObjectName(versionInfoPixmapName) + self.versionInfoPixmap[number].setPixmap(QtGui.QPixmap( + u':/plugins/plugin_alerts.png')) + #u':/bibles/bibles_reimport_alert.png')) + self.versionInfoPixmap[number].setAlignment(QtCore.Qt.AlignRight) + self.horizontalLayout[number].addWidget( + self.versionInfoPixmap[number]) + self.versionInfoLabel[number] = QtGui.QLabel( + self.verticalWidget[number]) + versionInfoLabelName = u'versionInfoLabel['+unicode(number)+u']' + self.versionInfoLabel[number].setObjectName(versionInfoLabelName) + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, + QtGui.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth( + self.versionInfoLabel[number].sizePolicy().hasHeightForWidth()) + self.versionInfoLabel[number].setSizePolicy(sizePolicy) + self.horizontalLayout[number].addWidget( + self.versionInfoLabel[number]) + self.formLayout.addWidget(self.verticalWidget[number]) + self.formWidget[number] = QtGui.QWidget(self.scrollAreaContents) + formWidgetName = u'formWidget['+unicode(number)+u']' + self.formWidget[number].setObjectName(formWidgetName) + self.formLayoutAttention[number] = QtGui.QFormLayout( + self.formWidget[number]) + self.formLayoutAttention[number].setContentsMargins(25, 0, 0, 5) + formLayoutAttentionName = u'formLayoutAttention['+unicode(number)+\ + u']' + self.formLayoutAttention[number].setObjectName( + formLayoutAttentionName) + self.versionNameLabel[number] = QtGui.QLabel( + self.formWidget[number]) + self.versionNameLabel[number].setObjectName(u'VersionNameLabel') + self.formLayoutAttention[number].setWidget(0, + QtGui.QFormLayout.LabelRole, self.versionNameLabel[number]) + self.versionNameEdit[number] = QtGui.QLineEdit( + self.formWidget[number]) + self.versionNameEdit[number].setObjectName(u'VersionNameEdit') + self.formLayoutAttention[number].setWidget(0, + QtGui.QFormLayout.FieldRole, self.versionNameEdit[number]) + self.versionNameEdit[number].setText(bible.get_name()) + self.formLayout.addWidget(self.formWidget[number]) + self.spacerItem = QtGui.QSpacerItem(20, 5, QtGui.QSizePolicy.Minimum, + QtGui.QSizePolicy.Expanding) + self.formLayout.addItem(self.spacerItem) + self.scrollArea.setWidget(self.scrollAreaContents) + + def clearScrollArea(self): + """ + Remove the content from the scrollArea. + """ + for number, filename in enumerate(self.files): + self.formLayout.removeWidget(self.checkBox[number]) + self.checkBox[number].setParent(None) + self.horizontalLayout[number].removeWidget( + self.versionInfoPixmap[number]) + self.versionInfoPixmap[number].setParent(None) + self.horizontalLayout[number].removeWidget( + self.versionInfoLabel[number]) + self.versionInfoLabel[number].setParent(None) + self.formLayout.removeWidget(self.verticalWidget[number]) + self.verticalWidget[number].setParent(None) + self.formLayoutAttention[number].removeWidget( + self.versionNameLabel[number]) + self.versionNameLabel[number].setParent(None) + self.formLayoutAttention[number].removeWidget( + self.versionNameEdit[number]) + self.formLayoutAttention[number].deleteLater() + self.versionNameEdit[number].setParent(None) + self.formLayout.removeWidget(self.formWidget[number]) + self.formWidget[number].setParent(None) + self.formLayout.removeItem(self.spacerItem) + + def addProgressPage(self): + """ + Add the progress page for the wizard. This page informs the user how + the wizard is progressing with its task. + """ + OpenLPWizard.addProgressPage(self) + self.progressLayout.setContentsMargins(48, 30, 48, 30) + self.progressLabelAfter = QtGui.QLabel(self.progressPage) + self.progressLabelAfter.setObjectName(u'progressLabelAfter') + self.progressLayout.addWidget(self.progressLabelAfter) + self.deleteCheckBox = QtGui.QCheckBox(self.progressPage) + self.deleteCheckBox.setObjectName(u'deleteCheckBox') + self.progressLayout.addWidget(self.deleteCheckBox) + self.deleteAllCheckBox = QtGui.QCheckBox(self.progressPage) + self.deleteAllCheckBox.setObjectName(u'deleteAllCheckBox') + self.progressLayout.addWidget(self.deleteAllCheckBox) + + def retranslateUi(self): + """ + Allow for localisation of the bible import wizard. + """ + self.setWindowTitle(translate('BiblesPlugin.ReImportWizardForm', + 'Bible ReImport Wizard')) + self.titleLabel.setText(WizardStrings.HeaderStyle % + translate('OpenLP.Ui', 'Welcome to the Bible ReImport Wizard')) + self.informationLabel.setText( + translate('BiblesPlugin.ReImportWizardForm', + 'This wizard will help you to reimport your existing Bibles from a ' + 'prior version of OpenLP 2. Click the next button below to start ' + 'the process by selecting the bibles to reimport.')) + self.selectPage.setTitle( + translate('BiblesPlugin.ReImportWizardForm', + 'Please choose')) + self.selectPage.setSubTitle( + translate('BiblesPlugin.ReImportWizardForm', + 'Please choose the bibles which should be reimported')) + for number, bible in enumerate(self.files): + self.versionNameLabel[number].setText( + translate('BiblesPlugin.ReImportWizardForm', 'Version name:')) + self.versionInfoLabel[number].setText( + translate('BiblesPlugin.ReImportWizardForm', 'This ' + 'bible still exists. Please change the name or uncheck it.')) + self.progressPage.setTitle(WizardStrings.Importing) + self.progressPage.setSubTitle( + translate('BiblesPlugin.ReImportWizardForm', + 'Please wait while your Bibles are imported.')) + self.progressLabel.setText(WizardStrings.Ready) + self.progressBar.setFormat(u'%p%') + self.deleteCheckBox.setText( + translate('BiblesPlugin.ReImportWizardForm', 'Delete old bible ' + 'database(s) from bibles which was imported\nsucessful right now')) + self.deleteAllCheckBox.setText( + translate('BiblesPlugin.ReImportWizardForm', 'Delete all old bible ' + 'database(s) (including not imported bibles)')) + self.progressLabelAfter.setText( + translate('BiblesPlugin.ReImportWizardForm', '\nIf OpenLP should ' + 'delete the old bible databases please choose:')) + + def validateCurrentPage(self): + """ + Validate the current page before moving on to the next page. + """ + if self.currentPage() == self.welcomePage: + return True + elif self.currentPage() == self.selectPage: + for number, filename in enumerate(self.files): + if not self.checkBox[number].checkState() == 2: + continue + version_name = unicode(self.versionNameEdit[number].text()) + oldbible = OldBibleDB(self.parent, path=self.oldpath, + file=filename) + oldname = oldbible.get_name() + if not version_name: + critical_error_message_box(UiStrings().EmptyField, + translate('BiblesPlugin.ReImportWizardForm', + 'You need to specify a version name for your Bible.')) + self.versionNameEdit[number].setFocus() + return False + elif self.manager.exists(version_name): + critical_error_message_box( + translate('BiblesPlugin.ReImportWizardForm', + 'Bible Exists'), + translate('BiblesPlugin.ReImportWizardForm', + 'This Bible already exists. Please import ' + 'a different Bible, delete the existing one or ' + 'uncheck.')) + self.versionNameEdit[number].setFocus() + return False + elif os.path.exists(os.path.join(self.newpath, filename)) and \ + version_name == oldname: + critical_error_message_box( + translate('BiblesPlugin.ReImportWizardForm', + 'Bible Exists'), + translate('BiblesPlugin.ReImportWizardForm', + 'This Bible already exists. Please import ' + 'a different Bible, delete the existing one or ' + 'uncheck.')) + self.versionNameEdit[number].setFocus() + return False + elif os.path.exists(os.path.join(self.newpath, + self.clean_filename(version_name))): + critical_error_message_box( + translate('BiblesPlugin.ReImportWizardForm', + 'Bible Exists'), + translate('BiblesPlugin.ReImportWizardForm', + 'This Bible already exists. Please import ' + 'a different Bible, delete the existing one or ' + 'uncheck.')) + self.versionNameEdit[number].setFocus() + return False + return True + if self.currentPage() == self.progressPage: + return True + + def setDefaults(self): + """ + Set default values for the wizard pages. + """ + log.debug(u'BibleReImport setDefaults') + settings = QtCore.QSettings() + settings.beginGroup(self.plugin.settingsSection) + self.stop_import_flag = False + self.success.clear() + self.newbibles.clear() + self.clearScrollArea() + self.files = SettingsManager.get_files(self.oldsettingsSection, + self.suffix) + self.addScrollArea() + self.customSignals() + self.retranslateUi() + self.maxBibles = len(self.files) + self.finishButton.setVisible(False) + self.cancelButton.setVisible(True) + for number, filename in enumerate(self.files): + self.checkBox[number].setCheckState(2) + if os.path.exists(os.path.join(self.newpath, filename)): + self.verticalWidget[number].setVisible(1) + self.formWidget[number].setVisible(1) + else: + self.verticalWidget[number].hide() + self.formWidget[number].hide() + self.progressLabelAfter.hide() + self.deleteCheckBox.hide() + self.deleteCheckBox.setCheckState(0) + self.deleteAllCheckBox.hide() + self.deleteAllCheckBox.setCheckState(0) + self.restart() + settings.endGroup() + + def preWizard(self): + """ + Prepare the UI for the import. + """ + OpenLPWizard.preWizard(self) + self.progressLabel.setText(translate( + 'BiblesPlugin.ImportWizardForm', + 'Starting Importing bible...')) + Receiver.send_message(u'openlp_process_events') + + def performWizard(self): + """ + Perform the actual import. + """ + include_webbible = False + proxy_server = None + if self.maxBibles == 0: + self.progressLabel.setText( + translate('BiblesPlugin.ReImportWizardForm', 'Sorry, but OpenLP' + ' could not find a Bible to reimport.')) + self.progressBar.hide() + return + self.maxBibles = 0 + for number, file in enumerate(self.files): + if self.checkBox[number].checkState() == 2: + self.maxBibles += 1 + number = 0 + for biblenumber, filename in enumerate(self.files): + bible_failed = False + self.success[biblenumber] = False + if not self.checkBox[biblenumber].checkState() == 2: + continue + self.progressBar.reset() + oldbible = OldBibleDB(self.parent, path=self.oldpath, file=filename) + name = oldbible.get_name() + if name is None: + delete_file(os.path.join(self.oldpath, filename)) + self.incrementProgressBar(unicode(translate( + 'BiblesPlugin.ReImportWizardForm', + 'Reimporting Bible %s of %s: "%s"\nFailed')) % + (number+1, self.maxBibles, name), + self.progressBar.maximum()-self.progressBar.value()) + number += 1 + continue + self.progressLabel.setText(unicode(translate( + 'BiblesPlugin.ReImportWizardForm', + 'Reimporting Bible %s of %s: "%s"\nImporting ...')) % + (number+1, self.maxBibles, name)) + if os.path.exists(os.path.join(self.newpath, filename)): + name = unicode(self.versionNameEdit[biblenumber].text()) + self.newbibles[number] = BibleDB(self.parent, path=self.oldpath, + name=name) + metadata = oldbible.get_metadata() + webbible = False + meta_data = {} + for meta in metadata: + meta_data[meta[u'key']] = meta[u'value'] + if not meta[u'key'] == u'Version': + self.newbibles[number].create_meta(meta[u'key'], + meta[u'value']) + else: + self.newbibles[number].create_meta(meta[u'key'], name) + if meta[u'key'] == u'download source': + webbible = True + include_webbible = True + if meta.has_key(u'proxy server'): + proxy_server = meta[u'proxy server'] + if webbible: + if meta_data[u'download source'].lower() == u'crosswalk': + handler = CWExtract(proxy_server) + elif meta_data[u'download source'].lower() == u'biblegateway': + handler = BGExtract(proxy_server) + elif meta_data[u'download source'].lower() == u'bibleserver': + handler = BSExtract(proxy_server) + books = handler.get_books_from_http(meta_data[u'download name']) + if not books: + log.exception(u'Importing books from %s - download '\ + u'name: "%s" failed' % ( + meta_data[u'download source'], + meta_data[u'download name'])) + delete_database(self.newpath, self.newbibles[number].\ + clean_filename(self.newbibles[number].get_name())) + del self.newbibles[number] + critical_error_message_box( + translate('BiblesPlugin.ReImportWizardForm', + 'Download Error'), + translate('BiblesPlugin.ReImportWizardForm', + 'To Re-Import your webbibles a Internet connection is ' + 'necessary. Please check your Internet connection, and ' + 'if this error continues to occur please consider ' + 'reporting a bug.')) + self.incrementProgressBar(unicode(translate( + 'BiblesPlugin.ReImportWizardForm', + 'Reimporting Bible %s of %s: "%s"\nFailed')) % + (number+1, self.maxBibles, name), + self.progressBar.maximum()-self.progressBar.value()) + number += 1 + continue + bible = BiblesResourcesDB.get_webbible( + meta_data[u'download name'], + meta_data[u'download source'].lower()) + if bible[u'language_id']: + language_id = bible[u'language_id'] + self.newbibles[number].create_meta(u'language_id', + language_id) + else: + language_id = self.newbibles[number].get_language() + if not language_id: + log.exception(u'Re-Importing from "%s" '\ + 'failed' % filename) + delete_database(self.newpath, self.newbibles[number].\ + clean_filename(self.newbibles[number].get_name())) + del self.newbibles[number] + self.incrementProgressBar(unicode(translate( + 'BiblesPlugin.ReImportWizardForm', + 'Reimporting Bible %s of %s: "%s"\nFailed')) % + (number+1, self.maxBibles, name), + self.progressBar.maximum()-self.progressBar.value()) + number += 1 + continue + self.progressBar.setMaximum(len(books)) + for book in books: + self.incrementProgressBar(unicode(translate( + 'BiblesPlugin.ReImportWizardForm', + 'Reimporting Bible %s of %s: "%s"\n' + 'Importing %s ...')) % + (number+1, self.maxBibles, name, book)) + book_ref_id = self.newbibles[number].\ + get_book_ref_id_by_name(book, language_id) + if not book_ref_id: + log.exception(u'Importing books from %s - download '\ + u'name: "%s" aborted by user' % ( + meta_data[u'download source'], + meta_data[u'download name'])) + delete_database(self.newpath, self.newbibles[number].\ + clean_filename(self.newbibles[number].get_name())) + del self.newbibles[number] + bible_failed = True + break + book_details = BiblesResourcesDB.get_book_by_id(book_ref_id) + self.newbibles[number].create_book(book, book_ref_id, + book_details[u'testament_id']) + else: + language_id = self.newbibles[number].get_object(BibleMeta, + u'language_id') + if not language_id: + language_id = self.newbibles[number].get_language() + if not language_id: + log.exception(u'Importing books from "%s" '\ + 'failed' % name) + delete_database(self.newpath, self.newbibles[number].\ + clean_filename(self.newbibles[number].get_name())) + del self.newbibles[number] + self.incrementProgressBar(unicode(translate( + 'BiblesPlugin.ReImportWizardForm', + 'Reimporting Bible %s of %s: "%s"\nFailed')) % + (number+1, self.maxBibles, name), + self.progressBar.maximum()-self.progressBar.value()) + number += 1 + continue + books = oldbible.get_books() + self.progressBar.setMaximum(len(books)) + for book in books: + self.incrementProgressBar(unicode(translate( + 'BiblesPlugin.ReImportWizardForm', + 'Reimporting Bible %s of %s: "%s"\n' + 'Importing %s ...')) % + (number+1, self.maxBibles, name, book[u'name'])) + book_ref_id = self.newbibles[number].\ + get_book_ref_id_by_name(book[u'name'], language_id) + if not book_ref_id: + log.exception(u'Importing books from %s " '\ + 'failed - aborted by user' % name) + delete_database(self.newpath, self.newbibles[number].\ + clean_filename(self.newbibles[number].get_name())) + del self.newbibles[number] + bible_failed = True + break + book_details = BiblesResourcesDB.get_book_by_id(book_ref_id) + db_book = self.newbibles[number].create_book(book[u'name'], + book_ref_id, book_details[u'testament_id']) + verses = oldbible.get_verses(book[u'id']) + for verse in verses: + self.newbibles[number].create_verse(db_book.id, + int(verse[u'chapter']), + int(verse[u'verse']), unicode(verse[u'text'])) + Receiver.send_message(u'openlp_process_events') + if not bible_failed: + self.incrementProgressBar(unicode(translate( + 'BiblesPlugin.ReImportWizardForm', + 'Reimporting Bible %s of %s: "%s"\n' + 'Done')) % + (number+1, self.maxBibles, name)) + self.success[biblenumber] = True + else: + self.incrementProgressBar(unicode(translate( + 'BiblesPlugin.ReImportWizardForm', + 'Reimporting Bible %s of %s: "%s"\nFailed')) % + (number+1, self.maxBibles, name), + self.progressBar.maximum()-self.progressBar.value()) + number += 1 + self.parent.reloadBibles() + successful_import = 0 + failed_import = 0 + for number, success in self.success.iteritems(): + if success == True: + successful_import += 1 + elif success == False and self.checkBox[number].checkState() == 2: + failed_import += 1 + if failed_import > 0: + failed_import_text = u' And ' + unicode(failed_import) + \ + u' reimport fails.' + else: + failed_import_text = u'' + if successful_import > 0: + if include_webbible: + self.progressLabel.setText(unicode( + translate('BiblesPlugin.ReImportWizardForm', 'Reimport %s ' + 'bibles successful.%s\nPlease note, that verses from ' + 'webbibles will be downloaded\non demand and thus an ' + 'internet connection is required.')) % + (successful_import, failed_import_text)) + else: + self.progressLabel.setText(unicode( + translate('BiblesPlugin.ReImportWizardForm', 'Reimport %s ' + 'bibles successful.%s')) % (successful_import, + failed_import_text)) + self.deleteCheckBox.setVisible(1) + bibles = u'' + for bible in self.newbibles.itervalues(): + name = bible.get_name() + bibles += u'\n"' + name + u'"' + self.deleteCheckBox.setToolTip(unicode(translate( + 'BiblesPlugin.ReImportWizardForm', + 'Sucessful imported bible(s):%s')) % bibles) + else: + self.progressLabel.setText( + translate('BiblesPlugin.ReImportWizardForm', 'Reimport ' + 'failed.')) + self.progressLabelAfter.setVisible(1) + self.deleteAllCheckBox.setVisible(1) diff --git a/openlp/plugins/bibles/lib/db.py b/openlp/plugins/bibles/lib/db.py index 7b22b9483..6dd7b3cbc 100644 --- a/openlp/plugins/bibles/lib/db.py +++ b/openlp/plugins/bibles/lib/db.py @@ -931,3 +931,125 @@ class AlternativeBookNamesDB(QtCore.QObject, Manager): u'alternative_book_names(book_reference_id, language_id, name) ' u'VALUES (?, ?, ?)', (book_reference_id, language_id, name), True) return alternative_book_name + + +class OldBibleDB(QtCore.QObject, Manager): + """ + This class conects to the old bible databases to reimport them to the new + database scheme. + """ + cursor = None + + def __init__(self, parent, **kwargs): + """ + The constructor loads up the database and creates and initialises the + tables if the database doesn't exist. + + **Required keyword arguments:** + + ``path`` + The path to the bible database file. + + ``name`` + The name of the database. This is also used as the file name for + SQLite databases. + """ + log.info(u'OldBibleDB loaded') + QtCore.QObject.__init__(self) + if u'path' not in kwargs: + raise KeyError(u'Missing keyword argument "path".') + if u'file' not in kwargs: + raise KeyError(u'Missing keyword argument "file".') + if u'path' in kwargs: + self.path = kwargs[u'path'] + if u'file' in kwargs: + self.file = kwargs[u'file'] + + def get_cursor(self): + """ + Return the cursor object. Instantiate one if it doesn't exist yet. + """ + if self.cursor is None: + filepath = os.path.join(self.path, self.file) + conn = sqlite3.connect(filepath) + self.cursor = conn.cursor() + return self.cursor + + def run_sql(self, query, parameters=()): + """ + Run an SQL query on the database, returning the results. + + ``query`` + The actual SQL query to run. + + ``parameters`` + Any variable parameters to add to the query. + """ + cursor = self.get_cursor() + cursor.execute(query, parameters) + return cursor.fetchall() + + def get_name(self): + """ + Returns the version name of the Bible. + """ + version_name = self.run_sql(u'SELECT value FROM ' + u'metadata WHERE key = "Version"') + if version_name: + self.name = version_name[0][0] + else: + self.name = None + return self.name + + def get_metadata(self): + """ + Returns the metadata of the Bible. + """ + metadata = self.run_sql(u'SELECT key, value FROM metadata ' + u'ORDER BY rowid') + if metadata: + metadata_list = [] + for meta in metadata: + metadata_list.append({ + u'key': unicode(meta[0]), + u'value': unicode(meta[1]) + }) + else: + metadata_list = None + return metadata_list + + def get_books(self): + """ + Returns the books of the Bible. + """ + books = self.run_sql(u'SELECT name, id FROM book ORDER BY id') + if books: + book_list = [] + for book in books: + book_list.append({ + u'name': unicode(book[0]), + u'id':int(book[1]) + }) + else: + book_list = None + return book_list + + def get_verses(self, book_id): + """ + Returns the verses of the Bible. + """ + verses = self.run_sql(u'SELECT book_id, chapter, verse, text FROM ' + u'verse WHERE book_id = ? ORDER BY id', (book_id, )) + if verses: + verse_list = [] + for verse in verses: + verse_list.append({ + u'book_id': int(verse[0]), + u'chapter': int(verse[1]), + u'verse': int(verse[2]), + u'text': unicode(verse[3]) + }) + else: + verse_list = None + return verse_list + diff --git a/openlp/plugins/bibles/lib/mediaitem.py b/openlp/plugins/bibles/lib/mediaitem.py index bd7a5ae85..1b7bf90ce 100644 --- a/openlp/plugins/bibles/lib/mediaitem.py +++ b/openlp/plugins/bibles/lib/mediaitem.py @@ -33,7 +33,7 @@ from openlp.core.lib import MediaManagerItem, Receiver, ItemCapabilities, \ from openlp.core.lib.searchedit import SearchEdit from openlp.core.lib.ui import UiStrings, add_widget_completer, \ media_item_combo_box, critical_error_message_box, find_and_set_in_combo_box -from openlp.plugins.bibles.forms import BibleImportForm +from openlp.plugins.bibles.forms import BibleImportForm, BibleReImportForm from openlp.plugins.bibles.lib import LayoutStyle, DisplayStyle, \ VerseReferenceList, get_reference_match @@ -310,6 +310,14 @@ class BibleMediaItem(MediaManagerItem): if self.import_wizard.exec_(): self.reloadBibles() + def onReImportClick(self): + if not hasattr(self, u'import_wizard'): + self.import_wizard = BibleReImportForm(self, self.parent.manager, + self.parent) + # If the import was not cancelled then reload. + if self.import_wizard.exec_(): + self.reloadBibles() + def loadBibles(self): log.debug(u'Loading Bibles') self.quickVersionComboBox.clear() @@ -849,4 +857,4 @@ class BibleMediaItem(MediaManagerItem): self.settings.layout_style) QtCore.QSettings().setValue( self.settingsSection + u'/verse layout style', - QtCore.QVariant(self.settings.layout_style)) \ No newline at end of file + QtCore.QVariant(self.settings.layout_style)) diff --git a/resources/images/bibles_reimport_alert.png b/resources/images/bibles_reimport_alert.png new file mode 100644 index 0000000000000000000000000000000000000000..331aa268725a4edff3fa6cab7dfaf5af24708c2c GIT binary patch literal 762 zcmVz8xpUII{8&=iH{wnUDxx6o*XQpr9@S zFA7f~5wyArj)7engn2gzstbkiqQW4^o2U%CF~JzoO$Y@oEjOFGxwX#D=9!*z-Y(o0 zQwbk<`S`x?dETGrWkiIXV2m*U4FEj(r*8lvv=^C(b_IaeKp-$7%W^`Nt(9kFmQEb*nE7Psy^?IqR ztBayjPKwQXiHJy&qz3@_5)S~tZnyVDm%lIP5+5is35raDTrL;6T(06>jn7at{N)#b z6NTa?0O;-Qt@Qi-eRcKC_36+(fN|S~@H}|_-^lXUJE&`DvkeRkTqt;90$|BxGRLp` z`_FAAgHTsr1Ed20I-3=AHY>#hx%don>+f;v=GF56+8JZu1VM0DR8;s+oj!Xq`ROt= zB~%pnI#Td;q)OJLXMdu$eUO)BITH*9=a|Ri@x7aV`>56uZi>(Ll#p-S-98`QF5Pu? z_YC6M`lSYE%SBUFRn<|4v#}`^ewD>Op@g67c8A+32*R;4RaJ9_VQ3cj;Fel`NG<2K z4it!wpY0ZJYUYhH+a;BVtcGD|0MIfrGV&yqO2ufONT<`uv9Yli0FE#K41f(l8-N-B s|?9jsO4v literal 0 HcmV?d00001