This commit is contained in:
Jonathan Corwin 2011-05-29 16:33:09 +01:00
commit 02da22c349
28 changed files with 2353 additions and 578 deletions

7
documentation/manual.txt Normal file
View File

@ -0,0 +1,7 @@
OpenLP Manual
=============
If you're reading this file, you're probably looking for the OpenLP manual. The
manual is hosted online at http://manual.openlp.org/. If you want to help with
the manual, contact the OpenLP team via IRC in the #openlp.org channel on the
Freenode network.

View File

@ -133,6 +133,7 @@ class OpenLP(QtGui.QApplication):
u'general/update check', QtCore.QVariant(True)).toBool()
if update_check:
VersionThread(self.mainWindow).start()
self.mainWindow.appStartup()
DelayStartThread(self.mainWindow).start()
return self.exec_()

View File

@ -34,6 +34,7 @@ from PyQt4 import QtCore
from sqlalchemy import create_engine, MetaData
from sqlalchemy.exc import InvalidRequestError
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.pool import NullPool
from openlp.core.utils import AppLocation, delete_file
@ -52,7 +53,7 @@ def init_db(url, auto_flush=True, auto_commit=False):
``auto_commit``
Sets the commit behaviour of the session
"""
engine = create_engine(url)
engine = create_engine(url, poolclass=NullPool)
metadata = MetaData(bind=engine)
session = scoped_session(sessionmaker(autoflush=auto_flush,
autocommit=auto_commit, bind=engine))

View File

@ -651,6 +651,15 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
self.setViewMode(False, True, False, False, True)
self.modeLiveItem.setChecked(True)
def appStartup(self):
# Give all the plugins a chance to perform some tasks at startup
Receiver.send_message(u'openlp_process_events')
for plugin in self.pluginManager.plugins:
if hasattr(plugin, u'appStartup'):
Receiver.send_message(u'openlp_process_events')
plugin.appStartup()
Receiver.send_message(u'openlp_process_events')
def firstTime(self):
# Import themes if first time
Receiver.send_message(u'openlp_process_events')

View File

@ -64,7 +64,7 @@ class SlideController(QtGui.QWidget):
float(self.screens.current[u'size'].height())
self.image_manager = self.parent().image_manager
self.loopList = [
u'Start Loop',
u'Play Slides Menu',
u'Loop Separator',
u'Image SpinBox'
]
@ -151,6 +151,7 @@ class SlideController(QtGui.QWidget):
context=QtCore.Qt.WidgetWithChildrenShortcut)
self.toolbar.addToolbarSeparator(u'Close Separator')
if self.isLive:
# Hide Menu
self.hideMenu = QtGui.QToolButton(self.toolbar)
self.hideMenu.setText(translate('OpenLP.SlideController', 'Hide'))
self.hideMenu.setPopupMode(QtGui.QToolButton.MenuButtonPopup)
@ -178,27 +179,34 @@ class SlideController(QtGui.QWidget):
self.hideMenu.menu().addAction(self.themeScreen)
self.hideMenu.menu().addAction(self.desktopScreen)
self.toolbar.addToolbarSeparator(u'Loop Separator')
startLoop = self.toolbar.addToolbarButton(
# Does not need translating - control string.
u'Start Loop', u':/media/media_time.png',
translate('OpenLP.SlideController', 'Enable timed slides.'),
self.onStartLoop)
startLoop.setObjectName(u'startLoop')
action_list = ActionList.get_instance()
action_list.add_action(startLoop, UiStrings().LiveToolbar)
stopLoop = self.toolbar.addToolbarButton(
# Does not need translating - control string.
u'Stop Loop', u':/media/media_stop.png',
translate('OpenLP.SlideController', 'Stop timed slides.'),
self.onStopLoop)
stopLoop.setObjectName(u'stopLoop')
action_list.add_action(stopLoop, UiStrings().LiveToolbar)
self.toogleLoop = shortcut_action(self, u'toogleLoop',
[QtGui.QKeySequence(u'L')], self.onToggleLoop,
category=UiStrings().LiveToolbar)
self.toogleLoop.setText(translate('OpenLP.SlideController',
'Start/Stop continuous loop'))
self.addAction(self.toogleLoop)
# Play Slides Menu
self.playSlidesMenu = QtGui.QToolButton(self.toolbar)
self.playSlidesMenu.setText(translate('OpenLP.SlideController',
'Play Slides'))
self.playSlidesMenu.setPopupMode(QtGui.QToolButton.MenuButtonPopup)
self.toolbar.addToolbarWidget(u'Play Slides Menu',
self.playSlidesMenu)
self.playSlidesMenu.setMenu(QtGui.QMenu(
translate('OpenLP.SlideController', 'Play Slides'),
self.toolbar))
self.playSlidesLoop = shortcut_action(self.playSlidesMenu,
u'playSlidesLoop', [], self.onPlaySlidesLoop,
u':/media/media_time.png', False, UiStrings().LiveToolbar)
self.playSlidesLoop.setText(
translate('OpenLP.SlideController', 'Play Slides in Loop'))
self.playSlidesOnce = shortcut_action(self.playSlidesMenu,
u'playSlidesOnce', [], self.onPlaySlidesOnce,
u':/media/media_time.png', False, UiStrings().LiveToolbar)
self.playSlidesOnce.setText(
translate('OpenLP.SlideController', 'Play Slides to End'))
if QtCore.QSettings().value(self.parent.generalSettingsSection +
u'/enable slide loop', QtCore.QVariant(True)).toBool():
self.playSlidesMenu.setDefaultAction(self.playSlidesLoop)
else:
self.playSlidesMenu.setDefaultAction(self.playSlidesOnce)
self.playSlidesMenu.menu().addAction(self.playSlidesLoop)
self.playSlidesMenu.menu().addAction(self.playSlidesOnce)
# Loop Delay Spinbox
self.delaySpinBox = QtGui.QSpinBox()
self.delaySpinBox.setRange(1, 180)
self.toolbar.addToolbarWidget(u'Image SpinBox', self.delaySpinBox)
@ -319,7 +327,6 @@ class SlideController(QtGui.QWidget):
QtCore.SIGNAL(u'slidecontroller_live_spin_delay'),
self.receiveSpinDelay)
self.toolbar.makeWidgetsInvisible(self.loopList)
self.toolbar.actions[u'Stop Loop'].setVisible(False)
else:
QtCore.QObject.connect(self.previewListWidget,
QtCore.SIGNAL(u'doubleClicked(QModelIndex)'),
@ -494,10 +501,6 @@ class SlideController(QtGui.QWidget):
self.mediabar.setVisible(False)
self.toolbar.makeWidgetsInvisible([u'Song Menu'])
self.toolbar.makeWidgetsInvisible(self.loopList)
self.toogleLoop.setEnabled(False)
self.toolbar.actions[u'Start Loop'].setEnabled(False)
self.toolbar.actions[u'Stop Loop'].setEnabled(False)
self.toolbar.actions[u'Stop Loop'].setVisible(False)
if item.is_text():
if QtCore.QSettings().value(
self.parent().songsSettingsSection + u'/display songbar',
@ -506,9 +509,6 @@ class SlideController(QtGui.QWidget):
if item.is_capable(ItemCapabilities.AllowsLoop) and \
len(item.get_frames()) > 1:
self.toolbar.makeWidgetsVisible(self.loopList)
self.toogleLoop.setEnabled(True)
self.toolbar.actions[u'Start Loop'].setEnabled(True)
self.toolbar.actions[u'Stop Loop'].setEnabled(True)
if item.is_media():
self.toolbar.setVisible(False)
self.mediabar.setVisible(True)
@ -941,7 +941,7 @@ class SlideController(QtGui.QWidget):
rect.y(), rect.width(), rect.height())
self.slidePreview.setPixmap(winimg)
def onSlideSelectedNext(self):
def onSlideSelectedNext(self, wrap=None):
"""
Go to the next slide.
"""
@ -954,8 +954,11 @@ class SlideController(QtGui.QWidget):
else:
row = self.previewListWidget.currentRow() + 1
if row == self.previewListWidget.rowCount():
if QtCore.QSettings().value(self.parent().generalSettingsSection
+ u'/enable slide loop', QtCore.QVariant(True)).toBool():
if wrap is None:
wrap = QtCore.QSettings().value(
self.parent().generalSettingsSection +
u'/enable slide loop', QtCore.QVariant(True)).toBool()
if wrap:
row = 0
else:
row = self.previewListWidget.rowCount() - 1
@ -1004,11 +1007,11 @@ class SlideController(QtGui.QWidget):
self.previewListWidget.rowCount() - 1)
self.slideSelected()
def onToggleLoop(self, toggled):
def onToggleLoop(self):
"""
Toggles the loop state.
"""
if self.toolbar.actions[u'Start Loop'].isVisible():
if self.playSlidesLoop.isChecked() or self.playSlidesOnce.isChecked():
self.onStartLoop()
else:
self.onStopLoop()
@ -1020,8 +1023,6 @@ class SlideController(QtGui.QWidget):
if self.previewListWidget.rowCount() > 1:
self.timer_id = self.startTimer(
int(self.delaySpinBox.value()) * 1000)
self.toolbar.actions[u'Stop Loop'].setVisible(True)
self.toolbar.actions[u'Start Loop'].setVisible(False)
def onStopLoop(self):
"""
@ -1030,15 +1031,39 @@ class SlideController(QtGui.QWidget):
if self.timer_id != 0:
self.killTimer(self.timer_id)
self.timer_id = 0
self.toolbar.actions[u'Start Loop'].setVisible(True)
self.toolbar.actions[u'Stop Loop'].setVisible(False)
def onPlaySlidesLoop(self, checked=None):
"""
Start or stop 'Play Slides in Loop'
"""
if checked is None:
checked = self.playSlidesLoop.isChecked()
else:
self.playSlidesLoop.setChecked(checked)
log.debug(u'onPlaySlidesLoop %s' % checked)
self.playSlidesMenu.setDefaultAction(self.playSlidesLoop)
self.playSlidesOnce.setChecked(False)
self.onToggleLoop()
def onPlaySlidesOnce(self, checked=None):
"""
Start or stop 'Play Slides to End'
"""
if checked is None:
checked = self.playSlidesOnce.isChecked()
else:
self.playSlidesOnce.setChecked(checked)
log.debug(u'onPlaySlidesOnce %s' % checked)
self.playSlidesMenu.setDefaultAction(self.playSlidesOnce)
self.playSlidesLoop.setChecked(False)
self.onToggleLoop()
def timerEvent(self, event):
"""
If the timer event is for this window select next slide
"""
if event.timerId() == self.timer_id:
self.onSlideSelectedNext()
self.onSlideSelectedNext(self.playSlidesLoop.isChecked())
def onEditSong(self):
"""

View File

@ -33,6 +33,7 @@ from openlp.core.lib import Plugin, StringContent, build_icon, translate
from openlp.core.lib.ui import base_action, UiStrings
from openlp.core.utils.actions import ActionList
from openlp.plugins.bibles.lib import BibleManager, BiblesTab, BibleMediaItem
from openlp.plugins.bibles.forms import BibleUpgradeForm
log = logging.getLogger(__name__)
@ -59,6 +60,8 @@ class BiblePlugin(Plugin):
#action_list.add_action(self.exportBibleItem, UiStrings().Export)
# Set to invisible until we can export bibles
self.exportBibleItem.setVisible(False)
if len(self.manager.old_bible_databases):
self.toolsUpgradeItem.setVisible(True)
def finalise(self):
"""
@ -73,6 +76,19 @@ class BiblePlugin(Plugin):
#action_list.remove_action(self.exportBibleItem, UiStrings().Export)
self.exportBibleItem.setVisible(False)
def appStartup(self):
"""
Perform tasks on application starup
"""
if len(self.manager.old_bible_databases):
if QtGui.QMessageBox.information(self.formparent,
translate('OpenLP', 'Information'), translate('OpenLP',
'Bible format has changed.\nYou have to upgrade your '
'existing Bibles.\nShould OpenLP upgrade now?'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes |
QtGui.QMessageBox.No)) == QtGui.QMessageBox.Yes:
self.onToolsUpgradeItemTriggered()
def addImportMenuItem(self, import_menu):
self.importBibleItem = base_action(import_menu, u'importBibleItem')
self.importBibleItem.setText(translate('BiblesPlugin', '&Bible'))
@ -88,6 +104,39 @@ class BiblePlugin(Plugin):
export_menu.addAction(self.exportBibleItem)
self.exportBibleItem.setVisible(False)
def addToolsMenuItem(self, tools_menu):
"""
Give the bible 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.debug(u'add tools menu')
self.toolsUpgradeItem = QtGui.QAction(tools_menu)
self.toolsUpgradeItem.setObjectName(u'toolsUpgradeItem')
self.toolsUpgradeItem.setText(
translate('BiblePlugin', '&Upgrade older Bibles'))
self.toolsUpgradeItem.setStatusTip(
translate('BiblePlugin', 'Upgrade the Bible databases to the '
'latest format'))
tools_menu.addAction(self.toolsUpgradeItem)
QtCore.QObject.connect(self.toolsUpgradeItem,
QtCore.SIGNAL(u'triggered()'), self.onToolsUpgradeItemTriggered)
self.toolsUpgradeItem.setVisible(False)
def onToolsUpgradeItemTriggered(self):
"""
Upgrade older bible databases.
"""
if not hasattr(self, u'upgrade_wizard'):
self.upgrade_wizard = BibleUpgradeForm(self.formparent,
self.manager, self)
# If the import was not cancelled then reload.
if self.upgrade_wizard.exec_():
self.mediaItem.reloadBibles()
def onBibleImportClick(self):
if self.mediaItem:
self.mediaItem.onImportClick()
@ -149,4 +198,3 @@ class BiblePlugin(Plugin):
'Add the selected Bible to the service.')
}
self.setPluginUiTextStrings(tooltips)

View File

@ -51,7 +51,10 @@ This allows OpenLP to use ``self.object`` for all the GUI elements while keeping
them separate from the functionality, so that it is easier to recreate the GUI
from the .ui files later if necessary.
"""
from booknameform import BookNameForm
from languageform import LanguageForm
from bibleimportform import BibleImportForm
from bibleupgradeform import BibleUpgradeForm
__all__ = ['BibleImportForm']
__all__ = [u'BookNameForm', u'LanguageForm', u'BibleImportForm',
u'BibleUpgradeForm']

View File

@ -41,6 +41,7 @@ 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, string_is_unicode
from openlp.plugins.bibles.lib.manager import BibleFormat
from openlp.plugins.bibles.lib.db import BiblesResourcesDB, clean_filename
log = logging.getLogger(__name__)
@ -125,9 +126,6 @@ class BibleImportForm(OpenLPWizard):
QtCore.QObject.connect(self.osisBrowseButton,
QtCore.SIGNAL(u'clicked()'),
self.onOsisBrowseButtonClicked)
QtCore.QObject.connect(self.csvTestamentsButton,
QtCore.SIGNAL(u'clicked()'),
self.onCsvTestamentsBrowseButtonClicked)
QtCore.QObject.connect(self.csvBooksButton,
QtCore.SIGNAL(u'clicked()'),
self.onCsvBooksBrowseButtonClicked)
@ -188,18 +186,6 @@ class BibleImportForm(OpenLPWizard):
self.csvLayout = QtGui.QFormLayout(self.csvWidget)
self.csvLayout.setMargin(0)
self.csvLayout.setObjectName(u'CsvLayout')
self.csvTestamentsLabel = QtGui.QLabel(self.csvWidget)
self.csvTestamentsLabel.setObjectName(u'CsvTestamentsLabel')
self.csvTestamentsLayout = QtGui.QHBoxLayout()
self.csvTestamentsLayout.setObjectName(u'CsvTestamentsLayout')
self.csvTestamentsEdit = QtGui.QLineEdit(self.csvWidget)
self.csvTestamentsEdit.setObjectName(u'CsvTestamentsEdit')
self.csvTestamentsLayout.addWidget(self.csvTestamentsEdit)
self.csvTestamentsButton = QtGui.QToolButton(self.csvWidget)
self.csvTestamentsButton.setIcon(self.openIcon)
self.csvTestamentsButton.setObjectName(u'CsvTestamentsButton')
self.csvTestamentsLayout.addWidget(self.csvTestamentsButton)
self.csvLayout.addRow(self.csvTestamentsLabel, self.csvTestamentsLayout)
self.csvBooksLabel = QtGui.QLabel(self.csvWidget)
self.csvBooksLabel.setObjectName(u'CsvBooksLabel')
self.csvBooksLayout = QtGui.QHBoxLayout()
@ -384,8 +370,6 @@ class BibleImportForm(OpenLPWizard):
translate('BiblesPlugin.ImportWizardForm', 'Bible file:'))
self.osisFileLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Bible file:'))
self.csvTestamentsLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Testaments file:'))
self.csvBooksLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Books file:'))
self.csvVersesLabel.setText(
@ -436,7 +420,6 @@ class BibleImportForm(OpenLPWizard):
# Align all QFormLayouts towards each other.
labelWidth = max(self.formatLabel.minimumSizeHint().width(),
self.osisFileLabel.minimumSizeHint().width(),
self.csvTestamentsLabel.minimumSizeHint().width(),
self.csvBooksLabel.minimumSizeHint().width(),
self.csvVersesLabel.minimumSizeHint().width(),
self.openSongFileLabel.minimumSizeHint().width(),
@ -458,14 +441,6 @@ class BibleImportForm(OpenLPWizard):
self.osisFileEdit.setFocus()
return False
elif self.field(u'source_format').toInt()[0] == BibleFormat.CSV:
if not self.field(u'csv_testamentsfile').toString():
answer = critical_error_message_box(UiStrings().NFSs,
translate('BiblesPlugin.ImportWizardForm',
'You have not specified a testaments file. Do you '
'want to proceed with the import?'), question=True)
if answer == QtGui.QMessageBox.No:
self.csvTestamentsEdit.setFocus()
return False
if not self.field(u'csv_booksfile').toString():
critical_error_message_box(UiStrings().NFSs,
translate('BiblesPlugin.ImportWizardForm',
@ -498,6 +473,7 @@ class BibleImportForm(OpenLPWizard):
license_version = unicode(self.field(u'license_version').toString())
license_copyright = \
unicode(self.field(u'license_copyright').toString())
path = AppLocation.get_section_data_path(u'bibles')
if not license_version:
critical_error_message_box(UiStrings().EmptyField,
translate('BiblesPlugin.ImportWizardForm',
@ -519,6 +495,15 @@ class BibleImportForm(OpenLPWizard):
'a different Bible or first delete the existing one.'))
self.versionNameEdit.setFocus()
return False
elif os.path.exists(os.path.join(path, clean_filename(
license_version))):
critical_error_message_box(
translate('BiblesPlugin.ImportWizardForm', 'Bible Exists'),
translate('BiblesPlugin.ImportWizardForm',
'This Bible already exists. Please import '
'a different Bible or first delete the existing one.'))
self.versionNameEdit.setFocus()
return False
return True
if self.currentPage() == self.progressPage:
return True
@ -543,14 +528,6 @@ class BibleImportForm(OpenLPWizard):
self.getFileName(WizardStrings.OpenTypeFile % WizardStrings.OSIS,
self.osisFileEdit)
def onCsvTestamentsBrowseButtonClicked(self):
"""
Show the file open dialog for the testaments CSV file.
"""
self.getFileName(WizardStrings.OpenTypeFile % WizardStrings.CSV,
self.csvTestamentsEdit, u'%s (*.csv)'
% translate('BiblesPlugin.ImportWizardForm', 'CSV File'))
def onCsvBooksBrowseButtonClicked(self):
"""
Show the file open dialog for the books CSV file.
@ -589,8 +566,6 @@ class BibleImportForm(OpenLPWizard):
"""
self.selectPage.registerField(u'source_format', self.formatComboBox)
self.selectPage.registerField(u'osis_location', self.osisFileEdit)
self.selectPage.registerField(
u'csv_testamentsfile', self.csvTestamentsEdit)
self.selectPage.registerField(u'csv_booksfile', self.csvBooksEdit)
self.selectPage.registerField(u'csv_versefile', self.csvVersesEdit)
self.selectPage.registerField(u'opensong_file', self.openSongFileEdit)
@ -619,7 +594,6 @@ class BibleImportForm(OpenLPWizard):
self.cancelButton.setVisible(True)
self.setField(u'source_format', QtCore.QVariant(0))
self.setField(u'osis_location', QtCore.QVariant(''))
self.setField(u'csv_testamentsfile', QtCore.QVariant(''))
self.setField(u'csv_booksfile', QtCore.QVariant(''))
self.setField(u'csv_versefile', QtCore.QVariant(''))
self.setField(u'opensong_file', QtCore.QVariant(''))
@ -646,46 +620,27 @@ class BibleImportForm(OpenLPWizard):
"""
Load the lists of Crosswalk, BibleGateway and Bibleserver bibles.
"""
filepath = AppLocation.get_directory(AppLocation.PluginsDir)
filepath = os.path.join(filepath, u'bibles', u'resources')
# Load Crosswalk Bibles.
self.loadBibleResourceFile(
os.path.join(filepath, u'crosswalkbooks.csv'),
WebDownload.Crosswalk)
self.loadBibleResource(WebDownload.Crosswalk)
# Load BibleGateway Bibles.
self.loadBibleResourceFile(os.path.join(filepath, u'biblegateway.csv'),
WebDownload.BibleGateway)
self.loadBibleResource(WebDownload.BibleGateway)
# Load and Bibleserver Bibles.
self.loadBibleResourceFile(os.path.join(filepath, u'bibleserver.csv'),
WebDownload.Bibleserver)
self.loadBibleResource(WebDownload.Bibleserver)
def loadBibleResourceFile(self, file_path_name, download_type):
def loadBibleResource(self, download_type):
"""
Loads a web bible resource file.
``file_path_name``
The file to load including the file's path.
Loads a web bible from bible_resources.sqlite.
``download_type``
The WebDownload type this file is for.
The WebDownload type e.g. bibleserver.
"""
self.web_bible_list[download_type] = {}
books_file = None
try:
books_file = open(file_path_name, 'rb')
dialect = csv.Sniffer().sniff(books_file.read(1024))
books_file.seek(0)
books_reader = csv.reader(books_file, dialect)
for line in books_reader:
ver = string_is_unicode(line[0])
name = string_is_unicode(line[1])
self.web_bible_list[download_type][ver] = name.strip()
except IOError:
log.exception(u'%s resources missing' %
WebDownload.Names[download_type])
finally:
if books_file:
books_file.close()
bibles = BiblesResourcesDB.get_webbibles(
WebDownload.Names[download_type])
for bible in bibles:
version = bible[u'name']
name = bible[u'abbreviation']
self.web_bible_list[download_type][version] = name.strip()
def preWizard(self):
"""
@ -720,8 +675,7 @@ class BibleImportForm(OpenLPWizard):
elif bible_type == BibleFormat.CSV:
# Import a CSV bible.
importer = self.manager.import_bible(BibleFormat.CSV,
name=license_version, testamentsfile=unicode(
self.field(u'csv_testamentsfile').toString()),
name=license_version,
booksfile=unicode(self.field(u'csv_booksfile').toString()),
versefile=unicode(self.field(u'csv_versefile').toString())
)
@ -752,7 +706,7 @@ class BibleImportForm(OpenLPWizard):
name=license_version,
filename=unicode(self.field(u'openlp1_location').toString())
)
if importer.do_import():
if importer.do_import(license_version):
self.manager.save_meta_data(license_version, license_version,
license_copyright, license_permissions)
self.manager.reload_bibles()

View File

@ -0,0 +1,779 @@
# -*- 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.path
import re
import shutil
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, clean_filename
from openlp.plugins.bibles.lib.http import BSExtract, BGExtract, CWExtract
log = logging.getLogger(__name__)
class BibleUpgradeForm(OpenLPWizard):
"""
This is the Bible Upgrade Wizard, which allows easy importing of Bibles
into OpenLP from older OpenLP2 database versions.
"""
log.info(u'BibleUpgradeForm 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.mediaItem = bibleplugin.mediaItem
self.suffix = u'.sqlite'
self.settingsSection = u'bibles'
self.path = AppLocation.get_section_data_path(
self.settingsSection)
self.files = self.manager.old_bible_databases
self.success = {}
self.newbibles = {}
OpenLPWizard.__init__(self, parent, bibleplugin, u'bibleUpgradeWizard',
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 onCheckBoxIndexChanged(self, index):
"""
Show/ Hide warnings if CheckBox state has changed
"""
for number, filename in enumerate(self.files):
if not self.checkBox[number].checkState() == QtCore.Qt.Checked:
self.verticalWidget[number].hide()
self.formWidget[number].hide()
else:
version_name = unicode(self.versionNameEdit[number].text())
if self.manager.exists(version_name):
self.verticalWidget[number].show()
self.formWidget[number].show()
def reject(self):
"""
Stop the wizard on cancel button, close button or ESC key.
"""
log.debug(u'Wizard cancelled by user')
self.stop_import_flag = True
if not self.currentPage() == self.progressPage:
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
"""
for number, filename in enumerate(self.files):
if number in self.success and self.success[number] == True:
delete_file(os.path.join(self.path, filename[0]))
def onBackupBrowseButtonClicked(self):
"""
Show the file open dialog for the OSIS file.
"""
filename = QtGui.QFileDialog.getExistingDirectory(self, translate(
'BiblesPlugin.UpgradeWizardForm', 'Select a Backup Directory'),
os.path.dirname(SettingsManager.get_last_dir(
self.plugin.settingsSection, 1)))
if filename:
self.backupDirectoryEdit.setText(filename)
SettingsManager.set_last_dir(self.plugin.settingsSection,
filename, 1)
def onNoBackupCheckBoxToggled(self, checked):
"""
Enable or disable the backup directory widgets.
"""
self.backupDirectoryEdit.setEnabled(not checked)
self.backupBrowseButton.setEnabled(not checked)
def backupOldBibles(self, backupdirectory):
"""
Backup old bible databases in a given folder.
"""
for filename in self.files:
try:
shutil.copy(os.path.join(self.path, filename[0]),
backupdirectory)
except:
return False
return True
def customInit(self):
"""
Perform any custom initialisation for bible upgrading.
"""
self.manager.set_process_dialog(self)
self.restart()
def customSignals(self):
"""
Set up the signals used in the bible importer.
"""
QtCore.QObject.connect(self.finishButton,
QtCore.SIGNAL(u'clicked()'), self.onFinishButton)
QtCore.QObject.connect(self.backupBrowseButton,
QtCore.SIGNAL(u'clicked()'), self.onBackupBrowseButtonClicked)
QtCore.QObject.connect(self.noBackupCheckBox,
QtCore.SIGNAL(u'toggled(bool)'), self.onNoBackupCheckBoxToggled)
def addCustomPages(self):
"""
Add the bible import specific wizard pages.
"""
# Backup Page
self.backupPage = QtGui.QWizardPage()
self.backupPage.setObjectName(u'BackupPage')
self.backupLayout = QtGui.QVBoxLayout(self.backupPage)
self.backupLayout.setObjectName(u'BackupLayout')
self.backupInfoLabel = QtGui.QLabel(self.backupPage)
self.backupInfoLabel.setOpenExternalLinks(True)
self.backupInfoLabel.setTextFormat(QtCore.Qt.RichText)
self.backupInfoLabel.setWordWrap(True)
self.backupInfoLabel.setObjectName(u'backupInfoLabel')
self.backupLayout.addWidget(self.backupInfoLabel)
self.selectLabel = QtGui.QLabel(self.backupPage)
self.selectLabel.setObjectName(u'selectLabel')
self.backupLayout.addWidget(self.selectLabel)
self.formLayout = QtGui.QFormLayout()
self.formLayout.setMargin(0)
self.formLayout.setObjectName(u'FormLayout')
self.backupDirectoryLabel = QtGui.QLabel(self.backupPage)
self.backupDirectoryLabel.setObjectName(u'backupDirectoryLabel')
self.backupDirectoryLayout = QtGui.QHBoxLayout()
self.backupDirectoryLayout.setObjectName(u'BackupDirectoryLayout')
self.backupDirectoryEdit = QtGui.QLineEdit(self.backupPage)
self.backupDirectoryEdit.setObjectName(u'BackupFolderEdit')
self.backupDirectoryLayout.addWidget(self.backupDirectoryEdit)
self.backupBrowseButton = QtGui.QToolButton(self.backupPage)
self.backupBrowseButton.setIcon(self.openIcon)
self.backupBrowseButton.setObjectName(u'BackupBrowseButton')
self.backupDirectoryLayout.addWidget(self.backupBrowseButton)
self.formLayout.addRow(self.backupDirectoryLabel,
self.backupDirectoryLayout)
self.backupLayout.addLayout(self.formLayout)
self.noBackupCheckBox = QtGui.QCheckBox(self.backupPage)
self.noBackupCheckBox.setObjectName('NoBackupCheckBox')
self.backupLayout.addWidget(self.noBackupCheckBox)
self.spacer = QtGui.QSpacerItem(10, 0, QtGui.QSizePolicy.Fixed,
QtGui.QSizePolicy.Minimum)
self.backupLayout.addItem(self.spacer)
self.addPage(self.backupPage)
# Select Page
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.mediaItem, path=self.path, file=filename[0])
self.checkBox[number] = QtGui.QCheckBox(self.scrollAreaContents)
checkBoxName = u'checkBox[%d]' % number
self.checkBox[number].setObjectName(checkBoxName)
self.checkBox[number].setText(bible.get_name())
self.checkBox[number].setCheckState(QtCore.Qt.Checked)
self.formLayout.addWidget(self.checkBox[number])
self.verticalWidget[number] = QtGui.QWidget(self.scrollAreaContents)
verticalWidgetName = u'verticalWidget[%d]' % number
self.verticalWidget[number].setObjectName(verticalWidgetName)
self.horizontalLayout[number] = QtGui.QHBoxLayout(
self.verticalWidget[number])
self.horizontalLayout[number].setContentsMargins(25, 0, 0, 0)
horizontalLayoutName = u'horizontalLayout[%d]' % number
self.horizontalLayout[number].setObjectName(horizontalLayoutName)
self.versionInfoPixmap[number] = QtGui.QLabel(
self.verticalWidget[number])
versionInfoPixmapName = u'versionInfoPixmap[%d]' % number
self.versionInfoPixmap[number].setObjectName(versionInfoPixmapName)
self.versionInfoPixmap[number].setPixmap(QtGui.QPixmap(
u':/bibles/bibles_upgrade_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[%d]' % number
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[%d]' % number
self.formWidget[number].setObjectName(formWidgetName)
self.formLayoutAttention[number] = QtGui.QFormLayout(
self.formWidget[number])
self.formLayoutAttention[number].setContentsMargins(25, 0, 0, 5)
formLayoutAttentionName = u'formLayoutAttention[%d]' % number
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])
#Set up the Signal for the checkbox
QtCore.QObject.connect(self.checkBox[number],
QtCore.SIGNAL(u'stateChanged(int)'),
self.onCheckBoxIndexChanged)
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 retranslateUi(self):
"""
Allow for localisation of the bible import wizard.
"""
self.setWindowTitle(translate('BiblesPlugin.UpgradeWizardForm',
'Bible Upgrade Wizard'))
self.titleLabel.setText(WizardStrings.HeaderStyle %
translate('OpenLP.Ui', 'Welcome to the Bible Upgrade Wizard'))
self.informationLabel.setText(
translate('BiblesPlugin.UpgradeWizardForm',
'This wizard will help you to upgrade your existing Bibles from a '
'prior version of OpenLP 2. Click the next button below to start '
'the upgrade process.'))
self.backupPage.setTitle(
translate('BiblesPlugin.UpgradeWizardForm',
'Select Backup Directory'))
self.backupPage.setSubTitle(
translate('BiblesPlugin.UpgradeWizardForm',
'Please select a backup directory for your Bibles'))
self.backupInfoLabel.setText(translate('BiblesPlugin.UpgradeWizardForm',
'Previous releases of OpenLP 2.0 are unable to use upgraded Bibles.'
' This will create a backup of your current Bibles so that you can '
'simply copy the files back to your OpenLP data directory if you '
'need to revert to a previous release of OpenLP. Instructions on '
'how to restore the files can be found in our <a href="'
'http://wiki.openlp.org/faq">Frequently Asked Questions</a>.'))
self.selectLabel.setText(translate('BiblesPlugin.UpgradeWizardForm',
'Please select a backup location for your Bibles.'))
self.backupDirectoryLabel.setText(
translate('BiblesPlugin.UpgradeWizardForm', 'Backup Directory:'))
self.noBackupCheckBox.setText(
translate('BiblesPlugin.UpgradeWizardForm',
'There is no need to backup my Bibles'))
self.selectPage.setTitle(
translate('BiblesPlugin.UpgradeWizardForm',
'Select Bibles'))
self.selectPage.setSubTitle(
translate('BiblesPlugin.UpgradeWizardForm',
'Please select the Bibles to upgrade'))
for number, bible in enumerate(self.files):
self.versionNameLabel[number].setText(
translate('BiblesPlugin.UpgradeWizardForm', 'Version name:'))
self.versionInfoLabel[number].setText(
translate('BiblesPlugin.UpgradeWizardForm', 'This '
'Bible still exists. Please change the name or uncheck it.'))
self.progressPage.setTitle(translate('BiblesPlugin.UpgradeWizardForm',
'Upgrading'))
self.progressPage.setSubTitle(
translate('BiblesPlugin.UpgradeWizardForm',
'Please wait while your Bibles are upgraded.'))
self.progressLabel.setText(WizardStrings.Ready)
self.progressBar.setFormat(u'%p%')
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.backupPage:
if not self.noBackupCheckBox.checkState() == QtCore.Qt.Checked:
if not unicode(self.backupDirectoryEdit.text()):
critical_error_message_box(UiStrings().EmptyField,
translate('BiblesPlugin.UpgradeWizardForm',
'You need to specify a Backup Directory for your '
'Bibles.'))
self.backupDirectoryEdit.setFocus()
return False
elif not os.path.exists(unicode(
self.backupDirectoryEdit.text())):
critical_error_message_box(UiStrings().Error,
translate('BiblesPlugin.UpgradeWizardForm',
'The given path is not an existing directory.'))
self.backupDirectoryEdit.setFocus()
return False
else:
if not self.backupOldBibles(unicode(
self.backupDirectoryEdit.text())):
critical_error_message_box(UiStrings().Error,
translate('BiblesPlugin.UpgradeWizardForm',
'The backup was not successfull.\nTo backup your '
'Bibles you need the permission to write in the given '
'directory. If you have a permissions to write and '
'this error still occurs, please report a bug.'))
return False
return True
elif self.currentPage() == self.selectPage:
for number, filename in enumerate(self.files):
if not self.checkBox[number].checkState() == QtCore.Qt.Checked:
continue
version_name = unicode(self.versionNameEdit[number].text())
if not version_name:
critical_error_message_box(UiStrings().EmptyField,
translate('BiblesPlugin.UpgradeWizardForm',
'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.UpgradeWizardForm',
'Bible Exists'),
translate('BiblesPlugin.UpgradeWizardForm',
'This Bible already exists. Please upgrade '
'a different Bible, delete the existing one or '
'uncheck.'))
self.versionNameEdit[number].setFocus()
return False
elif os.path.exists(os.path.join(self.path, clean_filename(
version_name))) and version_name == filename[1]:
newfilename = u'old_database_%s' % filename[0]
if not os.path.exists(os.path.join(self.path,
newfilename)):
os.rename(os.path.join(self.path, filename[0]),
os.path.join(self.path, newfilename))
self.files[number] = [newfilename, filename[1]]
continue
else:
critical_error_message_box(
translate('BiblesPlugin.UpgradeWizardForm',
'Bible Exists'),
translate('BiblesPlugin.UpgradeWizardForm',
'This Bible already exists. Please upgrade '
'a different Bible, delete the existing one or '
'uncheck.'))
self.verticalWidget[number].show()
self.formWidget[number].show()
self.versionNameEdit[number].setFocus()
return False
elif os.path.exists(os.path.join(self.path,
clean_filename(version_name))):
critical_error_message_box(
translate('BiblesPlugin.UpgradeWizardForm',
'Bible Exists'),
translate('BiblesPlugin.UpgradeWizardForm',
'This Bible already exists. Please upgrade '
'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'BibleUpgrade setDefaults')
settings = QtCore.QSettings()
settings.beginGroup(self.plugin.settingsSection)
self.stop_import_flag = False
self.success.clear()
self.newbibles.clear()
self.clearScrollArea()
self.files = self.manager.old_bible_databases
self.addScrollArea()
self.retranslateUi()
self.maxBibles = len(self.files)
for number, filename in enumerate(self.files):
self.checkBox[number].setCheckState(QtCore.Qt.Checked)
oldname = filename[1]
if self.manager.exists(oldname):
self.verticalWidget[number].show()
self.formWidget[number].show()
else:
self.verticalWidget[number].hide()
self.formWidget[number].hide()
self.progressBar.show()
self.restart()
self.finishButton.setVisible(False)
self.cancelButton.setVisible(True)
settings.endGroup()
def preWizard(self):
"""
Prepare the UI for the upgrade.
"""
OpenLPWizard.preWizard(self)
self.progressLabel.setText(translate(
'BiblesPlugin.UpgradeWizardForm',
'Starting upgrading Bible(s)...'))
Receiver.send_message(u'openlp_process_events')
def performWizard(self):
"""
Perform the actual upgrade.
"""
include_webbible = False
proxy_server = None
if self.maxBibles == 0:
self.progressLabel.setText(
translate('BiblesPlugin.UpgradeWizardForm', 'There are no '
'Bibles available to upgrade.'))
self.progressBar.hide()
return
self.maxBibles = 0
for number, file in enumerate(self.files):
if self.checkBox[number].checkState() == QtCore.Qt.Checked:
self.maxBibles += 1
number = 0
for biblenumber, filename in enumerate(self.files):
if self.stop_import_flag:
bible_failed = True
break
bible_failed = False
self.success[biblenumber] = False
if not self.checkBox[biblenumber].checkState() == QtCore.Qt.Checked:
continue
self.progressBar.reset()
oldbible = OldBibleDB(self.mediaItem, path=self.path,
file=filename[0])
name = filename[1]
if name is None:
delete_file(os.path.join(self.path, filename[0]))
self.incrementProgressBar(unicode(translate(
'BiblesPlugin.UpgradeWizardForm',
'Upgrading 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.UpgradeWizardForm',
'Upgrading Bible %s of %s: "%s"\nUpgrading ...')) %
(number + 1, self.maxBibles, name))
if os.path.exists(os.path.join(self.path, filename[0])):
name = unicode(self.versionNameEdit[biblenumber].text())
self.newbibles[number] = BibleDB(self.mediaItem, path=self.path,
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'Upgrading books from %s - download '\
u'name: "%s" failed' % (
meta_data[u'download source'],
meta_data[u'download name']))
delete_database(self.path,
clean_filename(self.newbibles[number].get_name()))
del self.newbibles[number]
critical_error_message_box(
translate('BiblesPlugin.UpgradeWizardForm',
'Download Error'),
translate('BiblesPlugin.UpgradeWizardForm',
'To upgrade your Web Bibles an Internet connection is '
'required. If you have a working Internet connection '
'and this error still occurs, please report a bug.'))
self.incrementProgressBar(unicode(translate(
'BiblesPlugin.UpgradeWizardForm',
'Upgrading 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(name)
if not language_id:
log.exception(u'Upgrading from "%s" failed' % filename[0])
delete_database(self.path,
clean_filename(self.newbibles[number].get_name()))
del self.newbibles[number]
self.incrementProgressBar(unicode(translate(
'BiblesPlugin.UpgradeWizardForm',
'Upgrading 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:
if self.stop_import_flag:
bible_failed = True
break
self.incrementProgressBar(unicode(translate(
'BiblesPlugin.UpgradeWizardForm',
'Upgrading Bible %s of %s: "%s"\n'
'Upgrading %s ...')) %
(number + 1, self.maxBibles, name, book))
book_ref_id = self.newbibles[number].\
get_book_ref_id_by_name(book, len(books), language_id)
if not book_ref_id:
log.exception(u'Upgrading books from %s - download '\
u'name: "%s" aborted by user' % (
meta_data[u'download source'],
meta_data[u'download name']))
delete_database(self.path,
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(name)
if not language_id:
log.exception(u'Upgrading books from "%s" failed' % name)
delete_database(self.path,
clean_filename(self.newbibles[number].get_name()))
del self.newbibles[number]
self.incrementProgressBar(unicode(translate(
'BiblesPlugin.UpgradeWizardForm',
'Upgrading 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:
if self.stop_import_flag:
bible_failed = True
break
self.incrementProgressBar(unicode(translate(
'BiblesPlugin.UpgradeWizardForm',
'Upgrading Bible %s of %s: "%s"\n'
'Upgrading %s ...')) %
(number + 1, self.maxBibles, name, book[u'name']))
book_ref_id = self.newbibles[number].\
get_book_ref_id_by_name(book[u'name'], len(books),
language_id)
if not book_ref_id:
log.exception(u'Upgrading books from %s " '\
'failed - aborted by user' % name)
delete_database(self.path,
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'])
if not verses:
log.exception(u'No verses found to import for book '
u'"%s"', book[u'name'])
self.newbibles[number].delete_book(db_book)
continue
for verse in verses:
if self.stop_import_flag:
bible_failed = True
break
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')
self.newbibles[number].session.commit()
if not bible_failed:
self.incrementProgressBar(unicode(translate(
'BiblesPlugin.UpgradeWizardForm',
'Upgrading Bible %s of %s: "%s"\n'
'Done')) %
(number + 1, self.maxBibles, name))
self.success[biblenumber] = True
else:
self.incrementProgressBar(unicode(translate(
'BiblesPlugin.UpgradeWizardForm',
'Upgrading Bible %s of %s: "%s"\nFailed')) %
(number + 1, self.maxBibles, name),
self.progressBar.maximum() - self.progressBar.value())
delete_database(self.path,
clean_filename(name))
number += 1
self.mediaItem.reloadBibles()
successful_import = 0
failed_import = 0
for number, filename in enumerate(self.files):
if number in self.success and self.success[number] == True:
successful_import += 1
elif self.checkBox[number].checkState() == QtCore.Qt.Checked:
failed_import += 1
if failed_import > 0:
failed_import_text = unicode(translate(
'BiblesPlugin.UpgradeWizardForm',
', %s failed')) % failed_import
else:
failed_import_text = u''
if successful_import > 0:
if include_webbible:
self.progressLabel.setText(unicode(
translate('BiblesPlugin.UpgradeWizardForm', 'Upgrading '
'Bible(s): %s successful%s\nPlease note, that verses from '
'Web Bibles will be downloaded\non demand and so an '
'Internet connection is required.')) %
(successful_import, failed_import_text))
else:
self.progressLabel.setText(unicode(
translate('BiblesPlugin.UpgradeWizardForm', 'Upgrading '
'Bible(s): %s successful%s')) % (successful_import,
failed_import_text))
else:
self.progressLabel.setText(
translate('BiblesPlugin.UpgradeWizardForm', 'Upgrade '
'failed.'))

View File

@ -0,0 +1,114 @@
# -*- 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, Meinert Jordan, Armin Köhler, Andreas Preikschat, #
# Christian Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon #
# Tibble, Carsten Tinggaard, 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 #
###############################################################################
from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate
class Ui_BookNameDialog(object):
def setupUi(self, bookNameDialog):
bookNameDialog.setObjectName(u'bookNameDialog')
bookNameDialog.resize(400, 271)
self.bookNameLayout = QtGui.QVBoxLayout(bookNameDialog)
self.bookNameLayout.setSpacing(8)
self.bookNameLayout.setMargin(8)
self.bookNameLayout.setObjectName(u'bookNameLayout')
self.infoLabel = QtGui.QLabel(bookNameDialog)
self.infoLabel.setWordWrap(True)
self.infoLabel.setObjectName(u'infoLabel')
self.bookNameLayout.addWidget(self.infoLabel)
self.correspondingLayout = QtGui.QGridLayout()
self.correspondingLayout.setColumnStretch(1, 1)
self.correspondingLayout.setSpacing(8)
self.correspondingLayout.setObjectName(u'correspondingLayout')
self.currentLabel = QtGui.QLabel(bookNameDialog)
self.currentLabel.setObjectName(u'currentLabel')
self.correspondingLayout.addWidget(self.currentLabel, 0, 0, 1, 1)
self.currentBookLabel = QtGui.QLabel(bookNameDialog)
self.currentBookLabel.setObjectName(u'currentBookLabel')
self.correspondingLayout.addWidget(self.currentBookLabel, 0, 1, 1, 1)
self.correspondingLabel = QtGui.QLabel(bookNameDialog)
self.correspondingLabel.setObjectName(u'correspondingLabel')
self.correspondingLayout.addWidget(
self.correspondingLabel, 1, 0, 1, 1)
self.correspondingComboBox = QtGui.QComboBox(bookNameDialog)
self.correspondingComboBox.setObjectName(u'correspondingComboBox')
self.correspondingLayout.addWidget(
self.correspondingComboBox, 1, 1, 1, 1)
self.bookNameLayout.addLayout(self.correspondingLayout)
self.optionsGroupBox = QtGui.QGroupBox(bookNameDialog)
self.optionsGroupBox.setObjectName(u'optionsGroupBox')
self.optionsLayout = QtGui.QVBoxLayout(self.optionsGroupBox)
self.optionsLayout.setSpacing(8)
self.optionsLayout.setMargin(8)
self.optionsLayout.setObjectName(u'optionsLayout')
self.oldTestamentCheckBox = QtGui.QCheckBox(self.optionsGroupBox)
self.oldTestamentCheckBox.setObjectName(u'oldTestamentCheckBox')
self.oldTestamentCheckBox.setCheckState(QtCore.Qt.Checked)
self.optionsLayout.addWidget(self.oldTestamentCheckBox)
self.newTestamentCheckBox = QtGui.QCheckBox(self.optionsGroupBox)
self.newTestamentCheckBox.setObjectName(u'newTestamentCheckBox')
self.newTestamentCheckBox.setCheckState(QtCore.Qt.Checked)
self.optionsLayout.addWidget(self.newTestamentCheckBox)
self.apocryphaCheckBox = QtGui.QCheckBox(self.optionsGroupBox)
self.apocryphaCheckBox.setObjectName(u'apocryphaCheckBox')
self.apocryphaCheckBox.setCheckState(QtCore.Qt.Checked)
self.optionsLayout.addWidget(self.apocryphaCheckBox)
self.bookNameLayout.addWidget(self.optionsGroupBox)
self.buttonBox = QtGui.QDialogButtonBox(bookNameDialog)
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
self.buttonBox.setStandardButtons(
QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok)
self.buttonBox.setObjectName(u'buttonBox')
self.bookNameLayout.addWidget(self.buttonBox)
self.retranslateUi(bookNameDialog)
QtCore.QObject.connect(
self.buttonBox, QtCore.SIGNAL(u'accepted()'),
bookNameDialog.accept)
QtCore.QObject.connect(
self.buttonBox, QtCore.SIGNAL(u'rejected()'),
bookNameDialog.reject)
QtCore.QMetaObject.connectSlotsByName(bookNameDialog)
def retranslateUi(self, bookNameDialog):
bookNameDialog.setWindowTitle(translate('BiblesPlugin.BookNameDialog',
'Select Book Name'))
self.infoLabel.setText(translate('BiblesPlugin.BookNameDialog',
'The following book name cannot be matched up internally. Please '
'select the corresponding English name from the list.'))
self.currentLabel.setText(translate('BiblesPlugin.BookNameDialog',
'Current name:'))
self.correspondingLabel.setText(translate(
'BiblesPlugin.BookNameDialog', 'Corresponding name:'))
self.optionsGroupBox.setTitle(translate('BiblesPlugin.BookNameDialog',
'Show Books From'))
self.oldTestamentCheckBox.setText(translate(
'BiblesPlugin.BookNameDialog', 'Old Testament'))
self.newTestamentCheckBox.setText(translate(
'BiblesPlugin.BookNameDialog', 'New Testament'))
self.apocryphaCheckBox.setText(translate('BiblesPlugin.BookNameDialog',
'Apocrypha'))

View File

@ -0,0 +1,123 @@
# -*- 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, Meinert Jordan, Armin Köhler, Andreas Preikschat, #
# Christian Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon #
# Tibble, Carsten Tinggaard, 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 #
###############################################################################
"""
Module implementing BookNameForm.
"""
import logging
from PyQt4.QtGui import QDialog
from PyQt4 import QtCore
from openlp.core.lib import translate
from openlp.core.lib.ui import critical_error_message_box
from openlp.plugins.bibles.forms.booknamedialog import \
Ui_BookNameDialog
from openlp.plugins.bibles.lib.db import BiblesResourcesDB
log = logging.getLogger(__name__)
class BookNameForm(QDialog, Ui_BookNameDialog):
"""
Class to manage a dialog which help the user to refer a book name a
to a english book name
"""
log.info(u'BookNameForm loaded')
def __init__(self, parent = None):
"""
Constructor
"""
QDialog.__init__(self, parent)
self.setupUi(self)
self.customSignals()
def customSignals(self):
"""
Set up the signals used in the booknameform.
"""
QtCore.QObject.connect(self.oldTestamentCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'),
self.onCheckBoxIndexChanged)
QtCore.QObject.connect(self.newTestamentCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'),
self.onCheckBoxIndexChanged)
QtCore.QObject.connect(self.apocryphaCheckBox,
QtCore.SIGNAL(u'stateChanged(int)'),
self.onCheckBoxIndexChanged)
def onCheckBoxIndexChanged(self, index):
'''
Reload Combobox if CheckBox state has changed
'''
self.reloadComboBox()
def reloadComboBox(self):
'''
Reload the Combobox items
'''
self.correspondingComboBox.clear()
items = BiblesResourcesDB.get_books()
for item in items:
addBook = True
for book in self.books:
if book.book_reference_id == item[u'id']:
addBook = False
break
if self.oldTestamentCheckBox.checkState() == QtCore.Qt.Unchecked \
and item[u'testament_id'] == 1:
addBook = False
elif self.newTestamentCheckBox.checkState() == QtCore.Qt.Unchecked \
and item[u'testament_id'] == 2:
addBook = False
elif self.apocryphaCheckBox.checkState() == QtCore.Qt.Unchecked \
and item[u'testament_id'] == 3:
addBook = False
if addBook:
self.correspondingComboBox.addItem(item[u'name'])
def exec_(self, name, books, maxbooks):
self.books = books
log.debug(maxbooks)
if maxbooks <= 27:
self.oldTestamentCheckBox.setCheckState(QtCore.Qt.Unchecked)
self.apocryphaCheckBox.setCheckState(QtCore.Qt.Unchecked)
elif maxbooks <= 66:
self.apocryphaCheckBox.setCheckState(QtCore.Qt.Unchecked)
self.reloadComboBox()
self.currentBookLabel.setText(unicode(name))
self.correspondingComboBox.setFocus()
return QDialog.exec_(self)
def accept(self):
if self.correspondingComboBox.currentText() == u'':
critical_error_message_box(
message=translate('BiblesPlugin.BookNameForm',
'You need to select a book.'))
self.correspondingComboBox.setFocus()
return False
else:
return QDialog.accept(self)

View File

@ -0,0 +1,84 @@
# -*- 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, Meinert Jordan, Armin Köhler, Andreas Preikschat, #
# Christian Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon #
# Tibble, Carsten Tinggaard, 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 #
###############################################################################
from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate
class Ui_LanguageDialog(object):
def setupUi(self, languageDialog):
languageDialog.setObjectName(u'languageDialog')
languageDialog.resize(400, 165)
self.languageLayout = QtGui.QVBoxLayout(languageDialog)
self.languageLayout.setSpacing(8)
self.languageLayout.setMargin(8)
self.languageLayout.setObjectName(u'languageLayout')
self.bibleLabel = QtGui.QLabel(languageDialog)
self.bibleLabel.setObjectName(u'bibleLabel')
self.languageLayout.addWidget(self.bibleLabel)
self.infoLabel = QtGui.QLabel(languageDialog)
self.infoLabel.setWordWrap(True)
self.infoLabel.setObjectName(u'infoLabel')
self.languageLayout.addWidget(self.infoLabel)
self.languageHBoxLayout = QtGui.QHBoxLayout()
self.languageHBoxLayout.setSpacing(8)
self.languageHBoxLayout.setObjectName(u'languageHBoxLayout')
self.languageLabel = QtGui.QLabel(languageDialog)
self.languageLabel.setObjectName(u'languageLabel')
self.languageHBoxLayout.addWidget(self.languageLabel)
self.languageComboBox = QtGui.QComboBox(languageDialog)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding,
QtGui.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(
self.languageComboBox.sizePolicy().hasHeightForWidth())
self.languageComboBox.setSizePolicy(sizePolicy)
self.languageComboBox.setObjectName(u'languageComboBox')
self.languageHBoxLayout.addWidget(self.languageComboBox)
self.languageLayout.addLayout(self.languageHBoxLayout)
self.buttonBox = QtGui.QDialogButtonBox(languageDialog)
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|
QtGui.QDialogButtonBox.Ok)
self.buttonBox.setObjectName(u'buttonBox')
self.languageLayout.addWidget(self.buttonBox)
self.retranslateUi(languageDialog)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'accepted()'),
languageDialog.accept)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(u'rejected()'),
languageDialog.reject)
def retranslateUi(self, languageDialog):
languageDialog.setWindowTitle(
translate('BiblesPlugin.LanguageDialog', 'Select Language'))
self.bibleLabel.setText(translate('BiblesPlugin.LanguageDialog', ''))
self.infoLabel.setText(translate('BiblesPlugin.LanguageDialog',
'OpenLP is unable to determine the language of this translation '
'of the Bible. Please select the language from the list below.'))
self.languageLabel.setText(translate('BiblesPlugin.LanguageDialog',
'Language:'))

View File

@ -0,0 +1,72 @@
# -*- 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, Meinert Jordan, Armin Köhler, Andreas Preikschat, #
# Christian Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon #
# Tibble, Carsten Tinggaard, 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 #
###############################################################################
"""
Module implementing LanguageForm.
"""
import logging
from PyQt4.QtGui import QDialog
from openlp.core.lib import translate
from openlp.core.lib.ui import critical_error_message_box
from openlp.plugins.bibles.forms.languagedialog import \
Ui_LanguageDialog
from openlp.plugins.bibles.lib.db import BiblesResourcesDB
log = logging.getLogger(__name__)
class LanguageForm(QDialog, Ui_LanguageDialog):
"""
Class to manage a dialog which ask the user for a language.
"""
log.info(u'LanguageForm loaded')
def __init__(self, parent = None):
"""
Constructor
"""
QDialog.__init__(self, parent)
self.setupUi(self)
def exec_(self, bible_name):
self.languageComboBox.addItem(u'')
if bible_name:
self.bibleLabel.setText(unicode(bible_name))
items = BiblesResourcesDB.get_languages()
for item in items:
self.languageComboBox.addItem(item[u'name'])
return QDialog.exec_(self)
def accept(self):
if self.languageComboBox.currentText() == u'':
critical_error_message_box(
message=translate('BiblesPlugin.LanguageForm',
'You need to choose a language.'))
self.languageComboBox.setFocus()
return False
else:
return QDialog.accept(self)

View File

@ -71,7 +71,7 @@ import chardet
import csv
from openlp.core.lib import Receiver, translate
from openlp.plugins.bibles.lib.db import BibleDB, Testament
from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB
log = logging.getLogger(__name__)
@ -79,6 +79,8 @@ class CSVBible(BibleDB):
"""
This class provides a specialisation for importing of CSV Bibles.
"""
log.info(u'CSVBible loaded')
def __init__(self, parent, **kwargs):
"""
Loads a Bible from a set of CVS files.
@ -87,48 +89,10 @@ class CSVBible(BibleDB):
"""
log.info(self.__class__.__name__)
BibleDB.__init__(self, parent, **kwargs)
try:
self.testamentsfile = kwargs[u'testamentsfile']
except KeyError:
self.testamentsfile = None
self.booksfile = kwargs[u'booksfile']
self.versesfile = kwargs[u'versefile']
def setup_testaments(self):
"""
Overrides parent method so we can handle importing a testament file.
"""
if self.testamentsfile:
self.wizard.progressBar.setMinimum(0)
self.wizard.progressBar.setMaximum(2)
self.wizard.progressBar.setValue(0)
testaments_file = None
try:
details = get_file_encoding(self.testamentsfile)
testaments_file = open(self.testamentsfile, 'rb')
testaments_reader = csv.reader(testaments_file, delimiter=',',
quotechar='"')
for line in testaments_reader:
if self.stop_import_flag:
break
self.wizard.incrementProgressBar(unicode(
translate('BibleDB.Wizard',
'Importing testaments... %s')) %
unicode(line[1], details['encoding']), 0)
self.save_object(Testament.populate(
name=unicode(line[1], details['encoding'])))
Receiver.send_message(u'openlp_process_events')
except (IOError, IndexError):
log.exception(u'Loading testaments from file failed')
finally:
if testaments_file:
testaments_file.close()
self.wizard.incrementProgressBar(unicode(translate(
'BibleDB.Wizard', 'Importing testaments... done.')), 2)
else:
BibleDB.setup_testaments(self)
def do_import(self):
def do_import(self, bible_name=None):
"""
Import the bible books and verses.
"""
@ -136,6 +100,10 @@ class CSVBible(BibleDB):
self.wizard.progressBar.setMinimum(0)
self.wizard.progressBar.setMaximum(66)
success = True
language_id = self.get_language(bible_name)
if not language_id:
log.exception(u'Importing books from "%s" failed' % self.filename)
return False
books_file = None
book_list = {}
# Populate the Tables
@ -149,8 +117,15 @@ class CSVBible(BibleDB):
self.wizard.incrementProgressBar(unicode(
translate('BibleDB.Wizard', 'Importing books... %s')) %
unicode(line[2], details['encoding']))
book_ref_id = self.get_book_ref_id_by_name(
unicode(line[2], details['encoding']), 67, language_id)
if not book_ref_id:
log.exception(u'Importing books from "%s" '\
'failed' % self.booksfile)
return False
book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
self.create_book(unicode(line[2], details['encoding']),
unicode(line[3], details['encoding']), int(line[1]))
book_ref_id, book_details[u'testament_id'])
book_list[int(line[0])] = unicode(line[2], details['encoding'])
Receiver.send_message(u'openlp_process_events')
except (IOError, IndexError):

View File

@ -27,16 +27,19 @@
import logging
import chardet
import os
import re
import sqlite3
from PyQt4 import QtCore
from sqlalchemy import Column, ForeignKey, or_, Table, types
from sqlalchemy.orm import class_mapper, mapper, relation
from sqlalchemy.orm.exc import UnmappedClassError
from openlp.core.lib import Receiver, translate
from openlp.core.lib import Receiver, translate, check_directory_exists
from openlp.core.lib.db import BaseModel, init_db, Manager
from openlp.core.lib.ui import critical_error_message_box
from openlp.core.utils import AppLocation
log = logging.getLogger(__name__)
@ -47,13 +50,6 @@ class BibleMeta(BaseModel):
pass
class Testament(BaseModel):
"""
Bible Testaments
"""
pass
class Book(BaseModel):
"""
Song model
@ -67,6 +63,18 @@ class Verse(BaseModel):
"""
pass
def clean_filename(filename):
"""
Clean up the version name of the Bible and convert it into a valid
file name.
``filename``
The "dirty" file name or version name.
"""
if not isinstance(filename, unicode):
filename = unicode(filename, u'utf-8')
filename = re.sub(r'[^\w]+', u'_', filename).strip(u'_')
return filename + u'.sqlite'
def init_schema(url):
"""
@ -81,19 +89,17 @@ def init_schema(url):
Column(u'key', types.Unicode(255), primary_key=True, index=True),
Column(u'value', types.Unicode(255)),
)
testament_table = Table(u'testament', metadata,
Column(u'id', types.Integer, primary_key=True),
Column(u'name', types.Unicode(50)),
)
book_table = Table(u'book', metadata,
Column(u'id', types.Integer, primary_key=True),
Column(u'testament_id', types.Integer, ForeignKey(u'testament.id')),
Column(u'book_reference_id', types.Integer, index=True),
Column(u'testament_reference_id', types.Integer),
Column(u'name', types.Unicode(50), index=True),
Column(u'abbreviation', types.Unicode(5), index=True),
)
verse_table = Table(u'verse', metadata,
Column(u'id', types.Integer, primary_key=True, index=True),
Column(u'book_id', types.Integer, ForeignKey(u'book.id'), index=True),
Column(u'book_id', types.Integer, ForeignKey(
u'book.id'), index=True),
Column(u'chapter', types.Integer, index=True),
Column(u'verse', types.Integer, index=True),
Column(u'text', types.UnicodeText, index=True),
@ -103,11 +109,6 @@ def init_schema(url):
class_mapper(BibleMeta)
except UnmappedClassError:
mapper(BibleMeta, meta_table)
try:
class_mapper(Testament)
except UnmappedClassError:
mapper(Testament, testament_table,
properties={'books': relation(Book, backref='testament')})
try:
class_mapper(Book)
except UnmappedClassError:
@ -129,6 +130,7 @@ class BibleDB(QtCore.QObject, Manager):
methods, but benefit from the database methods in here via inheritance,
rather than depending on yet another object.
"""
log.info(u'BibleDB loaded')
def __init__(self, parent, **kwargs):
"""
@ -156,12 +158,14 @@ class BibleDB(QtCore.QObject, Manager):
self.name = kwargs[u'name']
if not isinstance(self.name, unicode):
self.name = unicode(self.name, u'utf-8')
self.file = self.clean_filename(self.name)
self.file = clean_filename(self.name)
if u'file' in kwargs:
self.file = kwargs[u'file']
Manager.__init__(self, u'bibles', init_schema, self.file)
if u'file' in kwargs:
self.get_name()
if u'path' in kwargs:
self.path = kwargs[u'path']
self.wizard = None
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'openlp_stop_wizard'), self.stop_import)
@ -181,19 +185,6 @@ class BibleDB(QtCore.QObject, Manager):
self.name = version_name.value if version_name else None
return self.name
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 register(self, wizard):
"""
This method basically just initialialises the database. It is called
@ -206,36 +197,40 @@ class BibleDB(QtCore.QObject, Manager):
"""
self.wizard = wizard
self.create_meta(u'dbversion', u'2')
self.setup_testaments()
return self.name
def setup_testaments(self):
"""
Initialise the testaments section of a bible with suitable defaults.
"""
self.save_object(Testament.populate(name=u'Old Testament'))
self.save_object(Testament.populate(name=u'New Testament'))
self.save_object(Testament.populate(name=u'Apocrypha'))
def create_book(self, name, abbrev, testament=1):
def create_book(self, name, bk_ref_id, testament=1):
"""
Add a book to the database.
``name``
The name of the book.
``abbrev``
The abbreviation of the book.
``bk_ref_id``
The book_reference_id from bibles_resources.sqlite of the book.
``testament``
*Defaults to 1.* The id of the testament this book belongs to.
*Defaults to 1.* The testament_reference_id from
bibles_resources.sqlite of the testament this book belongs to.
"""
log.debug(u'create_book %s,%s', name, abbrev)
book = Book.populate(name=name, abbreviation=abbrev,
testament_id=testament)
log.debug(u'BibleDB.create_book("%s", "%s")', name, bk_ref_id)
book = Book.populate(name=name, book_reference_id=bk_ref_id,
testament_reference_id=testament)
self.save_object(book)
return book
def delete_book(self, db_book):
"""
Delete a book from the database.
``db_book``
The book object.
"""
log.debug(u'BibleDB.delete_book("%s")', db_book.name)
if self.delete_object(Book, db_book.id):
return True
return False
def create_chapter(self, book_id, chapter, textlist):
"""
Add a chapter and its verses to a book.
@ -250,7 +245,7 @@ class BibleDB(QtCore.QObject, Manager):
A dict of the verses to be inserted. The key is the verse number,
and the value is the verse text.
"""
log.debug(u'create_chapter %s,%s', book_id, chapter)
log.debug(u'BibleDBcreate_chapter("%s", "%s")', book_id, chapter)
# Text list has book and chapter as first two elements of the array.
for verse_number, verse_text in textlist.iteritems():
verse = Verse.populate(
@ -300,7 +295,9 @@ class BibleDB(QtCore.QObject, Manager):
``value``
The value for this instance.
"""
log.debug(u'save_meta %s/%s', key, value)
if not isinstance(value, unicode):
value = unicode(value)
log.debug(u'BibleDB.save_meta("%s/%s")', key, value)
self.save_object(BibleMeta.populate(key=key, value=value))
def get_book(self, book):
@ -310,20 +307,60 @@ class BibleDB(QtCore.QObject, Manager):
``book``
The name of the book to return.
"""
log.debug(u'BibleDb.get_book("%s")', book)
db_book = self.get_object_filtered(Book, Book.name.like(book + u'%'))
if db_book is None:
db_book = self.get_object_filtered(Book,
Book.abbreviation.like(book + u'%'))
return db_book
log.debug(u'BibleDB.get_book("%s")', book)
return self.get_object_filtered(Book, Book.name.like(book + u'%'))
def get_books(self):
"""
A wrapper so both local and web bibles have a get_books() method that
manager can call. Used in the media manager advanced search tab.
"""
log.debug(u'BibleDB.get_books()')
return self.get_all_objects(Book, order_by_ref=Book.id)
def get_book_by_book_ref_id(self, id):
"""
Return a book object from the database.
``id``
The reference id of the book to return.
"""
log.debug(u'BibleDB.get_book_by_book_ref_id("%s")', id)
return self.get_object_filtered(Book, Book.book_reference_id.like(id))
def get_book_ref_id_by_name(self, book, maxbooks, language_id=None):
log.debug(u'BibleDB.get_book_ref_id_by_name:("%s", "%s")', book,
language_id)
if BiblesResourcesDB.get_book(book, True):
book_temp = BiblesResourcesDB.get_book(book, True)
book_id = book_temp[u'id']
elif BiblesResourcesDB.get_alternative_book_name(book):
book_id = BiblesResourcesDB.get_alternative_book_name(book)
elif AlternativeBookNamesDB.get_book_reference_id(book):
book_id = AlternativeBookNamesDB.get_book_reference_id(book)
else:
from openlp.plugins.bibles.forms import BookNameForm
book_ref = None
book_name = BookNameForm(self.wizard)
if book_name.exec_(book, self.get_books(), maxbooks):
book_ref = unicode(
book_name.correspondingComboBox.currentText())
if not book_ref:
return None
else:
book_temp = BiblesResourcesDB.get_book(book_ref)
if book_temp:
book_id = book_temp[u'id']
else:
return None
if book_id:
AlternativeBookNamesDB.create_alternative_book_name(
book, book_id, language_id)
if book_id:
return book_id
else:
return None
def get_verses(self, reference_list, show_error=True):
"""
This is probably the most used function. It retrieves the list of
@ -333,24 +370,24 @@ class BibleDB(QtCore.QObject, Manager):
This is the list of references the media manager item wants. It is
a list of tuples, with the following format::
(book, chapter, start_verse, end_verse)
(book_reference_id, chapter, start_verse, end_verse)
Therefore, when you are looking for multiple items, simply break
them up into references like this, bundle them into a list. This
function then runs through the list, and returns an amalgamated
list of ``Verse`` objects. For example::
[(u'Genesis', 1, 1, 1), (u'Genesis', 2, 2, 3)]
[(u'35', 1, 1, 1), (u'35', 2, 2, 3)]
"""
log.debug(u'BibleDB.get_verses: %s', reference_list)
log.debug(u'BibleDB.get_verses("%s")', reference_list)
verse_list = []
for book, chapter, start_verse, end_verse in reference_list:
db_book = self.get_book(book)
for book_id, chapter, start_verse, end_verse in reference_list:
db_book = self.get_book_by_book_ref_id(book_id)
if db_book:
book = db_book.name
log.debug(u'Book name corrected to "%s"', book)
book_id = db_book.book_reference_id
log.debug(u'Book name corrected to "%s"', db_book.name)
if end_verse == -1:
end_verse = self.get_verse_count(book, chapter)
end_verse = self.get_verse_count(book_id, chapter)
verses = self.session.query(Verse)\
.filter_by(book_id=db_book.id)\
.filter_by(chapter=chapter)\
@ -360,7 +397,7 @@ class BibleDB(QtCore.QObject, Manager):
.all()
verse_list.extend(verses)
else:
log.debug(u'OpenLP failed to find book %s', book)
log.debug(u'OpenLP failed to find book with id "%s"', book_id)
if show_error:
critical_error_message_box(
translate('BiblesPlugin', 'No Book Found'),
@ -399,18 +436,18 @@ class BibleDB(QtCore.QObject, Manager):
Return the number of chapters in a book.
``book``
The book to get the chapter count for.
The book object to get the chapter count for.
"""
log.debug(u'BibleDB.get_chapter_count("%s")', book)
log.debug(u'BibleDB.get_chapter_count("%s")', book.name)
count = self.session.query(Verse.chapter).join(Book)\
.filter(Book.name == book)\
.filter(Book.book_reference_id==book.book_reference_id)\
.distinct().count()
if not count:
return 0
else:
return count
def get_verse_count(self, book, chapter):
def get_verse_count(self, book_id, chapter):
"""
Return the number of verses in a chapter.
@ -420,16 +457,49 @@ class BibleDB(QtCore.QObject, Manager):
``chapter``
The chapter to get the verse count for.
"""
log.debug(u'BibleDB.get_verse_count("%s", %s)', book, chapter)
log.debug(u'BibleDB.get_verse_count("%s", "%s")', book_id, chapter)
count = self.session.query(Verse).join(Book)\
.filter(Book.name == book)\
.filter(Verse.chapter == chapter)\
.filter(Book.book_reference_id==book_id)\
.filter(Verse.chapter==chapter)\
.count()
if not count:
return 0
else:
return count
def get_language(self, bible_name=None):
"""
If no language is given it calls a dialog window where the user could
select the bible language.
Return the language id of a bible.
``book``
The language the bible is.
"""
log.debug(u'BibleDB.get_language()')
from openlp.plugins.bibles.forms import LanguageForm
language = None
language_form = LanguageForm(self.wizard)
if language_form.exec_(bible_name):
language = unicode(language_form.languageComboBox.currentText())
if not language:
return False
language = BiblesResourcesDB.get_language(language)
language_id = language[u'id']
self.create_meta(u'language_id', language_id)
return language_id
def is_old_database(self):
"""
Returns ``True`` if it is a bible database, which has been created
prior to 1.9.6.
"""
try:
columns = self.session.query(Book).all()
except:
return True
return False
def dump_bible(self):
"""
Utility debugging method to dump the contents of a bible.
@ -441,3 +511,569 @@ class BibleDB(QtCore.QObject, Manager):
log.debug(u'...............................Verses ')
verses = self.session.query(Verse).all()
log.debug(verses)
class BiblesResourcesDB(QtCore.QObject, Manager):
"""
This class represents the database-bound Bible Resources. It provide
some resources which are used in the Bibles plugin.
A wrapper class around a small SQLite database which contains the download
resources, a biblelist from the different download resources, the books,
chapter counts and verse counts for the web download Bibles, a language
reference, the testament reference and some alternative book names. This
class contains a singleton "cursor" so that only one connection to the
SQLite database is ever used.
"""
cursor = None
@staticmethod
def get_cursor():
"""
Return the cursor object. Instantiate one if it doesn't exist yet.
"""
if BiblesResourcesDB.cursor is None:
filepath = os.path.join(
AppLocation.get_directory(AppLocation.PluginsDir), u'bibles',
u'resources', u'bibles_resources.sqlite')
conn = sqlite3.connect(filepath)
BiblesResourcesDB.cursor = conn.cursor()
return BiblesResourcesDB.cursor
@staticmethod
def run_sql(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 = BiblesResourcesDB.get_cursor()
cursor.execute(query, parameters)
return cursor.fetchall()
@staticmethod
def get_books():
"""
Return a list of all the books of the Bible.
"""
log.debug(u'BiblesResourcesDB.get_books()')
books = BiblesResourcesDB.run_sql(u'SELECT id, testament_id, name, '
u'abbreviation, chapters FROM book_reference ORDER BY id')
return [
{
u'id': book[0],
u'testament_id': book[1],
u'name': unicode(book[2]),
u'abbreviation': unicode(book[3]),
u'chapters': book[4]
}
for book in books
]
@staticmethod
def get_book(name, lower=False):
"""
Return a book by name or abbreviation.
``name``
The name or abbreviation of the book.
``lower``
True if the comparsion should be only lowercase
"""
log.debug(u'BiblesResourcesDB.get_book("%s")', name)
if not isinstance(name, unicode):
name = unicode(name)
if lower:
books = BiblesResourcesDB.run_sql(u'SELECT id, testament_id, name, '
u'abbreviation, chapters FROM book_reference WHERE '
u'LOWER(name) = ? OR LOWER(abbreviation) = ?',
(name.lower(), name.lower()))
else:
books = BiblesResourcesDB.run_sql(u'SELECT id, testament_id, name, '
u'abbreviation, chapters FROM book_reference WHERE name = ?'
u' OR abbreviation = ?', (name, name))
if books:
return {
u'id': books[0][0],
u'testament_id': books[0][1],
u'name': unicode(books[0][2]),
u'abbreviation': unicode(books[0][3]),
u'chapters': books[0][4]
}
else:
return None
@staticmethod
def get_book_by_id(id):
"""
Return a book by id.
``id``
The id of the book.
"""
log.debug(u'BiblesResourcesDB.get_book_by_id("%s")', id)
if not isinstance(id, int):
id = int(id)
books = BiblesResourcesDB.run_sql(u'SELECT id, testament_id, name, '
u'abbreviation, chapters FROM book_reference WHERE id = ?',
(id, ))
if books:
return {
u'id': books[0][0],
u'testament_id': books[0][1],
u'name': unicode(books[0][2]),
u'abbreviation': unicode(books[0][3]),
u'chapters': books[0][4]
}
else:
return None
@staticmethod
def get_chapter(book_id, chapter):
"""
Return the chapter details for a specific chapter of a book.
``book_id``
The id of a book.
``chapter``
The chapter number.
"""
log.debug(u'BiblesResourcesDB.get_chapter("%s", "%s")', book_id,
chapter)
if not isinstance(chapter, int):
chapter = int(chapter)
chapters = BiblesResourcesDB.run_sql(u'SELECT id, book_reference_id, '
u'chapter, verse_count FROM chapters WHERE book_reference_id = ?',
(book_id,))
if chapters:
return {
u'id': chapters[chapter-1][0],
u'book_reference_id': chapters[chapter-1][1],
u'chapter': chapters[chapter-1][2],
u'verse_count': chapters[chapter-1][3]
}
else:
return None
@staticmethod
def get_chapter_count(book_id):
"""
Return the number of chapters in a book.
``book_id``
The id of the book.
"""
log.debug(u'BiblesResourcesDB.get_chapter_count("%s")', book_id)
details = BiblesResourcesDB.get_book_by_id(book_id)
if details:
return details[u'chapters']
return 0
@staticmethod
def get_verse_count(book_id, chapter):
"""
Return the number of verses in a chapter.
``book``
The id of the book.
``chapter``
The number of the chapter.
"""
log.debug(u'BiblesResourcesDB.get_verse_count("%s", "%s")', book_id,
chapter)
details = BiblesResourcesDB.get_chapter(book_id, chapter)
if details:
return details[u'verse_count']
return 0
@staticmethod
def get_download_source(source):
"""
Return a download_source_id by source.
``name``
The name or abbreviation of the book.
"""
log.debug(u'BiblesResourcesDB.get_download_source("%s")', source)
if not isinstance(source, unicode):
source = unicode(source)
source = source.title()
dl_source = BiblesResourcesDB.run_sql(u'SELECT id, source FROM '
u'download_source WHERE source = ?', (source.lower(),))
if dl_source:
return {
u'id': dl_source[0][0],
u'source': dl_source[0][1]
}
else:
return None
@staticmethod
def get_webbibles(source):
"""
Return the bibles a webbible provide for download.
``source``
The source of the webbible.
"""
log.debug(u'BiblesResourcesDB.get_webbibles("%s")', source)
if not isinstance(source, unicode):
source = unicode(source)
source = BiblesResourcesDB.get_download_source(source)
bibles = BiblesResourcesDB.run_sql(u'SELECT id, name, abbreviation, '
u'language_id, download_source_id FROM webbibles WHERE '
u'download_source_id = ?', (source[u'id'],))
if bibles:
return [
{
u'id': bible[0],
u'name': bible[1],
u'abbreviation': bible[2],
u'language_id': bible[3],
u'download_source_id': bible[4]
}
for bible in bibles
]
else:
return None
@staticmethod
def get_webbible(abbreviation, source):
"""
Return the bibles a webbible provide for download.
``abbreviation``
The abbreviation of the webbible.
``source``
The source of the webbible.
"""
log.debug(u'BiblesResourcesDB.get_webbibles("%s", "%s")', abbreviation,
source)
if not isinstance(abbreviation, unicode):
abbreviation = unicode(abbreviation)
if not isinstance(source, unicode):
source = unicode(source)
source = BiblesResourcesDB.get_download_source(source)
bible = BiblesResourcesDB.run_sql(u'SELECT id, name, abbreviation, '
u'language_id, download_source_id FROM webbibles WHERE '
u'download_source_id = ? AND abbreviation = ?', (source[u'id'],
abbreviation))
if bible:
return {
u'id': bible[0][0],
u'name': bible[0][1],
u'abbreviation': bible[0][2],
u'language_id': bible[0][3],
u'download_source_id': bible[0][4]
}
else:
return None
@staticmethod
def get_alternative_book_name(name, language_id=None):
"""
Return a book_reference_id if the name matches.
``name``
The name to search the id.
``language_id``
The language_id for which language should be searched
"""
log.debug(u'BiblesResourcesDB.get_alternative_book_name("%s", "%s")',
name, language_id)
if language_id:
books = BiblesResourcesDB.run_sql(u'SELECT book_reference_id, name '
u'FROM alternative_book_names WHERE language_id = ? ORDER BY '
u'id', (language_id, ))
else:
books = BiblesResourcesDB.run_sql(u'SELECT book_reference_id, name '
u'FROM alternative_book_names ORDER BY id')
for book in books:
if book[1].lower() == name.lower():
return book[0]
return None
@staticmethod
def get_language(name):
"""
Return a dict containing the language id, name and code by name or
abbreviation.
``name``
The name or abbreviation of the language.
"""
log.debug(u'BiblesResourcesDB.get_language("%s")', name)
if not isinstance(name, unicode):
name = unicode(name)
language = BiblesResourcesDB.run_sql(u'SELECT id, name, code FROM '
u'language WHERE name = ? OR code = ?', (name, name.lower()))
if language:
return {
u'id': language[0][0],
u'name': unicode(language[0][1]),
u'code': unicode(language[0][2])
}
else:
return None
@staticmethod
def get_languages():
"""
Return a dict containing all languages with id, name and code.
"""
log.debug(u'BiblesResourcesDB.get_languages()')
languages = BiblesResourcesDB.run_sql(u'SELECT id, name, code FROM '
u'language ORDER by name')
if languages:
return [
{
u'id': language[0],
u'name': unicode(language[1]),
u'code': unicode(language[2])
}
for language in languages
]
else:
return None
@staticmethod
def get_testament_reference():
"""
Return a list of all testaments and their id of the Bible.
"""
log.debug(u'BiblesResourcesDB.get_testament_reference()')
testaments = BiblesResourcesDB.run_sql(u'SELECT id, name FROM '
u'testament_reference ORDER BY id')
return [
{
u'id': testament[0],
u'name': unicode(testament[1])
}
for testament in testaments
]
class AlternativeBookNamesDB(QtCore.QObject, Manager):
"""
This class represents a database-bound alternative book names system.
"""
cursor = None
conn = None
@staticmethod
def get_cursor():
"""
Return the cursor object. Instantiate one if it doesn't exist yet.
If necessary loads up the database and creates the tables if the
database doesn't exist.
"""
if AlternativeBookNamesDB.cursor is None:
filepath = os.path.join(
AppLocation.get_directory(AppLocation.DataDir), u'bibles',
u'alternative_book_names.sqlite')
if not os.path.exists(filepath):
#create new DB, create table alternative_book_names
AlternativeBookNamesDB.conn = sqlite3.connect(filepath)
AlternativeBookNamesDB.conn.execute(u'CREATE TABLE '
u'alternative_book_names(id INTEGER NOT NULL, '
u'book_reference_id INTEGER, language_id INTEGER, name '
u'VARCHAR(50), PRIMARY KEY (id))')
else:
#use existing DB
AlternativeBookNamesDB.conn = sqlite3.connect(filepath)
AlternativeBookNamesDB.cursor = AlternativeBookNamesDB.conn.cursor()
return AlternativeBookNamesDB.cursor
@staticmethod
def run_sql(query, parameters=(), commit=None):
"""
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
``commit``
If a commit statement is necessary this should be True.
"""
cursor = AlternativeBookNamesDB.get_cursor()
cursor.execute(query, parameters)
if commit:
AlternativeBookNamesDB.conn.commit()
return cursor.fetchall()
@staticmethod
def get_book_reference_id(name, language_id=None):
"""
Return a book_reference_id if the name matches.
``name``
The name to search the id.
``language_id``
The language_id for which language should be searched
"""
log.debug(u'AlternativeBookNamesDB.get_book_reference_id("%s", "%s")',
name, language_id)
if language_id:
books = AlternativeBookNamesDB.run_sql(u'SELECT book_reference_id, '
u'name FROM alternative_book_names WHERE language_id = ?',
(language_id, ))
else:
books = AlternativeBookNamesDB.run_sql(u'SELECT book_reference_id, '
u'name FROM alternative_book_names')
for book in books:
if book[1].lower() == name.lower():
return book[0]
return None
@staticmethod
def create_alternative_book_name(name, book_reference_id, language_id):
"""
Add an alternative book name to the database.
``name``
The name of the alternative book name.
``book_reference_id``
The book_reference_id of the book.
``language_id``
The language to which the alternative book name belong.
"""
log.debug(u'AlternativeBookNamesDB.create_alternative_book_name("%s", '
'"%s", "%s"', name, book_reference_id, language_id)
return AlternativeBookNamesDB.run_sql(u'INSERT INTO '
u'alternative_book_names(book_reference_id, language_id, name) '
u'VALUES (?, ?, ?)', (book_reference_id, language_id, name), True)
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)
self.connection = sqlite3.connect(filepath)
self.cursor = self.connection.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:
return [
{
u'key': unicode(meta[0]),
u'value': unicode(meta[1])
}
for meta in metadata
]
else:
return None
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:
return [
{
u'name': unicode(book[0]),
u'id':int(book[1])
}
for book in books
]
else:
return None
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:
return [
{
u'book_id': int(verse[0]),
u'chapter': int(verse[1]),
u'verse': int(verse[2]),
u'text': unicode(verse[3])
}
for verse in verses
]
else:
return None

View File

@ -42,161 +42,26 @@ from openlp.core.lib import Receiver, translate
from openlp.core.lib.ui import critical_error_message_box
from openlp.core.utils import AppLocation, get_web_page
from openlp.plugins.bibles.lib import SearchResults
from openlp.plugins.bibles.lib.db import BibleDB, Book
from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB, \
Book
log = logging.getLogger(__name__)
class HTTPBooks(object):
"""
A wrapper class around a small SQLite database which contains the books,
chapter counts and verse counts for the web download Bibles. This class
contains a singleton "cursor" so that only one connection to the SQLite
database is ever used.
"""
cursor = None
@staticmethod
def get_cursor():
"""
Return the cursor object. Instantiate one if it doesn't exist yet.
"""
if HTTPBooks.cursor is None:
filepath = os.path.join(
AppLocation.get_directory(AppLocation.PluginsDir), u'bibles',
u'resources', u'httpbooks.sqlite')
conn = sqlite3.connect(filepath)
HTTPBooks.cursor = conn.cursor()
return HTTPBooks.cursor
@staticmethod
def run_sql(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 = HTTPBooks.get_cursor()
cursor.execute(query, parameters)
return cursor.fetchall()
@staticmethod
def get_books():
"""
Return a list of all the books of the Bible.
"""
books = HTTPBooks.run_sql(u'SELECT id, testament_id, name, '
u'abbreviation, chapters FROM books ORDER BY id')
book_list = []
for book in books:
book_list.append({
u'id': book[0],
u'testament_id': book[1],
u'name': unicode(book[2]),
u'abbreviation': unicode(book[3]),
u'chapters': book[4]
})
return book_list
@staticmethod
def get_book(name):
"""
Return a book by name or abbreviation.
``name``
The name or abbreviation of the book.
"""
if not isinstance(name, unicode):
name = unicode(name)
name = name.title()
books = HTTPBooks.run_sql(u'SELECT id, testament_id, name, '
u'abbreviation, chapters FROM books WHERE name = ? OR '
u'abbreviation = ?', (name, name))
if books:
return {
u'id': books[0][0],
u'testament_id': books[0][1],
u'name': unicode(books[0][2]),
u'abbreviation': unicode(books[0][3]),
u'chapters': books[0][4]
}
else:
return None
@staticmethod
def get_chapter(name, chapter):
"""
Return the chapter details for a specific chapter of a book.
``name``
The name or abbreviation of a book.
``chapter``
The chapter number.
"""
if not isinstance(name, int):
chapter = int(chapter)
book = HTTPBooks.get_book(name)
chapters = HTTPBooks.run_sql(u'SELECT id, book_id, chapter, '
u'verses FROM chapters WHERE book_id = ?', (book[u'id'],))
if chapters:
return {
u'id': chapters[chapter-1][0],
u'book_id': chapters[chapter-1][1],
u'chapter': chapters[chapter-1][2],
u'verses': chapters[chapter-1][3]
}
else:
return None
@staticmethod
def get_chapter_count(book):
"""
Return the number of chapters in a book.
``book``
The name or abbreviation of the book.
"""
details = HTTPBooks.get_book(book)
if details:
return details[u'chapters']
return 0
@staticmethod
def get_verse_count(book, chapter):
"""
Return the number of verses in a chapter.
``book``
The name or abbreviation of the book.
``chapter``
The number of the chapter.
"""
details = HTTPBooks.get_chapter(book, chapter)
if details:
return details[u'verses']
return 0
class BGExtract(object):
"""
Extract verses from BibleGateway
"""
def __init__(self, proxyurl=None):
log.debug(u'init %s', proxyurl)
log.debug(u'BGExtract.init("%s")', proxyurl)
self.proxyurl = proxyurl
socket.setdefaulttimeout(30)
def get_bible_chapter(self, version, bookname, chapter):
"""
Access and decode bibles via the BibleGateway website.
Access and decode Bibles via the BibleGateway website.
``version``
The version of the bible like 31 for New International version.
The version of the Bible like 31 for New International version.
``bookname``
Name of the Book.
@ -204,9 +69,11 @@ class BGExtract(object):
``chapter``
Chapter number.
"""
log.debug(u'get_bible_chapter %s, %s, %s', version, bookname, chapter)
log.debug(u'BGExtract.get_bible_chapter("%s", "%s", "%s")', version,
bookname, chapter)
urlbookname = urllib.quote(bookname.encode("utf-8"))
url_params = urllib.urlencode(
{u'search': u'%s %s' % (bookname, chapter),
{u'search': u'%s %s' % (urlbookname, chapter),
u'version': u'%s' % version})
cleaner = [(re.compile('&nbsp;|<br />|\'\+\''), lambda match: '')]
soup = get_soup_for_bible_ref(
@ -264,13 +131,57 @@ class BGExtract(object):
return None
return SearchResults(bookname, chapter, verse_list)
def get_books_from_http(self, version):
"""
Load a list of all books a Bible contaions from BibleGateway website.
``version``
The version of the Bible like NIV for New International Version
"""
log.debug(u'BGExtract.get_books_from_http("%s")', version)
url_params = urllib.urlencode(
{u'search': 'Bible-List', u'version': u'%s' % version})
reference_url = u'http://www.biblegateway.com/passage/?%s' % url_params
page = get_web_page(reference_url)
if not page:
send_error_message(u'download')
return None
page_source = page.read()
page_source = unicode(page_source, 'utf8')
page_source_temp = re.search(u'<table id="booklist".*?>.*?</table>', \
page_source, re.DOTALL)
if page_source_temp:
soup = page_source_temp.group(0)
else:
soup = None
try:
soup = BeautifulSoup(soup)
except HTMLParseError:
log.exception(u'BeautifulSoup could not parse the Bible page.')
if not soup:
send_error_message(u'parse')
return None
Receiver.send_message(u'openlp_process_events')
content = soup.find(u'table', {u'id': u'booklist'})
content = content.findAll(u'tr')
if not content:
log.exception(u'No books found in the Biblegateway response.')
send_error_message(u'parse')
return None
books = []
for book in content:
book = book.find(u'td')
if book:
books.append(book.contents[0])
return books
class BSExtract(object):
"""
Extract verses from Bibleserver.com
"""
def __init__(self, proxyurl=None):
log.debug(u'init %s', proxyurl)
log.debug(u'BSExtract.init("%s")', proxyurl)
self.proxyurl = proxyurl
socket.setdefaulttimeout(30)
@ -287,9 +198,11 @@ class BSExtract(object):
``chapter``
Chapter number
"""
log.debug(u'get_bible_chapter %s,%s,%s', version, bookname, chapter)
log.debug(u'BSExtract.get_bible_chapter("%s", "%s", "%s")', version,
bookname, chapter)
urlbookname = urllib.quote(bookname.encode("utf-8"))
chapter_url = u'http://m.bibleserver.com/text/%s/%s%s' % \
(version, bookname, chapter)
(version, urlbookname, chapter)
header = (u'Accept-Language', u'en')
soup = get_soup_for_bible_ref(chapter_url, header)
if not soup:
@ -309,13 +222,37 @@ class BSExtract(object):
verses[versenumber] = verse.contents[1].rstrip(u'\n')
return SearchResults(bookname, chapter, verses)
def get_books_from_http(self, version):
"""
Load a list of all books a Bible contains from Bibleserver mobile
website.
``version``
The version of the Bible like NIV for New International Version
"""
log.debug(u'BSExtract.get_books_from_http("%s")', version)
chapter_url = u'http://m.bibleserver.com/overlay/selectBook?'\
'translation=%s' % (version)
soup = get_soup_for_bible_ref(chapter_url)
if not soup:
return None
content = soup.find(u'ul')
if not content:
log.exception(u'No books found in the Bibleserver response.')
send_error_message(u'parse')
return None
content = content.findAll(u'li')
return [
book.contents[0].contents[0] for book in content
]
class CWExtract(object):
"""
Extract verses from CrossWalk/BibleStudyTools
"""
def __init__(self, proxyurl=None):
log.debug(u'init %s', proxyurl)
log.debug(u'CWExtract.init("%s")', proxyurl)
self.proxyurl = proxyurl
socket.setdefaulttimeout(30)
@ -324,7 +261,7 @@ class CWExtract(object):
Access and decode bibles via the Crosswalk website
``version``
The version of the bible like niv for New International Version
The version of the Bible like niv for New International Version
``bookname``
Text name of in english e.g. 'gen' for Genesis
@ -332,10 +269,13 @@ class CWExtract(object):
``chapter``
Chapter number
"""
log.debug(u'get_bible_chapter %s,%s,%s', version, bookname, chapter)
log.debug(u'CWExtract.get_bible_chapter("%s", "%s", "%s")', version,
bookname, chapter)
urlbookname = bookname.replace(u' ', u'-')
urlbookname = urlbookname.lower()
urlbookname = urllib.quote(urlbookname.encode("utf-8"))
chapter_url = u'http://www.biblestudytools.com/%s/%s/%s.html' % \
(version, urlbookname.lower(), chapter)
(version, urlbookname, chapter)
soup = get_soup_for_bible_ref(chapter_url)
if not soup:
return None
@ -378,6 +318,32 @@ class CWExtract(object):
verses[versenumber] = versetext
return SearchResults(bookname, chapter, verses)
def get_books_from_http(self, version):
"""
Load a list of all books a Bible contain from the Crosswalk website.
``version``
The version of the bible like NIV for New International Version
"""
log.debug(u'CWExtract.get_books_from_http("%s")', version)
chapter_url = u'http://www.biblestudytools.com/%s/'\
% (version)
soup = get_soup_for_bible_ref(chapter_url)
if not soup:
return None
content = soup.find(u'div', {u'class': u'Body'})
content = content.find(u'ul', {u'class': u'parent'})
if not content:
log.exception(u'No books found in the Crosswalk response.')
send_error_message(u'parse')
return None
content = content.findAll(u'li')
books = []
for book in content:
book = book.find(u'a')
books.append(book.contents[0])
return books
class HTTPBible(BibleDB):
log.info(u'%s HTTPBible loaded' , __name__)
@ -400,6 +366,8 @@ class HTTPBible(BibleDB):
self.proxy_server = None
self.proxy_username = None
self.proxy_password = None
if u'path' in kwargs:
self.path = kwargs[u'path']
if u'proxy_server' in kwargs:
self.proxy_server = kwargs[u'proxy_server']
if u'proxy_username' in kwargs:
@ -407,13 +375,15 @@ class HTTPBible(BibleDB):
if u'proxy_password' in kwargs:
self.proxy_password = kwargs[u'proxy_password']
def do_import(self):
def do_import(self, bible_name=None):
"""
Run the import. This method overrides the parent class method. Returns
``True`` on success, ``False`` on failure.
"""
self.wizard.progressBar.setMaximum(2)
self.wizard.incrementProgressBar('Registering bible...')
self.wizard.progressBar.setMaximum(68)
self.wizard.incrementProgressBar(unicode(translate(
'BiblesPlugin.HTTPBible',
'Registering Bible and loading books...')))
self.create_meta(u'download source', self.download_source)
self.create_meta(u'download name', self.download_name)
if self.proxy_server:
@ -424,7 +394,51 @@ class HTTPBible(BibleDB):
if self.proxy_password:
# Store the proxy password.
self.create_meta(u'proxy password', self.proxy_password)
return True
if self.download_source.lower() == u'crosswalk':
handler = CWExtract(self.proxy_server)
elif self.download_source.lower() == u'biblegateway':
handler = BGExtract(self.proxy_server)
elif self.download_source.lower() == u'bibleserver':
handler = BSExtract(self.proxy_server)
books = handler.get_books_from_http(self.download_name)
if not books:
log.exception(u'Importing books from %s - download name: "%s" '\
'failed' % (self.download_source, self.download_name))
return False
self.wizard.progressBar.setMaximum(len(books)+2)
self.wizard.incrementProgressBar(unicode(translate(
'BiblesPlugin.HTTPBible', 'Registering Language...')))
bible = BiblesResourcesDB.get_webbible(self.download_name,
self.download_source.lower())
if bible[u'language_id']:
language_id = bible[u'language_id']
self.create_meta(u'language_id', language_id)
else:
language_id = self.get_language(bible_name)
if not language_id:
log.exception(u'Importing books from %s " '\
'failed' % self.filename)
return False
for book in books:
if self.stop_import_flag:
break
self.wizard.incrementProgressBar(unicode(translate(
'BiblesPlugin.HTTPBible', 'Importing %s...',
'Importing <book name>...')) % book)
book_ref_id = self.get_book_ref_id_by_name(book, len(books),
language_id)
if not book_ref_id:
log.exception(u'Importing books from %s - download name: "%s" '\
'failed' % (self.download_source, self.download_name))
return False
book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
log.debug(u'Book details: Name:%s; id:%s; testament_id:%s',
book, book_ref_id, book_details[u'testament_id'])
self.create_book(book, book_ref_id, book_details[u'testament_id'])
if self.stop_import_flag:
return False
else:
return True
def get_verses(self, reference_list, show_error=True):
"""
@ -438,34 +452,29 @@ class HTTPBible(BibleDB):
This is the list of references the media manager item wants. It is
a list of tuples, with the following format::
(book, chapter, start_verse, end_verse)
(book_reference_id, chapter, start_verse, end_verse)
Therefore, when you are looking for multiple items, simply break
them up into references like this, bundle them into a list. This
function then runs through the list, and returns an amalgamated
list of ``Verse`` objects. For example::
[(u'Genesis', 1, 1, 1), (u'Genesis', 2, 2, 3)]
[(u'35', 1, 1, 1), (u'35', 2, 2, 3)]
"""
log.debug(u'HTTPBible.get_verses("%s")', reference_list)
for reference in reference_list:
log.debug(u'Reference: %s', reference)
book = reference[0]
db_book = self.get_book(book)
book_id = reference[0]
db_book = self.get_book_by_book_ref_id(book_id)
if not db_book:
book_details = HTTPBooks.get_book(book)
if not book_details:
if show_error:
critical_error_message_box(
translate('BiblesPlugin', 'No Book Found'),
translate('BiblesPlugin', 'No matching '
'book could be found in this Bible. Check that you '
'have spelled the name of the book correctly.'))
return []
db_book = self.create_book(book_details[u'name'],
book_details[u'abbreviation'],
book_details[u'testament_id'])
if show_error:
critical_error_message_box(
translate('BiblesPlugin', 'No Book Found'),
translate('BiblesPlugin', 'No matching '
'book could be found in this Bible. Check that you '
'have spelled the name of the book correctly.'))
return []
book = db_book.name
if BibleDB.get_verse_count(self, book, reference[1]) == 0:
if BibleDB.get_verse_count(self, book_id, reference[1]) == 0:
Receiver.send_message(u'cursor_busy')
search_results = self.get_chapter(book, reference[1])
if search_results and search_results.has_verselist():
@ -488,7 +497,7 @@ class HTTPBible(BibleDB):
"""
Receive the request and call the relevant handler methods.
"""
log.debug(u'get_chapter %s, %s', book, chapter)
log.debug(u'HTTPBible.get_chapter("%s", "%s")', book, chapter)
log.debug(u'source = %s', self.download_source)
if self.download_source.lower() == u'crosswalk':
handler = CWExtract(self.proxy_server)
@ -502,16 +511,20 @@ class HTTPBible(BibleDB):
"""
Return the list of books.
"""
return [Book.populate(name=book['name'])
for book in HTTPBooks.get_books()]
log.debug(u'HTTPBible.get_books("%s")', Book.name)
return self.get_all_objects(Book, order_by_ref=Book.id)
def get_chapter_count(self, book):
"""
Return the number of chapters in a particular book.
``book``
The book object to get the chapter count for.
"""
return HTTPBooks.get_chapter_count(book)
log.debug(u'HTTPBible.get_chapter_count("%s")', book.name)
return BiblesResourcesDB.get_chapter_count(book.book_reference_id)
def get_verse_count(self, book, chapter):
def get_verse_count(self, book_id, chapter):
"""
Return the number of verses for the specified chapter and book.
@ -521,7 +534,8 @@ class HTTPBible(BibleDB):
``chapter``
The chapter whose verses are being counted.
"""
return HTTPBooks.get_verse_count(book, chapter)
log.debug(u'HTTPBible.get_verse_count("%s", %s)', book_id, chapter)
return BiblesResourcesDB.get_verse_count(book_id, chapter)
def get_soup_for_bible_ref(reference_url, header=None, pre_parse_regex=None,
pre_parse_substitute=None, cleaner=None):

View File

@ -31,9 +31,10 @@ import os
from PyQt4 import QtCore
from openlp.core.lib import Receiver, SettingsManager, translate
from openlp.core.lib.ui import critical_error_message_box
from openlp.core.utils import AppLocation, delete_file
from openlp.plugins.bibles.lib import parse_reference
from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta
from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta, OldBibleDB
from csvbible import CSVBible
from http import HTTPBible
from opensong import OpenSongBible
@ -140,8 +141,11 @@ class BibleManager(object):
"""
log.debug(u'Reload bibles')
files = SettingsManager.get_files(self.settingsSection, self.suffix)
if u'alternative_book_names.sqlite' in files:
files.remove(u'alternative_book_names.sqlite')
log.debug(u'Bible Files %s', files)
self.db_cache = {}
self.old_bible_databases = []
for filename in files:
bible = BibleDB(self.parent, path=self.path, file=filename)
name = bible.get_name()
@ -149,6 +153,11 @@ class BibleManager(object):
if name is None:
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(u'Bible Name: "%s"', name)
self.db_cache[name] = bible
# Look to see if lazy load bible exists and get create getter.
@ -210,8 +219,9 @@ class BibleManager(object):
log.debug(u'BibleManager.get_books("%s")', bible)
return [
{
u'name': book.name,
u'chapters': self.db_cache[bible].get_chapter_count(book.name)
u'name': book.name,
u'chapters': self.db_cache[bible].get_chapter_count(
book)
}
for book in self.db_cache[bible].get_books()
]
@ -219,8 +229,15 @@ class BibleManager(object):
def get_chapter_count(self, bible, book):
"""
Returns the number of Chapters for a given book.
``bible``
Unicode. The Bible to get the list of books from.
``book``
The book object to get the chapter count for.
"""
log.debug(u'get_book_chapter_count %s', book)
log.debug(u'BibleManager.get_book_chapter_count ("%s", "%s")', bible,
book.name)
return self.db_cache[bible].get_chapter_count(book)
def get_verse_count(self, bible, book, chapter):
@ -230,9 +247,11 @@ class BibleManager(object):
"""
log.debug(u'BibleManager.get_verse_count("%s", "%s", %s)',
bible, book, chapter)
return self.db_cache[bible].get_verse_count(book, chapter)
db_book = self.db_cache[bible].get_book(book)
book_ref_id = db_book.book_reference_id
return self.db_cache[bible].get_verse_count(book_ref_id, chapter)
def get_verses(self, bible, versetext, show_error=True):
def get_verses(self, bible, versetext, firstbible=False, show_error=True):
"""
Parses a scripture reference, fetches the verses from the Bible
specified, and returns a list of ``Verse`` objects.
@ -264,6 +283,28 @@ class BibleManager(object):
return None
reflist = parse_reference(versetext)
if reflist:
new_reflist = []
for item in reflist:
if item:
if firstbible:
db_book = self.db_cache[firstbible].get_book(item[0])
db_book = self.db_cache[bible].get_book_by_book_ref_id(
db_book.book_reference_id)
else:
db_book = self.db_cache[bible].get_book(item[0])
if db_book:
book_id = db_book.book_reference_id
log.debug(u'Book name corrected to "%s"', db_book.name)
new_reflist.append((book_id, item[1], item[2],
item[3]))
else:
log.debug(u'OpenLP failed to find book %s', item[0])
critical_error_message_box(
translate('BiblesPlugin', 'No Book Found'),
translate('BiblesPlugin', 'No matching book '
'could be found in this Bible. Check that you have '
'spelled the name of the book correctly.'))
reflist = new_reflist
return self.db_cache[bible].get_verses(reflist, show_error)
else:
if show_error:

View File

@ -602,7 +602,7 @@ class BibleMediaItem(MediaManagerItem):
self.search_results = self.plugin.manager.get_verses(bible, versetext)
if second_bible:
self.second_search_results = self.plugin.manager.get_verses(
second_bible, versetext)
second_bible, versetext, bible)
if not self.advancedLockButton.isChecked():
self.listView.clear()
if self.listView.count() != 0:
@ -630,7 +630,7 @@ class BibleMediaItem(MediaManagerItem):
self.search_results = self.plugin.manager.get_verses(bible, text)
if second_bible and self.search_results:
self.second_search_results = self.plugin.manager.get_verses(
second_bible, text)
second_bible, text, bible)
else:
# We are doing a 'Text Search'.
Receiver.send_message(u'cursor_busy')

View File

@ -30,7 +30,7 @@ import sqlite
from openlp.core.lib import Receiver
from openlp.core.ui.wizard import WizardStrings
from openlp.plugins.bibles.lib.db import BibleDB
from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB
log = logging.getLogger(__name__)
@ -46,7 +46,7 @@ class OpenLP1Bible(BibleDB):
BibleDB.__init__(self, parent, **kwargs)
self.filename = kwargs[u'filename']
def do_import(self):
def do_import(self, bible_name=None):
"""
Imports an openlp.org v1 bible.
"""
@ -57,6 +57,11 @@ class OpenLP1Bible(BibleDB):
cursor = connection.cursor()
except:
return False
#Create the bible language
language_id = self.get_language(bible_name)
if not language_id:
log.exception(u'Importing books from "%s" failed' % self.filename)
return False
# Create all books.
cursor.execute(u'SELECT id, testament_id, name, abbreviation FROM book')
books = cursor.fetchall()
@ -69,7 +74,15 @@ class OpenLP1Bible(BibleDB):
testament_id = int(book[1])
name = unicode(book[2], u'cp1252')
abbreviation = unicode(book[3], u'cp1252')
self.create_book(name, abbreviation, testament_id)
book_ref_id = self.get_book_ref_id_by_name(name, len(books),
language_id)
if not book_ref_id:
log.exception(u'Importing books from "%s" '\
'failed' % self.filename)
return False
book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
db_book = self.create_book(name, book_ref_id,
book_details[u'testament_id'])
# Update the progess bar.
self.wizard.incrementProgressBar(WizardStrings.ImportingType % name)
# Import the verses for this book.
@ -83,7 +96,7 @@ class OpenLP1Bible(BibleDB):
chapter = int(verse[0])
verse_number = int(verse[1])
text = unicode(verse[2], u'cp1252')
self.create_verse(book_id, chapter, verse_number, text)
self.create_verse(db_book.id, chapter, verse_number, text)
Receiver.send_message(u'openlp_process_events')
self.session.commit()
connection.close()

View File

@ -29,7 +29,7 @@ import logging
from lxml import objectify
from openlp.core.lib import Receiver, translate
from openlp.plugins.bibles.lib.db import BibleDB
from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB
log = logging.getLogger(__name__)
@ -46,7 +46,7 @@ class OpenSongBible(BibleDB):
BibleDB.__init__(self, parent, **kwargs)
self.filename = kwargs['filename']
def do_import(self):
def do_import(self, bible_name=None):
"""
Loads a Bible from file.
"""
@ -62,11 +62,23 @@ class OpenSongBible(BibleDB):
file = open(self.filename, u'r')
opensong = objectify.parse(file)
bible = opensong.getroot()
language_id = self.get_language(bible_name)
if not language_id:
log.exception(u'Importing books from "%s" '\
'failed' % self.filename)
return False
for book in bible.b:
if self.stop_import_flag:
break
db_book = self.create_book(unicode(book.attrib[u'n']),
unicode(book.attrib[u'n'][:4]))
book_ref_id = self.get_book_ref_id_by_name(
unicode(book.attrib[u'n']), len(bible.b), language_id)
if not book_ref_id:
log.exception(u'Importing books from "%s" '\
'failed' % self.filename)
return False
book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
db_book = self.create_book(unicode(book.attrib[u'n']),
book_ref_id, book_details[u'testament_id'])
for chapter in book.c:
if self.stop_import_flag:
break

View File

@ -34,7 +34,7 @@ import re
from openlp.core.lib import Receiver, translate
from openlp.core.utils import AppLocation
from openlp.plugins.bibles.lib.db import BibleDB
from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB
log = logging.getLogger(__name__)
@ -86,7 +86,7 @@ class OSISBible(BibleDB):
if fbibles:
fbibles.close()
def do_import(self):
def do_import(self, bible_name=None):
"""
Loads a Bible from file.
"""
@ -96,7 +96,6 @@ class OSISBible(BibleDB):
osis = None
success = True
last_chapter = 0
testament = 1
match_count = 0
self.wizard.incrementProgressBar(translate('BiblesPlugin.OsisImport',
'Detecting encoding (this may take a few minutes)...'))
@ -109,6 +108,11 @@ class OSISBible(BibleDB):
finally:
if detect_file:
detect_file.close()
# Set meta language_id
language_id = self.get_language(bible_name)
if not language_id:
log.exception(u'Importing books from "%s" failed' % self.filename)
return False
try:
osis = codecs.open(self.filename, u'r', details['encoding'])
repl = replacement
@ -123,13 +127,19 @@ class OSISBible(BibleDB):
verse = int(match.group(3))
verse_text = match.group(4)
if not db_book or db_book.name != self.books[book][0]:
log.debug(u'New book: "%s"', self.books[book][0])
if book == u'Matt' or book == u'Jdt':
testament += 1
log.debug(u'New book: "%s"' % self.books[book][0])
book_ref_id = self.get_book_ref_id_by_name(unicode(
self.books[book][0]), 67, language_id)
if not book_ref_id:
log.exception(u'Importing books from "%s" '\
'failed' % self.filename)
return False
book_details = BiblesResourcesDB.get_book_by_id(
book_ref_id)
db_book = self.create_book(
unicode(self.books[book][0]),
unicode(self.books[book][1]),
testament)
book_ref_id,
book_details[u'testament_id'])
if last_chapter == 0:
if book == u'Gen':
self.wizard.progressBar.setMaximum(1188)

View File

@ -1,81 +0,0 @@
João Ferreira de Almeida Atualizada,AA
التفسير التطبيقى للكتاب المقدس,ALAB
Shqip,ALB
Amplified Bible,AMP
Amuzgo de Guerrero,AMU
American Standard Version,ASV
La Bible du Semeur,BDS
Български 1940,BG1940
Български,BULG
Chinanteco de Comaltepec,CCO
Contemporary English Version,CEV
Cakchiquel Occidental,CKW
Hrvatski,CRO
Castilian,CST
聖經和合本 (简体中文),CUVS
聖經和合本 (繁体中文),CUV
Darby Translation,DARBY
Dette er Biblen på dansk,DN1933
Det Norsk Bibelselskap 1930,DNB1930
English Standard Version,ESV
GODS WORD Translation,GW
Holman Christian Standard Bible,HCSB
Kreyòl ayisyen bib,HCV
Hiligaynon Bible,HLGN
Hoffnung für Alle,HOF
Het Boek,HTB
Icelandic Bible,ICELAND
Jacalteco Oriental,JAC
Károlyi-biblia,KAR
Kekchi,KEK
21st Century King James Version,KJ21
King James Version,KJV
La Biblia de las Américas,LBLA
Levande Bibeln,LB
La Parola è Vita,LM
La Nuova Diodati,LND
Louis Segond,LSG
Luther Bibel 1545,LUTH1545
Māori Bible,MAORI
Македонски Новиот Завет,MNT
The Message,MSG
Mam de Comitancillo Central,MVC
Mam de Todos Santos Cuchumatán,MVJ
New American Standard Bible,NASB
New Century Version,NCV
Náhuatl de Guerrero,NGU
New International Reader's Version,NIRV
New International Version 1984,NIV1984
New International Version 2010,NIV
New International Version - UK,NIVUK
New King James Version,NKJV
New Living Translation,NLT
Nádej pre kazdého,NPK
Nueva Versión Internacional,NVI
O Livro,OL
Quiché Centro Occidental,QUT
Reimer 2001,REIMER
Română Cornilescu,RMNN
Новый перевод на русский язык,RUSV
Reina-Valera Antigua,RVA
Reina-Valera 1960,RVR1960
Reina-Valera 1995,RVR1995
Slovo na cestu,SNC
Ang Salita ng Diyos,SND
Swahili New Testament,SNT
Svenska 1917,SV1917
Levande Bibeln,SVL
Создать страницу,SZ
Traducción en lenguaje actual,TLA
New Romanian Translation,TLCR
Todays New International Version 2005,TNIV
Textus Receptus Stephanus 1550,TR1550
Textus Receptus Scrivener 1894,TR1894
Українська Біблія. Переклад Івана Огієнка,UKR
Uspanteco,USP
Kinh Thánh tiếng Việt 1934,VIET
Worldwide English (New Testament),WE
Codex Vaticanus Westcott-Hort 1881,WHNU
Westminster Leningrad Codex,WLC
Wycliffe New Testament,WYC
Young's Literal Translation,YLT
1 João Ferreira de Almeida Atualizada AA
2 التفسير التطبيقى للكتاب المقدس ALAB
3 Shqip ALB
4 Amplified Bible AMP
5 Amuzgo de Guerrero AMU
6 American Standard Version ASV
7 La Bible du Semeur BDS
8 Български 1940 BG1940
9 Български BULG
10 Chinanteco de Comaltepec CCO
11 Contemporary English Version CEV
12 Cakchiquel Occidental CKW
13 Hrvatski CRO
14 Castilian CST
15 聖經和合本 (简体中文) CUVS
16 聖經和合本 (繁体中文) CUV
17 Darby Translation DARBY
18 Dette er Biblen på dansk DN1933
19 Det Norsk Bibelselskap 1930 DNB1930
20 English Standard Version ESV
21 GOD’S WORD Translation GW
22 Holman Christian Standard Bible HCSB
23 Kreyòl ayisyen bib HCV
24 Hiligaynon Bible HLGN
25 Hoffnung für Alle HOF
26 Het Boek HTB
27 Icelandic Bible ICELAND
28 Jacalteco – Oriental JAC
29 Károlyi-biblia KAR
30 Kekchi KEK
31 21st Century King James Version KJ21
32 King James Version KJV
33 La Biblia de las Américas LBLA
34 Levande Bibeln LB
35 La Parola è Vita LM
36 La Nuova Diodati LND
37 Louis Segond LSG
38 Luther Bibel 1545 LUTH1545
39 Māori Bible MAORI
40 Македонски Новиот Завет MNT
41 The Message MSG
42 Mam de Comitancillo Central MVC
43 Mam de Todos Santos Cuchumatán MVJ
44 New American Standard Bible NASB
45 New Century Version NCV
46 Náhuatl de Guerrero NGU
47 New International Reader's Version NIRV
48 New International Version 1984 NIV1984
49 New International Version 2010 NIV
50 New International Version - UK NIVUK
51 New King James Version NKJV
52 New Living Translation NLT
53 Nádej pre kazdého NPK
54 Nueva Versión Internacional NVI
55 O Livro OL
56 Quiché – Centro Occidental QUT
57 Reimer 2001 REIMER
58 Română Cornilescu RMNN
59 Новый перевод на русский язык RUSV
60 Reina-Valera Antigua RVA
61 Reina-Valera 1960 RVR1960
62 Reina-Valera 1995 RVR1995
63 Slovo na cestu SNC
64 Ang Salita ng Diyos SND
65 Swahili New Testament SNT
66 Svenska 1917 SV1917
67 Levande Bibeln SVL
68 Создать страницу SZ
69 Traducción en lenguaje actual TLA
70 New Romanian Translation TLCR
71 Today’s New International Version 2005 TNIV
72 Textus Receptus Stephanus 1550 TR1550
73 Textus Receptus Scrivener 1894 TR1894
74 Українська Біблія. Переклад Івана Огієнка UKR
75 Uspanteco USP
76 Kinh Thánh tiếng Việt 1934 VIET
77 Worldwide English (New Testament) WE
78 Codex Vaticanus Westcott-Hort 1881 WHNU
79 Westminster Leningrad Codex WLC
80 Wycliffe New Testament WYC
81 Young's Literal Translation YLT

View File

@ -1,39 +0,0 @@
عربي, ARA
Bible překlad 21. století, B21
Bible du Semeur, BDS
Българската Библия, BLG
Český ekumenický překlad, CEP
Hrvatski, CRO
Священное Писание, CRS
Version La Biblia al Dia, CST
中文和合本(简体), CUVS
Bibelen på hverdagsdansk, DK
Revidierte Elberfelder, ELB
Einheitsübersetzung, EU
Gute Nachricht Bibel, GNB
Hoffnung für alle, HFA
Hungarian, HUN
Het Boek, HTB
La Parola è Vita, ITA
IBS-fordítás (Új Károli), KAR
King James Version, KJV
Luther 1984, LUT
Septuaginta, LXX
Neue Genfer Übersetzung, NGU
New International Readers Version, NIRV
New International Version, NIV
Neues Leben, NL
En Levende Bok (NOR), NOR
Nádej pre kazdého, NPK
Noua traducere în limba românã, NTR
Nueva Versión Internacional, NVI
הברית הישנה, OT
Słowo Życia, POL
O Livro, PRT
Новый перевод на русский язык, RUS
Slovo na cestu, SNC
Schlachter 2000, SLT
En Levande Bok (SWE), SVL
Today's New International Version, TNIV
Türkçe, TR
Biblia Vulgata, VUL
1 عربي ARA
2 Bible – překlad 21. století B21
3 Bible du Semeur BDS
4 Българската Библия BLG
5 Český ekumenický překlad CEP
6 Hrvatski CRO
7 Священное Писание CRS
8 Version La Biblia al Dia CST
9 中文和合本(简体) CUVS
10 Bibelen på hverdagsdansk DK
11 Revidierte Elberfelder ELB
12 Einheitsübersetzung EU
13 Gute Nachricht Bibel GNB
14 Hoffnung für alle HFA
15 Hungarian HUN
16 Het Boek HTB
17 La Parola è Vita ITA
18 IBS-fordítás (Új Károli) KAR
19 King James Version KJV
20 Luther 1984 LUT
21 Septuaginta LXX
22 Neue Genfer Übersetzung NGU
23 New International Readers Version NIRV
24 New International Version NIV
25 Neues Leben NL
26 En Levende Bok (NOR) NOR
27 Nádej pre kazdého NPK
28 Noua traducere în limba românã NTR
29 Nueva Versión Internacional NVI
30 הברית הישנה OT
31 Słowo Życia POL
32 O Livro PRT
33 Новый перевод на русский язык RUS
34 Slovo na cestu SNC
35 Schlachter 2000 SLT
36 En Levande Bok (SWE) SVL
37 Today's New International Version TNIV
38 Türkçe TR
39 Biblia Vulgata VUL

View File

@ -1,27 +0,0 @@
New American Standard,nas
American Standard Version,asv
English Standard Version,esv
New King James Version,nkj
King James Version,kjv
Holman Christian Standard Bible,csb
Third Millennium Bible,tmb
New International Version,niv
New Living Translation,nlt
New Revised Standard,nrs
Revised Standard Version,rsv
Good News Translation,gnt
Douay-Rheims Bible,rhe
The Message,msg
The Complete Jewish Bible,cjb
New Century Version,ncv
GOD'S WORD Translation,gwd
Hebrew Names Version,hnv
World English Bible,web
The Bible in Basic English,bbe
Young's Literal Translation,ylt
Today's New International Version,tnv
New International Reader's Version,nrv
The Darby Translation,dby
The Webster Bible,wbt
The Latin Vulgate,vul
Weymouth New Testament,wnt
1 New American Standard nas
2 American Standard Version asv
3 English Standard Version esv
4 New King James Version nkj
5 King James Version kjv
6 Holman Christian Standard Bible csb
7 Third Millennium Bible tmb
8 New International Version niv
9 New Living Translation nlt
10 New Revised Standard nrs
11 Revised Standard Version rsv
12 Good News Translation gnt
13 Douay-Rheims Bible rhe
14 The Message msg
15 The Complete Jewish Bible cjb
16 New Century Version ncv
17 GOD'S WORD Translation gwd
18 Hebrew Names Version hnv
19 World English Bible web
20 The Bible in Basic English bbe
21 Young's Literal Translation ylt
22 Today's New International Version tnv
23 New International Reader's Version nrv
24 The Darby Translation dby
25 The Webster Bible wbt
26 The Latin Vulgate vul
27 Weymouth New Testament wnt

Binary file not shown.

After

Width:  |  Height:  |  Size: 762 B

View File

@ -24,6 +24,7 @@
<qresource prefix="bibles">
<file>bibles_search_text.png</file>
<file>bibles_search_reference.png</file>
<file>bibles_upgrade_alert.png</file>
<file>bibles_search_unlock.png</file>
<file>bibles_search_lock.png</file>
</qresource>