Head r700 and import fixes

This commit is contained in:
Jon Tibble 2010-02-06 16:23:47 +00:00
commit f30136924f
39 changed files with 1730 additions and 1393 deletions

View File

@ -68,6 +68,10 @@ class OpenLP(QtGui.QApplication):
global log
log.info(u'OpenLP Application Loaded')
def notify(self, obj, evt):
#TODO needed for presentation exceptions
return QtGui.QApplication.notify(self, obj, evt)
def run(self):
"""
Run the OpenLP application.
@ -131,6 +135,7 @@ class OpenLP(QtGui.QApplication):
if show_splash:
# now kill the splashscreen
self.splash.finish(self.mainWindow)
self.mainWindow.repaint()
self.mainWindow.versionCheck()
return self.exec_()
@ -143,7 +148,7 @@ def main():
usage = u'Usage: %prog [options] [qt-options]'
parser = OptionParser(usage=usage)
parser.add_option("-l", "--log-level", dest="loglevel",
default="info", metavar="LEVEL",
default="warning", metavar="LEVEL",
help="Set logging to LEVEL level. Valid values are "
"\"debug\", \"info\", \"warning\".")
parser.add_option("-p", "--portable", dest="portable",
@ -154,7 +159,7 @@ def main():
help="Set the Qt4 style (passed directly to Qt4).")
# Set up logging
filename = u'openlp.log'
logfile = FileHandler(filename)
logfile = FileHandler(filename, u'w')
logfile.setFormatter(logging.Formatter(
u'%(asctime)s %(name)-15s %(levelname)-8s %(message)s'))
log.addHandler(logfile)

View File

@ -32,6 +32,7 @@ class BaseListWithDnD(QtGui.QListWidget):
def __init__(self, parent=None):
QtGui.QListWidget.__init__(self, parent)
self.parent = parent
# this must be set by the class which is inheriting
assert(self.PluginName)
@ -47,4 +48,5 @@ class BaseListWithDnD(QtGui.QListWidget):
mimeData = QtCore.QMimeData()
drag.setMimeData(mimeData)
mimeData.setText(self.PluginName)
dropAction = drag.start(QtCore.Qt.CopyAction)
dropAction = drag.start(QtCore.Qt.CopyAction)

View File

@ -104,6 +104,9 @@ class EventReceiver(QtCore.QObject):
``remote_edit_clear``
Informs all components that remote edit has been aborted.
``presentation types``
Informs all components of the presentation types supported.
"""
global log
log = logging.getLogger(u'EventReceiver')
@ -161,4 +164,5 @@ class Receiver():
"""
Get the global ``eventreceiver`` instance.
"""
return Receiver.eventreceiver
return Receiver.eventreceiver

View File

@ -253,7 +253,7 @@ class MediaManagerItem(QtGui.QWidget):
def addListViewToToolBar(self):
#Add the List widget
self.ListView = self.ListViewWithDnD_class()
self.ListView = self.ListViewWithDnD_class(self)
self.ListView.uniformItemSizes = True
self.ListView.setGeometry(QtCore.QRect(10, 100, 256, 591))
self.ListView.setSpacing(1)
@ -400,4 +400,4 @@ class MediaManagerItem(QtGui.QWidget):
if self.generateSlideData(service_item):
return service_item
else:
return None
return None

View File

@ -28,7 +28,7 @@ import logging
from PyQt4 import QtCore
from renderer import Renderer
from openlp.core.lib import ThemeLevel, resize_image
from openlp.core.lib import ThemeLevel
class RenderManager(object):
"""
@ -64,8 +64,6 @@ class RenderManager(object):
self.theme_level = u''
self.override_background = None
self.themedata = None
self.save_bg_frame = None
self.override_background_changed = False
def update_display(self, screen_number):
"""
@ -134,22 +132,6 @@ class RenderManager(object):
self.calculate_default(self.screens.current[u'size'])
self.renderer.set_theme(self.themedata)
self.build_text_rectangle(self.themedata)
#Replace the background image from renderer with one from image
if self.override_background:
if self.save_bg_frame is None:
self.save_bg_frame = self.renderer.bg_frame
if self.override_background_changed:
self.renderer.bg_frame = resize_image(
self.override_background, self.width, self.height)
self.override_background_changed = False
else:
if self.override_background_changed:
self.renderer.bg_frame = resize_image(
self.override_background, self.width, self.height)
self.override_background_changed = False
if self.save_bg_frame:
self.renderer.bg_frame = self.save_bg_frame
self.save_bg_frame = None
def build_text_rectangle(self, theme):
"""

View File

@ -29,7 +29,7 @@ import os
from PyQt4 import QtCore, QtGui
from PyQt4.phonon import Phonon
from openlp.core.lib import Receiver
from openlp.core.lib import Receiver, resize_image
class DisplayWidget(QtGui.QWidget):
"""
@ -95,10 +95,12 @@ class MainDisplay(DisplayWidget):
self.audio = Phonon.AudioOutput(Phonon.VideoCategory, self.mediaObject)
Phonon.createPath(self.mediaObject, self.video)
Phonon.createPath(self.mediaObject, self.audio)
self.display = QtGui.QLabel(self)
self.display.setScaledContents(True)
self.alertDisplay = QtGui.QLabel(self)
self.alertDisplay.setScaledContents(True)
self.display_image = QtGui.QLabel(self)
self.display_image.setScaledContents(True)
self.display_text = QtGui.QLabel(self)
self.display_text.setScaledContents(True)
self.display_alert = QtGui.QLabel(self)
self.display_alert.setScaledContents(True)
self.primary = True
self.displayBlank = False
self.blankFrame = None
@ -122,7 +124,7 @@ class MainDisplay(DisplayWidget):
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'media_play'), self.onMediaPlay)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'media_pause'), self.onMediaPaws)
QtCore.SIGNAL(u'media_pause'), self.onMediaPause)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'media_stop'), self.onMediaStop)
@ -138,11 +140,13 @@ class MainDisplay(DisplayWidget):
self.setGeometry(self.screen[u'size'])
self.alertScreenPosition = self.screen[u'size'].height() * 0.9
self.alertHeight = self.screen[u'size'].height() - self.alertScreenPosition
self.alertDisplay.setGeometry(
self.display_alert.setGeometry(
QtCore.QRect(0, self.alertScreenPosition,
self.screen[u'size'].width(),self.alertHeight))
self.video.setGeometry(self.screen[u'size'])
self.display.resize(self.screen[u'size'].width(),
self.display_image.resize(self.screen[u'size'].width(),
self.screen[u'size'].height())
self.display_text.resize(self.screen[u'size'].width(),
self.screen[u'size'].height())
#Build a custom splash screen
self.InitialFrame = QtGui.QImage(
@ -157,7 +161,8 @@ class MainDisplay(DisplayWidget):
(self.screen[u'size'].width() - splash_image.width()) / 2,
(self.screen[u'size'].height() - splash_image.height()) / 2,
splash_image)
self.frameView(self.InitialFrame)
self.display_image.setPixmap(QtGui.QPixmap.fromImage(self.InitialFrame))
self.repaint()
#Build a Black screen
painter = QtGui.QPainter()
self.blankFrame = QtGui.QImage(
@ -165,11 +170,14 @@ class MainDisplay(DisplayWidget):
self.screen[u'size'].height(),
QtGui.QImage.Format_ARGB32_Premultiplied)
painter.begin(self.blankFrame)
#TODO make black when testing finished
painter.fillRect(self.blankFrame.rect(), QtCore.Qt.red)
#buid a blank transparent image
#build a blank transparent image
self.transparent = QtGui.QPixmap(self.screen[u'size'].width(),
self.screen[u'size'].height())
self.transparent.fill(QtCore.Qt.transparent)
self.display_alert.setPixmap(self.transparent)
self.frameView(self.transparent)
# To display or not to display?
if not self.screen[u'primary']:
self.showFullScreen()
@ -181,6 +189,8 @@ class MainDisplay(DisplayWidget):
def resetDisplay(self):
if self.primary:
self.setVisible(False)
else:
self.showFullScreen()
def hideDisplay(self):
self.setVisible(False)
@ -188,6 +198,17 @@ class MainDisplay(DisplayWidget):
def showDisplay(self):
if not self.primary:
self.setVisible(True)
self.showFullScreen()
def addImageWithText(self, frame):
frame = resize_image(frame,
self.screen[u'size'].width(),
self.screen[u'size'].height() )
self.display_image.setPixmap(QtGui.QPixmap.fromImage(frame))
# self.display_image.show()
# if not self.isVisible():
# self.setVisible(True)
# self.showFullScreen()
def frameView(self, frame, transition=False):
"""
@ -199,18 +220,21 @@ class MainDisplay(DisplayWidget):
if not self.displayBlank:
if transition:
if self.frame is not None:
self.display.setPixmap(QtGui.QPixmap.fromImage(self.frame))
self.display_text.setPixmap(QtGui.QPixmap.fromImage(self.frame))
self.repaint()
self.frame = None
if frame[u'trans'] is not None:
self.display.setPixmap(QtGui.QPixmap.fromImage(frame[u'trans']))
self.display_text.setPixmap(QtGui.QPixmap.fromImage(frame[u'trans']))
self.repaint()
self.frame = frame[u'trans']
self.display.setPixmap(QtGui.QPixmap.fromImage(frame[u'main']))
self.display_text.setPixmap(QtGui.QPixmap.fromImage(frame[u'main']))
self.display_frame = frame[u'main']
self.repaint()
else:
self.display.setPixmap(QtGui.QPixmap.fromImage(frame))
if isinstance(frame, QtGui.QPixmap):
self.display_text.setPixmap(frame)
else:
self.display_text.setPixmap(QtGui.QPixmap.fromImage(frame))
self.display_frame = frame
if not self.isVisible():
self.setVisible(True)
@ -219,14 +243,12 @@ class MainDisplay(DisplayWidget):
def blankDisplay(self, blanked=True):
if blanked:
self.displayBlank = True
self.display.setPixmap(QtGui.QPixmap.fromImage(self.blankFrame))
self.display_text.setPixmap(QtGui.QPixmap.fromImage(self.blankFrame))
else:
self.displayBlank = False
if self.display_frame:
self.frameView(self.display_frame)
# if blanked != self.parent.LiveController.blankButton.isChecked():
# self.parent.LiveController.blankButton.setChecked(self.displayBlank)
# self.parent.generalConfig.set_config(u'screen blank', self.displayBlank)
def displayAlert(self, text=u''):
"""
@ -236,8 +258,11 @@ class MainDisplay(DisplayWidget):
display text
"""
log.debug(u'display alert called %s' % text)
self.parent.StatusBar.showMessage(self.trUtf8(u''))
self.alertList.append(text)
if self.timer_id != 0 or self.mediaLoaded:
self.parent.StatusBar.showMessage(\
self.trUtf8(u'Alert message created and delayed'))
return
self.generateAlert()
@ -269,22 +294,24 @@ class MainDisplay(DisplayWidget):
painter.drawText(
x, y + metrics.height() - metrics.descent() - 1, text)
painter.end()
self.alertDisplay.setPixmap(alertframe)
self.alertDisplay.setVisible(True)
self.display_alert.setPixmap(alertframe)
self.display_alert.setVisible(True)
# check to see if we have a timer running
if self.timer_id == 0:
self.timer_id = self.startTimer(int(alertTab.timeout) * 1000)
def timerEvent(self, event):
if event.timerId() == self.timer_id:
self.alertDisplay.setPixmap(self.transparent)
self.display_alert.setPixmap(self.transparent)
self.killTimer(self.timer_id)
self.timer_id = 0
self.generateAlert()
def onMediaQueue(self, message):
log.debug(u'Queue new media message %s' % message)
self.display.close()
self.display_image.close()
self.display_text.close()
self.display_alert.close()
file = os.path.join(message[1], message[2])
if self.firstTime:
self.mediaObject.setCurrentSource(Phonon.MediaSource(file))
@ -300,15 +327,16 @@ class MainDisplay(DisplayWidget):
self.display_frame = self.blankFrame
self.firstTime = True
self.mediaLoaded = True
self.display.hide()
self.alertDisplay.hide()
self.display_image.hide()
self.display_text.hide()
self.display_alert.hide()
self.video.setFullScreen(True)
self.video.setVisible(True)
self.mediaObject.play()
if self.primary:
self.setVisible(True)
self.setVisible(True)
self.hide()
def onMediaPaws(self):
def onMediaPause(self):
log.debug(u'Media paused by user')
self.mediaObject.pause()
@ -319,11 +347,10 @@ class MainDisplay(DisplayWidget):
def onMediaFinish(self):
log.debug(u'Reached end of media playlist')
if self.primary:
self.setVisible(False)
self.mediaObject.stop()
self.mediaObject.clearQueue()
self.mediaLoaded = False
self.video.setVisible(False)
self.display.show()
self.display_text.show()
self.display_image.show()
self.blankDisplay(False)

View File

@ -50,7 +50,6 @@ media_manager_style = """
border-color: palette(light);
}
"""
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
"""

View File

@ -225,12 +225,17 @@ class ServiceManager(QtGui.QWidget):
QtCore.SIGNAL(u'update_themes'), self.updateThemeList)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'remote_edit_clear'), self.onRemoteEditClear)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'presentation types'), self.onPresentationTypes)
# Last little bits of setting up
self.config = PluginConfig(u'ServiceManager')
self.servicePath = self.config.get_data_path()
self.service_theme = unicode(
self.config.get_config(u'service theme', u''))
def onPresentationTypes(self, presentation_types):
self.presentation_types = presentation_types
def onMoveSelectionUp(self):
"""
Moves the selection up the window
@ -433,10 +438,10 @@ class ServiceManager(QtGui.QWidget):
for item in self.serviceItems:
service.append({u'serviceitem':item[u'service_item'].get_service_repr()})
if item[u'service_item'].uses_file():
for frame in item[u'service_item'].get_frames:
for frame in item[u'service_item'].get_frames():
path_from = unicode(os.path.join(
item[u'service_item'].service_item_path,
frame.get_frame_title()))
frame[u'title']))
zip.write(path_from)
file = open(servicefile, u'wb')
cPickle.dump(service, file)
@ -499,7 +504,8 @@ class ServiceManager(QtGui.QWidget):
serviceitem = ServiceItem()
serviceitem.RenderManager = self.parent.RenderManager
serviceitem.set_from_service(item, self.servicePath)
self.addServiceItem(serviceitem)
if self.validateItem(serviceitem):
self.addServiceItem(serviceitem)
try:
if os.path.isfile(p_file):
os.remove(p_file)
@ -516,6 +522,14 @@ class ServiceManager(QtGui.QWidget):
self.serviceName = name[len(name) - 1]
self.parent.serviceChanged(True, self.serviceName)
def validateItem(self, serviceItem):
# print "---"
# print serviceItem.name
# print serviceItem.title
# print serviceItem.service_item_path
# print serviceItem.service_item_type
return True
def cleanUp(self):
"""
Empties the servicePath of temporary files
@ -617,7 +631,7 @@ class ServiceManager(QtGui.QWidget):
else:
pos = parentitem.data(0, QtCore.Qt.UserRole).toInt()[0]
count = item.data(0, QtCore.Qt.UserRole).toInt()[0]
#adjuest for zero based arrays
#adjust for zero based arrays
pos = pos - 1
return pos, count

View File

@ -249,32 +249,33 @@ class ThemeManager(QtGui.QWidget):
log.debug(u'Load themes from dir')
self.themelist = []
self.ThemeListWidget.clear()
for root, dirs, files in os.walk(self.path):
for name in files:
if name.endswith(u'.png'):
#check to see file is in theme root directory
theme = os.path.join(self.path, name)
if os.path.exists(theme):
(path, filename) = os.path.split(unicode(file))
textName = os.path.splitext(name)[0]
if textName == self.global_theme:
name = u'%s (%s)' % (textName,
self.trUtf8('default'))
else:
name = textName
thumb = os.path.join(self.thumbPath, u'%s.png' % textName)
item_name = QtGui.QListWidgetItem(name)
if os.path.exists(thumb):
icon = build_icon(thumb)
else:
icon = build_icon(theme)
pixmap = icon.pixmap(QtCore.QSize(88,50))
pixmap.save(thumb, u'png')
item_name.setIcon(icon)
item_name.setData(QtCore.Qt.UserRole,
QtCore.QVariant(textName))
self.ThemeListWidget.addItem(item_name)
self.themelist.append(textName)
#root, dirs, files = os.walk(self.path)
dirList = os.listdir(self.path)
for name in dirList:
if name.endswith(u'.png'):
#check to see file is in theme root directory
theme = os.path.join(self.path, name)
if os.path.exists(theme):
(path, filename) = os.path.split(unicode(file))
textName = os.path.splitext(name)[0]
if textName == self.global_theme:
name = u'%s (%s)' % (textName,
self.trUtf8('default'))
else:
name = textName
thumb = os.path.join(self.thumbPath, u'%s.png' % textName)
item_name = QtGui.QListWidgetItem(name)
if os.path.exists(thumb):
icon = build_icon(thumb)
else:
icon = build_icon(theme)
pixmap = icon.pixmap(QtCore.QSize(88,50))
pixmap.save(thumb, u'png')
item_name.setIcon(icon)
item_name.setData(QtCore.Qt.UserRole,
QtCore.QVariant(textName))
self.ThemeListWidget.addItem(item_name)
self.themelist.append(textName)
self.pushThemes()
def pushThemes(self):

View File

@ -40,12 +40,12 @@ class BiblePlugin(Plugin):
self.weight = -9
self.icon = build_icon(u':/media/media_bible.png')
#Register the bible Manager
self.biblemanager = None
self.manager = None
def initialise(self):
log.info(u'bibles Initialising')
if self.biblemanager is None:
self.biblemanager = BibleManager(self.config)
if self.manager is None:
self.manager = BibleManager(self, self.config)
Plugin.initialise(self)
self.insert_toolbox_item()
self.ImportBibleItem.setVisible(True)
@ -90,4 +90,5 @@ class BiblePlugin(Plugin):
about_text = self.trUtf8('<strong>Bible Plugin</strong><br />This '
'plugin allows bible verses from different sources to be '
'displayed on the screen during the service.')
return about_text
return about_text

View File

@ -91,15 +91,6 @@ class Ui_BibleImportWizard(object):
self.OsisLayout.setMargin(0)
self.OsisLayout.setSpacing(8)
self.OsisLayout.setObjectName(u'OsisLayout')
self.OsisBibleNameLabel = QtGui.QLabel(self.OsisPage)
self.OsisBibleNameLabel.setIndent(0)
self.OsisBibleNameLabel.setObjectName(u'OsisBibleNameLabel')
self.OsisLayout.setWidget(0, QtGui.QFormLayout.LabelRole,
self.OsisBibleNameLabel)
self.OsisBibleNameEdit = QtGui.QLineEdit(self.OsisPage)
self.OsisBibleNameEdit.setObjectName(u'OsisBibleNameEdit')
self.OsisLayout.setWidget(0, QtGui.QFormLayout.FieldRole,
self.OsisBibleNameEdit)
self.OsisLocationLabel = QtGui.QLabel(self.OsisPage)
self.OsisLocationLabel.setObjectName(u'OsisLocationLabel')
self.OsisLayout.setWidget(1, QtGui.QFormLayout.LabelRole,
@ -302,13 +293,11 @@ class Ui_BibleImportWizard(object):
self.ImportProgressLabel.setObjectName(u'ImportProgressLabel')
self.ImportLayout.addWidget(self.ImportProgressLabel)
self.ImportProgressBar = QtGui.QProgressBar(self.ImportPage)
self.ImportProgressBar.setProperty(u'value', 0)
self.ImportProgressBar.setInvertedAppearance(False)
self.ImportProgressBar.setValue(0)
self.ImportProgressBar.setObjectName(u'ImportProgressBar')
self.ImportLayout.addWidget(self.ImportProgressBar)
BibleImportWizard.addPage(self.ImportPage)
self.retranslateUi(BibleImportWizard)
self.FormatWidget.setCurrentIndex(0)
self.WebDownloadTabWidget.setCurrentIndex(0)
@ -334,7 +323,6 @@ class Ui_BibleImportWizard(object):
self.FormatComboBox.setItemText(1, self.trUtf8('CSV'))
self.FormatComboBox.setItemText(2, self.trUtf8('OpenSong'))
self.FormatComboBox.setItemText(3, self.trUtf8('Web Download'))
self.OsisBibleNameLabel.setText(self.trUtf8('Bible Name:'))
self.OsisLocationLabel.setText(self.trUtf8('File Location:'))
self.BooksLocationLabel.setText(self.trUtf8('Books Location:'))
self.VerseLocationLabel.setText(self.trUtf8('Verse Location:'))
@ -362,4 +350,4 @@ class Ui_BibleImportWizard(object):
self.ImportPage.setSubTitle(
self.trUtf8('Please wait while your Bible is imported.'))
self.ImportProgressLabel.setText(self.trUtf8('Ready.'))
#self.ImportProgressBar.setFormat(u'%p')
self.ImportProgressBar.setFormat(u'%p%')

View File

@ -23,6 +23,7 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
import csv
import logging
import os
import os.path
@ -44,8 +45,8 @@ class DownloadLocation(object):
}
@classmethod
def get_name(class_, id):
return class_.Names[id]
def get_name(cls, id):
return cls.Names[id]
class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
@ -58,7 +59,7 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
log = logging.getLogger(u'BibleImportForm')
log.info(u'BibleImportForm loaded')
def __init__(self, parent, config, biblemanager, bibleplugin):
def __init__(self, parent, config, manager, bibleplugin):
'''
Constructor
'''
@ -67,10 +68,10 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
self.registerFields()
self.finishButton = self.button(QtGui.QWizard.FinishButton)
self.cancelButton = self.button(QtGui.QWizard.CancelButton)
self.biblemanager = biblemanager
self.manager = manager
self.config = config
self.bibleplugin = bibleplugin
self.biblemanager.set_process_dialog(self)
self.manager.set_process_dialog(self)
self.web_bible_list = {}
self.loadWebBibles()
QtCore.QObject.connect(self.LocationComboBox,
@ -95,9 +96,9 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
QtCore.SIGNAL(u'currentIdChanged(int)'),
self.onCurrentIdChanged)
def show(self):
def exec_(self):
self.setDefaults()
return QtGui.QWizard.show()
return QtGui.QWizard.exec_(self)
def validateCurrentPage(self):
if self.currentId() == 0:
@ -106,14 +107,6 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
elif self.currentId() == 1:
# Select page
if self.field(u'source_format').toInt()[0] == BibleFormat.OSIS:
if self.field(u'osis_biblename').toString() == u'':
QtGui.QMessageBox.critical(self,
self.trUtf8('Invalid Bible Name'),
self.trUtf8('You need to specify a name for your '
'Bible!'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
self.OsisBibleNameEdit.setFocus()
return False
if self.field(u'osis_location').toString() == u'':
QtGui.QMessageBox.critical(self,
self.trUtf8('Invalid Bible Location'),
@ -168,6 +161,15 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
self.CopyrightEdit.setFocus()
return False
elif self.manager.exists(
self.field(u'license_version').toString()):
QtGui.QMessageBox.critical(self,
self.trUtf8('Bible Exists'),
self.trUtf8('This Bible already exists! Please import '
'a different Bible or first delete the existing one.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
self.VersionNameEdit.setFocus()
return False
return True
if self.currentId() == 3:
# Progress page
@ -208,8 +210,6 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
def registerFields(self):
self.SelectPage.registerField(
u'source_format', self.FormatComboBox)
self.SelectPage.registerField(
u'osis_biblename', self.OsisBibleNameEdit)
self.SelectPage.registerField(
u'osis_location', self.OSISLocationEdit)
self.SelectPage.registerField(
@ -237,23 +237,22 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
def setDefaults(self):
self.setField(u'source_format', 0)
self.setField(u'osis_biblename', u'')
self.setField(u'osis_location', u'')
self.setField(u'csv_booksfile', u'')
self.setField(u'csv_versefile', u'')
self.setField(u'opensong_file', u'')
self.setField(u'web_location', 0)
self.setField(u'osis_location', '')
self.setField(u'csv_booksfile', '')
self.setField(u'csv_versefile', '')
self.setField(u'opensong_file', '')
self.setField(u'web_location', DownloadLocation.Crosswalk)
self.setField(u'web_biblename', self.BibleComboBox)
self.setField(u'proxy_server',
self.config.get_config(u'proxy address', u''))
self.config.get_config(u'proxy address', ''))
self.setField(u'proxy_username',
self.config.get_config(u'proxy username',u''))
self.config.get_config(u'proxy username',''))
self.setField(u'proxy_password',
self.config.get_config(u'proxy password',u''))
self.config.get_config(u'proxy password',''))
self.setField(u'license_version', self.VersionNameEdit)
self.setField(u'license_copyright', self.CopyrightEdit)
self.setField(u'license_permission', self.PermissionEdit)
self.onLocationComboBoxChanged(0)
self.onLocationComboBoxChanged(DownloadLocation.Crosswalk)
def loadWebBibles(self):
"""
@ -266,29 +265,33 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
fbibles = None
try:
self.web_bible_list[DownloadLocation.Crosswalk] = {}
fbibles = open(os.path.join(filepath, u'crosswalkbooks.csv'), 'r')
for line in fbibles:
parts = line.split(u',')
self.web_bible_list[DownloadLocation.Crosswalk][parts[0]] = \
parts[1].rstrip()
books_file = open(os.path.join(filepath, u'crosswalkbooks.csv'), 'r')
dialect = csv.Sniffer().sniff(books_file.read(1024))
books_file.seek(0)
books_reader = csv.reader(books_file, dialect)
for line in books_reader:
self.web_bible_list[DownloadLocation.Crosswalk][line[0]] = \
unicode(line[1], u'utf-8').strip()
except:
log.exception(u'Crosswalk resources missing')
finally:
if fbibles:
fbibles.close()
if books_file:
books_file.close()
#Load and store BibleGateway Bibles
try:
self.web_bible_list[DownloadLocation.BibleGateway] = {}
fbibles = open(os.path.join(filepath, u'biblegateway.csv'), 'r')
for line in fbibles:
parts = line.split(u',')
self.web_bible_list[DownloadLocation.BibleGateway][parts[0]] = \
parts[1].rstrip()
books_file = open(os.path.join(filepath, u'biblegateway.csv'), 'r')
dialect = csv.Sniffer().sniff(books_file.read(1024))
books_file.seek(0)
books_reader = csv.reader(books_file, dialect)
for line in books_reader:
self.web_bible_list[DownloadLocation.BibleGateway][line[0]] = \
unicode(line[1], u'utf-8').strip()
except:
log.exception(u'Biblegateway resources missing')
finally:
if fbibles:
fbibles.close()
if books_file:
books_file.close()
def getFileName(self, title, editbox):
filename = QtGui.QFileDialog.getOpenFileName(self, title,
@ -316,22 +319,22 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
success = False
if bible_type == BibleFormat.OSIS:
# Import an OSIS bible
success = self.biblemanager.register_osis_file_bible(
unicode(self.field(u'license_version').toString()),
unicode(self.field(u'osis_location').toString())
success = self.manager.import_bible(BibleFormat.OSIS,
name=unicode(self.field(u'license_version').toString()),
filename=unicode(self.field(u'osis_location').toString())
)
elif bible_type == BibleFormat.CSV:
# Import a CSV bible
success = self.biblemanager.register_csv_file_bible(
unicode(self.field(u'license_version').toString()),
self.field(u'csv_booksfile').toString(),
self.field(u'csv_versefile').toString()
success = self.manager.import_bible(BibleFormat.CSV,
name=unicode(self.field(u'license_version').toString()),
booksfile=self.field(u'csv_booksfile').toString(),
versefile=self.field(u'csv_versefile').toString()
)
elif bible_type == BibleFormat.OpenSong:
# Import an OpenSong bible
success = self.biblemanager.register_opensong_bible(
unicode(self.field(u'license_version').toString()),
self.field(u'opensong_file').toString()
success = self.manager.import_bible(BibleFormat.OpenSong,
name=unicode(self.field(u'license_version').toString()),
filename=self.field(u'opensong_file').toString()
)
elif bible_type == BibleFormat.WebDownload:
# Import a bible from the web
@ -343,21 +346,22 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
elif download_location == DownloadLocation.BibleGateway:
bible = self.web_bible_list[DownloadLocation.BibleGateway][
unicode(self.BibleComboBox.currentText())]
success = self.biblemanager.register_http_bible(
unicode(self.field(u'license_version').toString()),
unicode(DownloadLocation.get_name(download_location)),
unicode(bible),
unicode(self.field(u'proxy_server').toString()),
unicode(self.field(u'proxy_username').toString()),
unicode(self.field(u'proxy_password').toString())
success = self.manager.import_bible(BibleFormat.WebDownload,
name=unicode(self.field(u'license_version').toString()),
download_source=unicode(DownloadLocation.get_name(download_location)),
download_name=unicode(bible),
proxy_server=unicode(self.field(u'proxy_server').toString()),
proxy_username=unicode(self.field(u'proxy_username').toString()),
proxy_password=unicode(self.field(u'proxy_password').toString())
)
if success:
self.biblemanager.save_meta_data(
self.manager.save_meta_data(
unicode(self.field(u'license_version').toString()),
unicode(self.field(u'license_version').toString()),
unicode(self.field(u'license_copyright').toString()),
unicode(self.field(u'license_permission').toString())
)
self.manager.reload_bibles()
self.ImportProgressLabel.setText(self.trUtf8('Finished import.'))
else:
self.ImportProgressLabel.setText(
@ -367,4 +371,4 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
self.ImportProgressBar.setValue(self.ImportProgressBar.maximum())
self.finishButton.setVisible(True)
self.cancelButton.setVisible(False)
Receiver.send_message(u'process_events')
Receiver.send_message(u'process_events')

View File

@ -1,190 +0,0 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
###############################################################################
import os
import logging
from common import BibleCommon
from openlp.plugins.bibles.lib.models import *
class BibleDBImpl(BibleCommon):
global log
log = logging.getLogger(u'BibleDBImpl')
log.info(u'BibleDBimpl loaded')
def __init__(self, biblepath, biblename, config):
# Connect to database
self.config = config
self.biblefile = os.path.join(biblepath, biblename + u'.sqlite')
log.debug(u'Load bible %s on path %s', biblename, self.biblefile)
db_type = self.config.get_config(u'db type', u'sqlite')
db_url = u''
if db_type == u'sqlite':
db_url = u'sqlite:///' + self.biblefile
else:
db_url = u'%s://%s:%s@%s/%s' % \
(db_type, self.config.get_config(u'db username'),
self.config.get_config(u'db password'),
self.config.get_config(u'db hostname'),
self.config.get_config(u'db database'))
self.metadata, self.session = init_models(db_url)
self.metadata.create_all(checkfirst=True)
def create_tables(self):
log.debug(u'createTables')
self.save_meta(u'dbversion', u'2')
self._load_testament(u'Old Testament')
self._load_testament(u'New Testament')
self._load_testament(u'Apocrypha')
def add_verse(self, bookid, chap, vse, text):
verse = Verse()
verse.book_id = bookid
verse.chapter = chap
verse.verse = vse
verse.text = text
self.session.add(verse)
return verse
def save_verses(self):
log.debug('Saving verses...')
self.session.commit()
def create_chapter(self, bookid, chap, textlist):
log.debug(u'create_chapter %s,%s', bookid, chap)
#text list has book and chapter as first to elements of the array
for verse_number, verse_text in textlist.iteritems():
verse = Verse()
verse.book_id = bookid
verse.chapter = chap
verse.verse = verse_number
verse.text = verse_text
self.session.add(verse)
self.session.commit()
def create_book(self, bookname, bookabbrev, testament=1):
log.debug(u'create_book %s,%s', bookname, bookabbrev)
book = Book()
book.testament_id = testament
book.name = bookname
book.abbreviation = bookabbrev
self.session.add(book)
self.session.commit()
return book
def save_meta(self, key, value):
log.debug(u'save_meta %s/%s', key, value)
bmeta = BibleMeta()
bmeta.key = key
bmeta.value = value
self.session.add(bmeta)
self.session.commit()
def get_meta(self, metakey):
log.debug(u'get meta %s', metakey)
return self.session.query(BibleMeta).filter_by(key=metakey).first()
def delete_meta(self, metakey):
biblemeta = self.get_meta(metakey)
try:
self.session.delete(biblemeta)
self.session.commit()
return True
except:
return False
def _load_testament(self, testament):
log.debug(u'load_testaments %s', testament)
test = ONTestament()
test.name = testament
self.session.add(test)
self.session.commit()
def get_bible_books(self):
log.debug(u'get_bible_books')
return self.session.query(Book).order_by(Book.id).all()
def get_max_bible_book_verses(self, bookname, chapter):
log.debug(u'get_max_bible_book_verses %s, %s', bookname, chapter)
verse = self.session.query(Verse).join(Book).filter(
Book.name == bookname).filter(
Verse.chapter == chapter).order_by(Verse.verse.desc()).first()
if verse == None:
return 0
else:
return verse.verse
def get_max_bible_book_chapter(self, bookname):
log.debug(u'get_max_bible_book_chapter %s', bookname)
verse = self.session.query(Verse).join(Book).filter(
Book.name == bookname).order_by(Verse.chapter.desc()).first()
if verse == None:
return 0
else:
return verse.chapter
def get_bible_book(self, bookname):
log.debug(u'get_bible_book %s', bookname)
book = self.session.query(Book).filter(
Book.name.like(bookname + u'%')).first()
if book is None:
book = self.session.query(Book).filter(
Book.abbreviation.like(bookname + u'%')).first()
return book
def get_bible_chapter(self, id, chapter):
log.debug(u'get_bible_chapter %s, %s', id, chapter)
return self.session.query(Verse).filter_by(chapter=chapter).filter_by(
book_id=id).first()
def get_bible_text(self, bookname, chapter, sverse, everse):
log.debug(u'get_bible_text %s, %s, %s, %s', bookname, chapter, sverse,
everse)
#Look up book name or abbreviation
book = self.get_bible_book(bookname)
if book:
bookname = book.name
log.debug(u'bookname corrected to %s' % bookname)
verses = self.session.query(Verse).join(Book).filter(
Book.name == bookname).filter(Verse.chapter == chapter).filter(
Verse.verse>=sverse).filter(Verse.verse<=everse).order_by(
Verse.verse).all()
return verses
def get_verses_from_text(self, versetext):
log.debug(u'get_verses_from_text %s',versetext)
versetext = u'%%%s%%' % versetext
verses = self.session.query(Verse).filter(
Verse.text.like(versetext)).all()
return verses
def dump_bible(self):
log.debug( u'.........Dumping Bible Database')
log.debug( '...............................Books ')
books = self.session.query(Book).all()
log.debug(books)
log.debug( u'...............................Verses ')
verses = self.session.query(Verse).all()
log.debug(verses)

View File

@ -1,228 +0,0 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
###############################################################################
import logging
from common import BibleCommon, SearchResults
class BGExtract(BibleCommon):
global log
log = logging.getLogger(u'BibleHTTPMgr(BG_extract)')
log.info(u'BG_extract loaded')
def __init__(self, proxyurl= None):
log.debug(u'init %s', proxyurl)
self.proxyurl = proxyurl
def get_bible_chapter(self, version, bookname, chapter) :
"""
Access and decode bibles via the BibleGateway website
``Version``
The version of the bible like 31 for New International version
``bookname``
Name of the Book
``chapter``
Chapter number
"""
log.debug(u'get_bible_chapter %s,%s,%s',
version, bookname, chapter)
urlstring = \
u'http://www.biblegateway.com/passage/?search=%s+%d&version=%s' % \
(bookname, chapter, version)
log.debug(u'BibleGateway urm = %s' % urlstring)
xml_string = self._get_web_text(urlstring, self.proxyurl)
verseSearch = u'<sup class=\"versenum'
verseFootnote = u'<sup class=\'footnote'
verse = 1
i = xml_string.find(u'result-text-style-normal') + 26
xml_string = xml_string[i:len(xml_string)]
versePos = xml_string.find(verseSearch)
bible = {}
while versePos > -1:
# clear out string
verseText = u''
versePos = xml_string.find(u'</sup>', versePos) + 6
i = xml_string.find(verseSearch, versePos + 1)
# Not sure if this is needed now
if i == -1:
i = xml_string.find(u'</div', versePos + 1)
j = xml_string.find(u'<strong', versePos + 1)
if j > 0 and j < i:
i = j
verseText = xml_string[versePos + 7 : i ]
# store the verse
bible[verse] = self._clean_text(verseText)
versePos = -1
else:
verseText = xml_string[versePos: i]
start_tag = verseText.find(verseFootnote)
while start_tag > -1:
end_tag = verseText.find(u'</sup>')
verseText = verseText[:start_tag] + verseText[end_tag + 6:len(verseText)]
start_tag = verseText.find(verseFootnote)
# Chop off verse and start again
xml_string = xml_string[i:]
#look for the next verse
versePos = xml_string.find(verseSearch)
# store the verse
bible[verse] = self._clean_text(verseText)
verse += 1
return SearchResults(bookname, chapter, bible)
class CWExtract(BibleCommon):
global log
log = logging.getLogger(u'BibleHTTPMgr(CWExtract)')
log.info(u'CWExtract loaded')
def __init__(self, proxyurl=None):
log.debug(u'init %s', proxyurl)
self.proxyurl = proxyurl
def get_bible_chapter(self, version, bookname, chapter) :
log.debug(u'getBibleChapter %s,%s,%s',
version,bookname, chapter)
"""
Access and decode bibles via the Crosswalk website
``version``
The version of the bible like niv for New International Version
``bookname``
Text name of in english e.g. 'gen' for Genesis
``chapter``
Chapter number
"""
log.debug(u'get_bible_chapter %s,%s,%s',
version, bookname, chapter)
bookname = bookname.replace(u' ', u'')
urlstring = u'http://bible.crosswalk.com/OnlineStudyBible/bible.cgi?word=%s+%d&version=%s'\
% (bookname, chapter, version)
xml_string = self._get_web_text(urlstring, self.proxyurl)
## Strip Book Title from Heading to return it to system
##
i = xml_string.find(u'<title>')
j = xml_string.find(u'-', i)
book_title = xml_string[i + 7:j]
book_title = book_title.rstrip()
log.debug(u'Book Title %s', book_title)
i = book_title.rfind(u' ')
book_chapter = book_title[i+1:len(book_title)].rstrip()
book_title = book_title[:i].rstrip()
log.debug(u'Book Title %s', book_title)
log.debug(u'Book Chapter %s', book_chapter)
# Strip Verse Data from Page and build an array
i = xml_string.find(u'NavCurrentChapter')
xml_string = xml_string[i:len(xml_string)]
i = xml_string.find(u'<TABLE')
xml_string = xml_string[i:len(xml_string)]
i = xml_string.find(u'<B>')
#remove the <B> at the front
xml_string = xml_string[i + 3 :len(xml_string)]
# Remove the heading for the book
i = xml_string.find(u'<B>')
#remove the <B> at the front
xml_string = xml_string[i + 3 :len(xml_string)]
versePos = xml_string.find(u'<BLOCKQUOTE>')
bible = {}
while versePos > 0:
verseText = u''
versePos = xml_string.find(u'<B><I>', versePos) + 6
i = xml_string.find(u'</I></B>', versePos)
# Got the Chapter
verse = xml_string[versePos:i]
# move the starting position to begining of the text
versePos = i + 8
# find the start of the next verse
i = xml_string.find(u'<B><I>', versePos)
if i == -1:
i = xml_string.find(u'</BLOCKQUOTE>',versePos)
verseText = xml_string[versePos: i]
versePos = 0
else:
verseText = xml_string[versePos: i]
versePos = i
bible[verse] = self._clean_text(verseText)
return SearchResults(book_title, book_chapter, bible)
class BibleHTTPImpl():
global log
log = logging.getLogger(u'BibleHTTPMgr')
log.info(u'BibleHTTP manager loaded')
def __init__(self):
"""
Finds all the bibles defined for the system
Creates an Interface Object for each bible containing connection
information
Throws Exception if no Bibles are found.
Init confirms the bible exists and stores the database path.
"""
self.biblesource = u''
self.proxyurl = None
self.bibleid = None
def set_proxy(self, proxyurl):
"""
Set the Proxy Url
"""
log.debug(u'set_proxy %s', proxyurl)
self.proxyurl = proxyurl
def set_bibleid(self, bibleid):
"""
Set the bible id.
The shore identifier of the the bible.
"""
log.debug(u'set_bibleid %s', bibleid)
self.bibleid = bibleid
def set_bible_source(self, biblesource):
"""
Set the source of where the bible text is coming from
"""
log.debug(u'set_bible_source %s', biblesource)
self.biblesource = biblesource
def get_bible_chapter(self, version, bookname, chapter):
"""
Receive the request and call the relevant handler methods
"""
log.debug(u'get_bible_chapter %s,%s,%s',
version, bookname, chapter)
log.debug(u'biblesource = %s', self.biblesource)
try:
if self.biblesource.lower() == u'crosswalk':
ev = CWExtract(self.proxyurl)
else:
ev = BGExtract(self.proxyurl)
return ev.get_bible_chapter(self.bibleid, bookname, chapter)
except:
log.exception("Failed to get bible chapter")

View File

@ -26,8 +26,97 @@
import urllib2
import chardet
import logging
import re
class SearchResults:
only_verses = re.compile(r'([\w .]+)[ ]+([0-9]+)[ ]*[:|v|V][ ]*([0-9]+)'
r'(?:[ ]*-[ ]*([0-9]+|end))?(?:[ ]*,[ ]*([0-9]+)(?:[ ]*-[ ]*([0-9]+|end))?)?',
re.UNICODE)
chapter_range = re.compile(r'([\w .]+)[ ]+([0-9]+)[ ]*[:|v|V][ ]*'
r'([0-9]+)[ ]*-[ ]*([0-9]+)[ ]*[:|v|V][ ]*([0-9]+)',
re.UNICODE)
log = logging.getLogger(__name__)
def parse_reference(reference):
"""
This is the über-awesome function that takes a person's typed in string
and converts it to a reference list, a list of references to be queried
from the Bible database files.
The reference list is a list of tuples, with each tuple structured like
this::
(book, chapter, start_verse, end_verse)
"""
reference = reference.strip()
log.debug('parse_reference("%s")', reference)
reference_list = []
# We start with the most "complicated" match first, so that they are found
# first, and we don't have any "false positives".
match = chapter_range.match(reference)
if match:
log.debug('Found a chapter range.')
book = match.group(1)
from_verse = match.group(3)
to_verse = match.group(5)
if int(match.group(2)) == int(match.group(4)):
reference_list.append(
(match.group(1), int(match.group(2)), from_verse, to_verse)
)
else:
if int(match.group(2)) > int(match.group(4)):
from_chapter = int(match.group(4))
to_chapter = int(match.group(2))
else:
from_chapter = int(match.group(2))
to_chapter = int(match.group(4))
for chapter in xrange(from_chapter, to_chapter + 1):
if chapter == from_chapter:
reference_list.append(
(match.group(1), chapter, from_verse, -1)
)
elif chapter == to_chapter:
reference_list.append(
(match.group(1), chapter, 1, to_verse)
)
else:
reference_list.append(
(match.group(1), chapter, 1, -1)
)
else:
match = only_verses.match(reference)
if match:
log.debug('Found a verse range.')
book = match.group(1)
chapter = match.group(2)
verse = match.group(3)
if match.group(4) is None:
reference_list.append((book, chapter, verse, verse))
elif match.group(5) is None:
end_verse = match.group(4)
if end_verse == u'end':
end_verse = -1
reference_list.append((book, chapter, verse, end_verse))
elif match.group(6) is None:
reference_list.extend([
(book, chapter, verse, match.group(4)),
(book, chapter, match.group(5), match.group(5))
])
else:
end_verse = match.group(6)
if end_verse == u'end':
end_verse = -1
reference_list.extend([
(book, chapter, verse, match.group(4)),
(book, chapter, match.group(5), end_verse)
])
else:
log.debug('Didn\'t find anything.')
log.debug(reference_list)
return reference_list
class SearchResults(object):
"""
Encapsulate a set of search results. This is Bible-type independant.
"""
@ -81,12 +170,6 @@ class BibleCommon(object):
log = logging.getLogger(u'BibleCommon')
log.info(u'BibleCommon')
def __init__(self):
"""
An empty constructor... not sure why I'm here.
"""
pass
def _get_web_text(self, urlstring, proxyurl):
"""
Get the HTML from the web page.
@ -165,4 +248,4 @@ class BibleCommon(object):
text = text[:start_tag] + text[end_tag + 1:]
start_tag = text.find(u'<')
text = text.replace(u'>', u'')
return text.rstrip().lstrip()
return text.rstrip().lstrip()

View File

@ -25,96 +25,97 @@
import logging
import chardet
import csv
from openlp.plugins.bibles.lib.common import BibleCommon
from openlp.core.lib import Receiver
from db import BibleDB
class BibleCSVImpl(BibleCommon):
global log
log = logging.getLogger(u'BibleCSVImpl')
log.info(u'BibleCVSImpl loaded')
def __init__(self, bibledb):
log = logging.getLogger(__name__)
class CSVBible(BibleDB):
"""
This class provides a specialisation for importing of CSV Bibles.
"""
def __init__(self, parent, **kwargs):
"""
Loads a Bible from a pair of CVS files passed in
This class assumes the files contain all the information and
a clean bible is being loaded.
"""
self.bibledb = bibledb
self.loadbible = True
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'openlpstopimport'), self.stop_import)
BibleDB.__init__(self, parent, **kwargs)
log.info(self.__class__.__name__)
if u'booksfile' not in kwargs:
raise KeyError(u'You have to supply a file to import books from.')
self.booksfile = kwargs[u'booksfile']
if u'versesfile' not in kwargs:
raise KeyError(u'You have to supply a file to import verses from.')
self.versesfile = kwargs[u'versesfile']
#QtCore.QObject.connect(Receiver.get_receiver(),
# QtCore.SIGNAL(u'openlpstopimport'), self.stop_import)
def stop_import(self):
self.loadbible = False
"""
Stops the import of the Bible.
"""
log.debug('Stopping import!')
self.stop_import = True
def load_data(self, booksfile, versesfile, dialogobject):
def do_import(self):
#Populate the Tables
success = True
fbooks = None
books_file = None
try:
fbooks = open(booksfile, 'r')
count = 0
for line in fbooks:
books_file = open(self.booksfile, 'r')
dialect = csv.Sniffer().sniff(books_file.read(1024))
books_file.seek(0)
books_reader = csv.reader(books_file, dialect)
for line in books_reader:
# cancel pressed
if not self.loadbible:
if self.stop_import:
break
details = chardet.detect(line)
line = unicode(line, details['encoding'])
p = line.split(u',')
p1 = p[1].replace(u'"', u'')
p2 = p[2].replace(u'"', u'')
p3 = p[3].replace(u'"', u'')
self.bibledb.create_book(p2, p3, int(p1))
count += 1
#Flush the screen events
if count % 3 == 0:
Receiver.send_message(u'process_events')
count = 0
details = chardet.detect(line[1])
self.create_book(unicode(line[1], details['encoding']),
line[2], int(line[0]))
Receiver.send_message(u'process_events')
except:
log.exception(u'Loading books from file failed')
success = False
finally:
if fbooks:
fbooks.close()
if books_file:
books_file.close()
if not success:
return False
fverse = None
verse_file = None
try:
fverse = open(versesfile, 'r')
count = 0
book_ptr = None
for line in fverse:
if not self.loadbible: # cancel pressed
verse_file = open(versesfile, 'r')
dialect = csv.Sniffer().sniff(verse_file.read(1024))
verse_file.seek(0)
verse_reader = csv.reader(verse_file, dialect)
for line in verse_reader:
if self.stop_import: # cancel pressed
break
details = chardet.detect(line)
line = unicode(line, details['encoding'])
# split into 3 units and leave the rest as a single field
p = line.split(u',', 3)
p0 = p[0].replace(u'"', u'')
p3 = p[3].replace(u'"', u'')
if book_ptr is not p0:
book = self.bibledb.get_bible_book(p0)
details = chardet.detect(line[3])
if book_ptr != line[0]:
book = self.get_book(line[0])
book_ptr = book.name
# increament the progress bar
dialogobject.incrementProgressBar(u'Importing %s %s' % \
book.name)
self.bibledb.add_verse(book.id, p[1], p[2], p3)
count += 1
#Every x verses repaint the screen
if count % 3 == 0:
Receiver.send_message(u'process_events')
count = 0
self.bibledb.save_verses()
self.wizard.incrementProgressBar(
u'Importing %s %s' % (book.name, line[1]))
self.commit()
self.create_verse(book.id, line[1], line[2],
unicode(line[3], details['encoding']))
Receiver.send_message(u'process_events')
self.commit()
except:
log.exception(u'Loading verses from file failed')
success = False
finally:
if fverse:
fverse.close()
if not self.loadbible:
dialogobject.incrementProgressBar(u'Import canceled!')
dialogobject.ImportProgressBar.setValue(
dialogobject.ImportProgressBar.maximum())
if verse_file:
verse_file.close()
if self.stop_import:
self.wizard.incrementProgressBar(u'Import canceled!')
return False
else:
return success
return success

View File

@ -0,0 +1,286 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
###############################################################################
import os
import logging
import chardet
from sqlalchemy import or_
from PyQt4 import QtCore
from openlp.plugins.bibles.lib.models import *
log = logging.getLogger(__name__)
class BibleDB(QtCore.QObject):
"""
This class represents a database-bound Bible. It is used as a base class
for all the custom importers, so that the can implement their own import
methods, but benefit from the database methods in here via inheritance,
rather than depending on yet another object.
"""
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.
``config``
The configuration object, passed in from the plugin.
"""
log.info(u'BibleDBimpl loaded')
QtCore.QObject.__init__(self)
if u'path' not in kwargs:
raise KeyError(u'Missing keyword argument "path".')
if u'name' not in kwargs:
raise KeyError(u'Missing keyword argument "name".')
if u'config' not in kwargs:
raise KeyError(u'Missing keyword argument "config".')
self.stop_import = False
self.name = kwargs[u'name']
self.config = kwargs[u'config']
self.db_file = os.path.join(kwargs[u'path'],
u'%s.sqlite' % kwargs[u'name'])
log.debug(u'Load bible %s on path %s', kwargs[u'name'], self.db_file)
db_type = self.config.get_config(u'db type', u'sqlite')
db_url = u''
if db_type == u'sqlite':
db_url = u'sqlite:///' + self.db_file
else:
db_url = u'%s://%s:%s@%s/%s' % \
(db_type, self.config.get_config(u'db username'),
self.config.get_config(u'db password'),
self.config.get_config(u'db hostname'),
self.config.get_config(u'db database'))
self.metadata, self.session = init_models(db_url)
self.metadata.create_all(checkfirst=True)
def register(self, wizard):
"""
This method basically just initialialises the database. It is called
from the Bible Manager when a Bible is imported. Descendant classes
may want to override this method to supply their own custom
initialisation as well.
"""
self.wizard = wizard
self.create_tables()
return self.name
def commit(self):
log.debug('Committing...')
self.session.commit()
def create_tables(self):
log.debug(u'createTables')
self.create_meta(u'dbversion', u'2')
self.create_testament(u'Old Testament')
self.create_testament(u'New Testament')
self.create_testament(u'Apocrypha')
def create_testament(self, testament):
log.debug(u'BibleDB.create_testament("%s")', testament)
self.session.add(Testament.populate(name=testament))
self.commit()
def create_book(self, name, abbrev, testament=1):
log.debug(u'create_book %s,%s', name, abbrev)
book = Book.populate(name=name, abbreviation=abbrev,
testament_id=testament)
self.session.add(book)
self.commit()
return book
def create_chapter(self, book_id, chapter, textlist):
log.debug(u'create_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(
book_id = book_id,
chapter = chapter,
verse = verse_number,
text = verse_text
)
self.session.add(verse)
self.commit()
def create_verse(self, book_id, chapter, verse, text):
if not isinstance(text, unicode):
details = chardet.detect(text)
text = unicode(text, details[u'encoding'])
verse = Verse.populate(
book_id=book_id,
chapter=chapter,
verse=verse,
text=text
)
self.session.add(verse)
return verse
def create_meta(self, key, value):
log.debug(u'save_meta %s/%s', key, value)
self.session.add(BibleMeta.populate(key=key, value=value))
self.commit()
def get_books(self):
log.debug(u'BibleDB.get_books()')
return self.session.query(Book).order_by(Book.id).all()
def get_book(self, book):
log.debug(u'BibleDb.get_book("%s")', book)
db_book = self.session.query(Book)\
.filter(Book.name.like(book + u'%'))\
.first()
if db_book is None:
db_book = self.session.query(Book)\
.filter(Book.abbreviation.like(book + u'%'))\
.first()
return db_book
def get_chapter(self, id, chapter):
log.debug(u'BibleDB.get_chapter("%s", %s)', id, chapter)
return self.session.query(Verse)\
.filter_by(chapter=chapter)\
.filter_by(book_id=id)\
.first()
def get_verses(self, reference_list):
"""
This is probably the most used function. It retrieves the list of
verses based on the user's query.
``reference_list``
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)
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)]
"""
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)
if end_verse == -1:
end_verse = self.get_verse_count(book, chapter)
if db_book:
book = db_book.name
log.debug(u'Book name corrected to "%s"', book)
verses = self.session.query(Verse)\
.filter_by(book_id=db_book.id)\
.filter_by(chapter=chapter)\
.filter(Verse.verse >= start_verse)\
.filter(Verse.verse <= end_verse)\
.order_by(Verse.verse)\
.all()
verse_list.extend(verses)
return verse_list
def verse_search(self, text):
"""
Search for verses containing text ``text``.
``text``
The text to search for. If the text contains commas, it will be
split apart and OR'd on the list of values. If the text just
contains spaces, it will split apart and AND'd on the list of
values.
"""
log.debug(u'BibleDB.verse_search("%s")', text)
verses = self.session.query(Verse)
if text.find(u',') > -1:
or_clause = []
keywords = [u'%%%s%%' % keyword.strip() for keyword in text.split(u',')]
for keyword in keywords:
or_clause.append(Verse.text.like(keyword))
verses = verses.filter(or_(*or_clause))
else:
keywords = [u'%%%s%%' % keyword.strip() for keyword in text.split(u' ')]
for keyword in keywords:
verses = verses.filter(Verse.text.like(keyword))
verses = verses.all()
return verses
def get_chapter_count(self, book):
log.debug(u'BibleDB.get_chapter_count("%s")', book)
count = self.session.query(Verse.chapter).join(Book)\
.filter(Book.name==book)\
.distinct().count()
#verse = self.session.query(Verse).join(Book).filter(
# Book.name == bookname).order_by(Verse.chapter.desc()).first()
if not count:
return 0
else:
return count
def get_verse_count(self, book, chapter):
log.debug(u'BibleDB.get_verse_count("%s", %s)', book, chapter)
count = self.session.query(Verse).join(Book)\
.filter(Book.name==book)\
.filter(Verse.chapter==chapter)\
.count()
#verse = self.session.query(Verse).join(Book).filter(
# Book.name == bookname).filter(
# Verse.chapter == chapter).order_by(Verse.verse.desc()).first()
if not count:
return 0
else:
return count
def get_meta(self, key):
log.debug(u'get meta %s', key)
return self.session.query(BibleMeta).get(key)
def delete_meta(self, metakey):
biblemeta = self.get_meta(metakey)
try:
self.session.delete(biblemeta)
self.commit()
return True
except:
return False
def dump_bible(self):
log.debug(u'.........Dumping Bible Database')
log.debug('...............................Books ')
books = self.session.query(Book).all()
log.debug(books)
log.debug(u'...............................Verses ')
verses = self.session.query(Verse).all()
log.debug(verses)

View File

@ -0,0 +1,361 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
###############################################################################
import logging
import urllib2
import os
import sqlite3
from BeautifulSoup import BeautifulSoup
from openlp.core.lib import Receiver
from common import BibleCommon, SearchResults
from db import BibleDB
from openlp.plugins.bibles.lib.models import Book
class HTTPBooks(object):
cursor = None
@staticmethod
def get_cursor():
if HTTPBooks.cursor is None:
filepath = os.path.join(os.path.dirname(os.path.abspath(__file__)),
u'..', u'resources', u'httpbooks.sqlite')
conn = sqlite3.connect(filepath)
HTTPBooks.cursor = conn.cursor()
return HTTPBooks.cursor
@staticmethod
def run_sql(query, parameters=()):
cursor = HTTPBooks.get_cursor()
cursor.execute(query, parameters)
return cursor.fetchall()
@staticmethod
def get_books():
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):
if not isinstance(name, unicode):
name = unicode(name)
books = HTTPBooks.run_sql(u'SELECT id, testament_id, name, '
u'abbreviation, chapters FROM books WHERE name = ? OR '
u'abbreviation = ?', (name, name))
if len(books) > 0:
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):
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 len(chapters) > 0:
return {
u'id': chapters[0][0],
u'book_id': chapters[0][1],
u'chapter': chapters[0][2],
u'verses': chapters[0][3]
}
else:
return None
@staticmethod
def get_chapter_count(book):
details = HTTPBooks.get_book(book)
if details:
return details[u'chapters']
return 0
@staticmethod
def get_verse_count(book, chapter):
details = HTTPBooks.get_chapter(book, chapter)
if details:
return details[u'verses']
return 0
class BGExtract(BibleCommon):
global log
log = logging.getLogger(u'BibleHTTPMgr(BG_extract)')
log.info(u'BG_extract loaded')
def __init__(self, proxyurl=None):
log.debug(u'init %s', proxyurl)
self.proxyurl = proxyurl
def get_bible_chapter(self, version, bookname, chapter) :
"""
Access and decode bibles via the BibleGateway website
``Version``
The version of the bible like 31 for New International version
``bookname``
Name of the Book
``chapter``
Chapter number
"""
log.debug(u'get_bible_chapter %s, %s, %s', version, bookname, chapter)
urlstring = u'http://www.biblegateway.com/passage/?search=%s+%s' \
u'&version=%s' % (bookname, chapter, version)
log.debug(u'BibleGateway url = %s' % urlstring)
xml_string = self._get_web_text(urlstring, self.proxyurl)
verseSearch = u'<sup class=\"versenum'
verseFootnote = u'<sup class=\'footnote'
verse = 1
i = xml_string.find(u'result-text-style-normal') + 26
xml_string = xml_string[i:len(xml_string)]
versePos = xml_string.find(verseSearch)
bible = {}
while versePos > -1:
# clear out string
verseText = u''
versePos = xml_string.find(u'</sup>', versePos) + 6
i = xml_string.find(verseSearch, versePos + 1)
# Not sure if this is needed now
if i == -1:
i = xml_string.find(u'</div', versePos + 1)
j = xml_string.find(u'<strong', versePos + 1)
if j > 0 and j < i:
i = j
verseText = xml_string[versePos + 7 : i ]
# store the verse
bible[verse] = self._clean_text(verseText)
versePos = -1
else:
verseText = xml_string[versePos: i]
start_tag = verseText.find(verseFootnote)
while start_tag > -1:
end_tag = verseText.find(u'</sup>')
verseText = verseText[:start_tag] + verseText[end_tag + 6:len(verseText)]
start_tag = verseText.find(verseFootnote)
# Chop off verse and start again
xml_string = xml_string[i:]
#look for the next verse
versePos = xml_string.find(verseSearch)
# store the verse
bible[verse] = self._clean_text(verseText)
verse += 1
return SearchResults(bookname, chapter, bible)
class CWExtract(BibleCommon):
log.info(u'%s loaded', __name__)
def __init__(self, proxyurl=None):
log.debug(u'init %s', proxyurl)
self.proxyurl = proxyurl
def get_bible_chapter(self, version, bookname, chapter):
log.debug(u'%s %s, %s, %s', __name__, version, bookname, chapter)
"""
Access and decode bibles via the Crosswalk website
``version``
The version of the bible like niv for New International Version
``bookname``
Text name of in english e.g. 'gen' for Genesis
``chapter``
Chapter number
"""
log.debug(u'get_bible_chapter %s,%s,%s',
version, bookname, chapter)
bookname = bookname.replace(u' ', u'')
chapter_url = u'http://www.biblestudytools.com/%s/%s/%s.html' % \
(version, bookname.lower(), chapter)
log.debug(u'URL: %s', chapter_url)
page = urllib2.urlopen(chapter_url)
if not page:
return None
soup = BeautifulSoup(page)
htmlverses = soup.findAll(u'span', u'versetext')
verses = {}
for verse in htmlverses:
Receiver.send_message(u'process_events')
versenumber = int(verse.contents[0].contents[0])
versetext = u''
for part in verse.contents:
if str(part)[0] != u'<':
versetext = versetext + part
versetext = versetext.strip(u'\n\r\t ')
verses[versenumber] = versetext
return SearchResults(bookname, chapter, verses)
class HTTPBible(BibleDB):
log.info(u'%s loaded', __name__)
def __init__(self, parent, **kwargs):
"""
Finds all the bibles defined for the system
Creates an Interface Object for each bible containing connection
information
Throws Exception if no Bibles are found.
Init confirms the bible exists and stores the database path.
"""
BibleDB.__init__(self, parent, **kwargs)
if u'download_source' not in kwargs:
raise KeyError(u'Missing keyword argument "download_source"')
if u'download_name' not in kwargs:
raise KeyError(u'Missing keyword argument "download_name"')
self.download_source = kwargs[u'download_source']
self.download_name = kwargs[u'download_name']
if u'proxy_server' in kwargs:
self.proxy_server = kwargs[u'proxy_server']
else:
self.proxy_server = None
if u'proxy_username' in kwargs:
self.proxy_username = kwargs[u'proxy_username']
else:
self.proxy_username = None
if u'proxy_password' in kwargs:
self.proxy_password = kwargs[u'proxy_password']
else:
self.proxy_password = None
def do_import(self):
self.wizard.ImportProgressBar.setMaximum(2)
self.wizard.incrementProgressBar('Registering bible...')
self.create_meta(u'download source', self.download_source)
self.create_meta(u'download name', self.download_name)
if self.proxy_server:
self.create_meta(u'proxy server', self.proxy_server)
if self.proxy_username:
# store the proxy userid
self.create_meta(u'proxy username', self.proxy_username)
if self.proxy_password:
# store the proxy password
self.create_meta(u'proxy password', self.proxy_password)
self.wizard.incrementProgressBar('Registered.')
return True
def get_verses(self, reference_list):
"""
A reimplementation of the ``BibleDB.get_verses`` method, this one is
specifically for web Bibles. It first checks to see if the particular
chapter exists in the DB, and if not it pulls it from the web. If the
chapter DOES exist, it simply pulls the verses from the DB using the
ancestor method.
``reference_list``
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)
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)]
"""
for reference in reference_list:
log.debug('Reference: %s', reference)
book = reference[0]
db_book = self.get_book(book)
if not db_book:
book_details = self.lookup_book(book)
if not book_details:
Receiver.send_message(u'bible_nobook')
return []
db_book = self.create_book(book_details[u'name'],
book_details[u'abbreviation'], book_details[u'testament_id'])
book = db_book.name
if BibleDB.get_verse_count(self, book, reference[1]) == 0:
Receiver.send_message(u'bible_showprogress')
Receiver.send_message(u'process_events')
search_results = self.get_chapter(self.name, book, reference[1])
if search_results and search_results.has_verselist():
## We have found a book of the bible lets check to see
## if it was there. By reusing the returned book name
## we get a correct book. For example it is possible
## to request ac and get Acts back.
bookname = search_results.get_book()
# check to see if book/chapter exists
db_book = self.get_book(bookname)
self.create_chapter(db_book.id, search_results.get_chapter(),
search_results.get_verselist())
Receiver.send_message(u'bible_hideprogress')
Receiver.send_message(u'process_events')
return BibleDB.get_verses(self, reference_list)
def get_chapter(self, version, book, chapter):
"""
Receive the request and call the relevant handler methods
"""
log.debug(u'get_chapter %s, %s, %s', version, book, chapter)
log.debug(u'source = %s', self.download_source)
try:
if self.download_source.lower() == u'crosswalk':
ev = CWExtract(self.proxy_server)
else:
ev = BGExtract(self.proxy_server)
return ev.get_bible_chapter(self.download_name, book, chapter)
except:
log.exception("Failed to get bible chapter")
return None
def get_books(self):
return [Book.populate(name=book['name']) for book in HTTPBooks.get_books()]
def lookup_book(self, book):
return HTTPBooks.get_book(book)
def get_chapter_count(self, book):
return HTTPBooks.get_chapter_count(book)
def get_verse_count(self, book, chapter):
return HTTPBooks.get_verse_count(book, chapter)
def set_proxy_server(self, server):
self.proxy_server = server

View File

@ -26,37 +26,60 @@
import logging
import os
from bibleOpenSongimpl import BibleOpenSongImpl
from bibleOSISimpl import BibleOSISImpl
from bibleCSVimpl import BibleCSVImpl
from bibleDBimpl import BibleDBImpl
from bibleHTTPimpl import BibleHTTPImpl
from common import parse_reference
from opensong import OpenSongBible
from osis import OSISBible
from csvbible import CSVBible
from db import BibleDB
from http import HTTPBible
class BibleMode(object):
"""
This is basically an enumeration class which specifies the mode of a Bible.
Mode refers to whether or not a Bible in OpenLP is a full Bible or needs to
be downloaded from the Internet on an as-needed basis.
"""
Full = 1
Partial = 2
class BibleFormat(object):
"""
This is a special enumeration class that holds the various types of Bibles,
plus a few helper functions to facilitate generic handling of Bible types
for importing.
"""
Unknown = -1
OSIS = 0
CSV = 1
OpenSong = 2
WebDownload = 3
@classmethod
def get_handler(class_, id):
if id == class_.OSIS:
return BibleOSISImpl
elif id == class_.CSV:
return BibleCSVImpl
elif id == class_.OpenSong:
return BibleOpenSongImpl
elif id == class_.WebDownload:
return BibleHTTPImpl
@staticmethod
def get_class(id):
"""
Return the appropriate imeplementation class.
"""
if id == BibleFormat.OSIS:
return OSISBible
elif id == BibleFormat.CSV:
return CSVBible
elif id == BibleFormat.OpenSong:
return OpenSongBible
elif id == BibleFormat.WebDownload:
return HTTPBible
else:
return None
@staticmethod
def list():
return [
BibleFormat.OSIS,
BibleFormat.CSV,
BibleFormat.OpenSong,
BibleFormat.WebDownload
]
class BibleManager(object):
"""
@ -66,300 +89,139 @@ class BibleManager(object):
log = logging.getLogger(u'BibleManager')
log.info(u'Bible manager loaded')
def __init__(self, config):
def __init__(self, parent, config):
"""
Finds all the bibles defined for the system and creates an
interface object for each bible containing connection
information. Throws Exception if no Bibles are found.
Finds all the bibles defined for the system and creates an interface
object for each bible containing connection information. Throws
Exception if no Bibles are found.
Init confirms the bible exists and stores the database path.
``config``
The plugin's configuration object.
"""
self.config = config
log.debug(u'Bible Initialising')
self.config = config
self.parent = parent
self.web = u'Web'
# dict of bible database objects
self.bible_db_cache = None
# dict of bible http readers
self.bible_http_cache = None
self.biblePath = self.config.get_data_path()
#get proxy name for screen
self.proxyname = self.config.get_config(u'proxy name')
self.bibleSuffix = u'sqlite'
self.dialogobject = None
self.db_cache = None
self.path = self.config.get_data_path()
self.proxy_name = self.config.get_config(u'proxy name')
self.suffix = u'sqlite'
self.import_wizard = None
self.reload_bibles()
self.media = None
def reload_bibles(self):
"""
Reloads the Bibles from the available Bible databases on disk. If a web
Bible is encountered, an instance of HTTPBible is loaded instead of the
BibleDB class.
"""
log.debug(u'Reload bibles')
files = self.config.get_files(self.bibleSuffix)
files = self.config.get_files(self.suffix)
log.debug(u'Bible Files %s', files)
self.bible_db_cache = {}
self.bible_http_cache = {}
# books of the bible with testaments
self.book_testaments = {}
# books of the bible with chapter count
self.book_chapters = []
# books of the bible with abbreviation
self.book_abbreviations = {}
self.web_bibles_present = False
for f in files:
nme = f.split(u'.')
bname = nme[0]
self.bible_db_cache[bname] = BibleDBImpl(self.biblePath,
bname, self.config)
self.db_cache = {}
for filename in files:
name, extension = os.path.splitext(filename)
self.db_cache[name] = BibleDB(self.parent, path=self.path, name=name, config=self.config)
# look to see if lazy load bible exists and get create getter.
biblesource = self.bible_db_cache[bname].get_meta(u'WEB')
if biblesource:
self.web_bibles_present = True
nhttp = BibleHTTPImpl()
# tell The Server where to get the verses from.
nhttp.set_bible_source(biblesource.value)
self.bible_http_cache [bname] = nhttp
# look to see if lazy load bible exists and get create getter.
meta = self.bible_db_cache[bname].get_meta(u'proxy')
proxy = None
if meta:
proxy = meta.value
# tell The Server where to get the verses from.
nhttp.set_proxy(proxy)
# look to see if lazy load bible exists and get create getter.
bibleid = self.bible_db_cache[bname].get_meta(u'bibleid').value
# tell The Server where to get the verses from.
nhttp.set_bibleid(bibleid)
else:
# makes the Full / partial code easier.
self.bible_http_cache [bname] = None
if self.web_bibles_present:
# books of the bible linked to bibleid {osis, name}
self.book_testaments = {}
# books of the bible linked to bibleid {osis, abbrev}
self.book_abbreviations = {}
filepath = os.path.split(os.path.abspath(__file__))[0]
filepath = os.path.abspath(os.path.join(
filepath, u'..', u'resources',u'httpbooks.csv'))
fbibles = None
try:
fbibles = open(filepath, u'r')
for line in fbibles:
p = line.split(u',')
self.book_abbreviations[p[0]] = p[1].replace(u'\n', '')
self.book_testaments[p[0]] = p[2].replace(u'\n', '')
self.book_chapters.append({u'book':p[0], u'total':p[3].replace(u'\n', '')})
except:
log.exception(u'Failed to load bible')
finally:
if fbibles:
fbibles.close()
log.debug(u'Bible Initialised')
source = self.db_cache[name].get_meta(u'download source')
if source:
download_name = self.db_cache[name].get_meta(u'download name').value
meta_proxy = self.db_cache[name].get_meta(u'proxy url')
web_bible = HTTPBible(self.parent, path=self.path, name=name,
config=self.config, download_source=source.value,
download_name=download_name)
if meta_proxy:
web_bible.set_proxy_server(meta_proxy.value)
#del self.db_cache[name]
self.db_cache[name] = web_bible
log.debug(u'Bibles reloaded')
def set_process_dialog(self, dialogobject):
def set_process_dialog(self, wizard):
"""
Sets the reference to the dialog with the progress bar on it.
``dialogobject``
The reference to the dialog.
``dialog``
The reference to the import wizard.
"""
self.dialogobject = dialogobject
self.import_wizard = wizard
def import_bible(self, type, **kwargs):
"""
Register a bible in the bible cache, and then import the verses.
``type``
What type of Bible,
What type of Bible, one of the ``BibleFormat`` values.
``**kwargs``
Keyword arguments to send to the actual importer class.
"""
pass
class_ = BibleFormat.get_class(type)
kwargs['path'] = self.path
kwargs['config'] = self.config
importer = class_(self.parent, **kwargs)
name = importer.register(self.import_wizard)
self.db_cache[name] = importer
return importer.do_import()
def register_http_bible(self, biblename, biblesource, bibleid,
proxyurl=None, proxyid=None, proxypass=None):
def get_bibles(self):
"""
Return a list of bibles from a given URL. The selected Bible
can then be registered and LazyLoaded into a database.
``biblename``
The name of the bible to register.
``biblesource``
Where this Bible stores it's verses.
``bibleid``
The identifier for a Bible.
``proxyurl``
Defaults to *None*. An optional URL to a proxy server.
``proxyid``
Defaults to *None*. A username for logging into the proxy
server.
``proxypass``
Defaults to *None*. The password to accompany the username.
"""
log.debug(u'register_HTTP_bible %s, %s, %s, %s, %s, %s',
biblename, biblesource, bibleid, proxyurl, proxyid, proxypass)
if self._is_new_bible(biblename):
# Create new Bible
nbible = BibleDBImpl(self.biblePath, biblename, self.config)
# Create Database
nbible.create_tables()
self.bible_db_cache[biblename] = nbible
nhttp = BibleHTTPImpl()
nhttp.set_bible_source(biblesource)
self.bible_http_cache[biblename] = nhttp
# register a lazy loading interest
nbible.save_meta(u'WEB', biblesource)
# store the web id of the bible
nbible.save_meta(u'bibleid', bibleid)
if proxyurl:
# store the proxy URL
nbible.save_meta(u'proxy', proxyurl)
nhttp.set_proxy(proxyurl)
if proxyid:
# store the proxy userid
nbible.save_meta(u'proxyid', proxyid)
if proxypass:
# store the proxy password
nbible.save_meta(u'proxypass', proxypass)
return True
else:
log.debug(u'register_http_file_bible %s not created already exists',
biblename)
return False
def register_csv_file_bible(self, biblename, booksfile, versefile):
"""
Method to load a bible from a set of files into a database.
If the database exists it is deleted and the database is reloaded
from scratch.
"""
log.debug(u'register_CSV_file_bible %s,%s,%s',
biblename, booksfile, versefile)
if self._is_new_bible(biblename):
# Create new Bible
nbible = BibleDBImpl(self.biblePath, biblename, self.config)
# Create database
nbible.create_tables()
# Cache the database for use later
self.bible_db_cache[biblename] = nbible
# Create the loader and pass in the database
bcsv = BibleCSVImpl(nbible)
return bcsv.load_data(booksfile, versefile, self.dialogobject)
else:
log.debug(u'register_csv_file_bible %s not created already exists',
biblename)
return False
def register_osis_file_bible(self, biblename, osisfile):
"""
Method to load a bible from a osis xml file extracted from Sword bible
viewer. If the database exists it is deleted and the database is
reloaded from scratch.
"""
log.debug(u'register_OSIS_file_bible %s, %s', biblename, osisfile)
if self._is_new_bible(biblename):
# Create new Bible
nbible = BibleDBImpl(self.biblePath, biblename, self.config)
# Create Database
nbible.create_tables()
# Cache the database for use later
self.bible_db_cache[biblename] = nbible
# Create the loader and pass in the database
bosis = BibleOSISImpl(self.biblePath, nbible)
return bosis.load_data(osisfile, self.dialogobject)
else:
log.debug(
u'register_OSIS_file_bible %s, %s not created already exists',
biblename, osisfile)
return False
def register_opensong_bible(self, biblename, opensongfile):
"""
Method to load a bible from an OpenSong xml file. If the database
exists it is deleted and the database is reloaded from scratch.
"""
log.debug(u'register_opensong_file_bible %s, %s', biblename, opensongfile)
if self._is_new_bible(biblename):
# Create new Bible
nbible = BibleDBImpl(self.biblePath, biblename, self.config)
# Create Database
nbible.create_tables()
# Cache the database for use later
self.bible_db_cache[biblename] = nbible
# Create the loader and pass in the database
bcsv = BibleOpenSongImpl(self.biblePath, nbible)
bcsv.load_data(opensongfile, self.dialogobject)
return True
else:
log.debug(u'register_opensong_file_bible %s, %s not created '
u'already exists', biblename, opensongfile)
return False
def get_bibles(self, mode=BibleMode.Full):
"""
Returns a list of Books of the bible. When ``mode`` is set to
``BibleMode.Full`` this method returns all the Bibles for the
Advanced Search, and when the mode is ``BibleMode.Partial``
this method returns all the bibles for the Quick Search.
Returns a list of the names of available Bibles.
"""
log.debug(u'get_bibles')
bible_list = []
for bible_name, bible_object in self.bible_db_cache.iteritems():
if self.bible_http_cache[bible_name]:
bible_name = u'%s (%s)' % (bible_name, self.web)
bible_list.append(bible_name)
return bible_list
return [name for name, bible in self.db_cache.iteritems()]
def is_bible_web(self, bible):
pos_end = bible.find(u' (%s)' % self.web)
if pos_end != -1:
return True, bible[:pos_end]
return False, bible
def get_bible_books(self):
def get_books(self, bible):
"""
Returns a list of the books of the bible
"""
log.debug(u'get_bible_books')
return self.book_chapters
Returns a list of Bible books, and the number of chapters in that book.
def get_book_chapter_count(self, book):
``bible``
Unicode. The Bible to get the list of books from.
"""
log.debug(u'BibleManager.get_books("%s")', bible)
return [
{
u'name': book.name,
u'chapters': self.db_cache[bible].get_chapter_count(book.name)
}
for book in self.db_cache[bible].get_books()
]
def get_chapter_count(self, bible, book):
"""
Returns the number of Chapters for a given book
"""
log.debug(u'get_book_chapter_count %s', book)
return self.book_chapters[book]
return self.db_cache[bible].get_chapter_count(book)
def get_book_verse_count(self, bible, book, chapter):
def get_verse_count(self, bible, book, chapter):
"""
Returns all the number of verses for a given
book and chapterMaxBibleBookVerses
"""
log.debug(u'get_book_verse_count %s,%s,%s', bible, book, chapter)
web, bible = self.is_bible_web(bible)
if web:
count = self.bible_db_cache[bible].get_max_bible_book_verses(
book, chapter)
if count == 0:
# Make sure the first chapter has been downloaded
self.get_verse_text(bible, book, chapter, chapter, 1, 1)
count = self.bible_db_cache[bible].get_max_bible_book_verses(
book, chapter)
return count
else:
return self.bible_db_cache[bible].get_max_bible_book_verses(
book, chapter)
log.debug(u'BibleManager.get_verse_count("%s", "%s", %s)', bible, book, chapter)
return self.db_cache[bible].get_verse_count(book, chapter)
def get_verse_from_text(self, bible, versetext):
def get_verses(self, bible, versetext):
"""
Returns all the number of verses for a given
book and chapterMaxBibleBookVerses
Parses a scripture reference, fetches the verses from the Bible
specified, and returns a list of ``Verse`` objects.
``bible``
Unicode. The Bible to use.
``versetext``
Unicode. The scripture reference. Valid scripture references are:
- Genesis 1:1
- Genesis 1:1-10
- Genesis 1:1-2:10
"""
log.debug(u'get_verses_from_text %s,%s', bible, versetext)
web, bible = self.is_bible_web(bible)
return self.bible_db_cache[bible].get_verses_from_text(versetext)
log.debug(u'BibleManager.get_verses("%s", "%s")', bible, versetext)
reflist = parse_reference(versetext)
return self.db_cache[bible].get_verses(reflist)
def save_meta_data(self, bible, version, copyright, permissions):
"""
@ -367,124 +229,28 @@ class BibleManager(object):
"""
log.debug(u'save_meta data %s,%s, %s,%s',
bible, version, copyright, permissions)
self.bible_db_cache[bible].save_meta(u'Version', version)
self.bible_db_cache[bible].save_meta(u'Copyright', copyright)
self.bible_db_cache[bible].save_meta(u'Permissions', permissions)
self.db_cache[bible].create_meta(u'Version', version)
self.db_cache[bible].create_meta(u'Copyright', copyright)
self.db_cache[bible].create_meta(u'Permissions', permissions)
def get_meta_data(self, bible, key):
"""
Returns the meta data for a given key
"""
log.debug(u'get_meta %s,%s', bible, key)
web, bible = self.is_bible_web(bible)
return self.bible_db_cache[bible].get_meta(key)
return self.db_cache[bible].get_meta(key)
def get_verse_text(self, bible, bookname, schapter, echapter, sverse,
everse=0):
"""
Returns a list of verses for a given Book, Chapter and ranges of verses.
If the end verse(everse) is less then the start verse(sverse)
then only one verse is returned
``bible``
The name of the bible to be used
Rest can be guessed at !
"""
text = []
self.media.setQuickMessage(u'')
log.debug(u'get_verse_text %s,%s,%s,%s,%s,%s',
bible, bookname, schapter, echapter, sverse, everse)
# check to see if book/chapter exists fow HTTP bibles and load cache
# if necessary
web, bible = self.is_bible_web(bible)
if self.bible_http_cache[bible]:
book = self.bible_db_cache[bible].get_bible_book(bookname)
if book is None:
log.debug(u'get_verse_text : new book')
for chapter in range(schapter, echapter + 1):
self.media.setQuickMessage(
unicode(self.media.trUtf8('Downloading %s: %s')) %
(bookname, chapter))
search_results = \
self.bible_http_cache[bible].get_bible_chapter(
bible, bookname, chapter)
if search_results.has_verselist() :
## We have found a book of the bible lets check to see
## if it was there. By reusing the returned book name
## we get a correct book. For example it is possible
## to request ac and get Acts back.
bookname = search_results.get_book()
# check to see if book/chapter exists
book = self.bible_db_cache[bible].get_bible_book(
bookname)
if book is None:
## Then create book, chapter and text
book = self.bible_db_cache[bible].create_book(
bookname, self.book_abbreviations[bookname],
self.book_testaments[bookname])
log.debug(u'New http book %s, %s, %s',
book, book.id, book.name)
self.bible_db_cache[bible].create_chapter(
book.id, search_results.get_chapter(),
search_results.get_verselist())
else:
## Book exists check chapter and texts only.
v = self.bible_db_cache[bible].get_bible_chapter(
book.id, chapter)
if v is None:
self.media.setQuickMessage(
unicode(self.media.trUtf8('%Downloading %s: %s'))\
% (bookname, chapter))
self.bible_db_cache[bible].create_chapter(
book.id, chapter,
search_results.get_verselist())
else:
log.debug(u'get_verse_text : old book')
for chapter in range(schapter, echapter + 1):
v = self.bible_db_cache[bible].get_bible_chapter(
book.id, chapter)
if v is None:
try:
self.media.setQuickMessage(\
unicode(self.media.trUtf8('Downloading %s: %s'))
% (bookname, chapter))
search_results = \
self.bible_http_cache[bible].get_bible_chapter(
bible, bookname, chapter)
if search_results.has_verselist():
self.bible_db_cache[bible].create_chapter(
book.id, search_results.get_chapter(),
search_results.get_verselist())
except:
log.exception(u'Problem getting scripture online')
#Now get verses from database
if schapter == echapter:
text = self.bible_db_cache[bible].get_bible_text(bookname,
schapter, sverse, everse)
else:
for i in range (schapter, echapter + 1):
if i == schapter:
start = sverse
end = self.get_book_verse_count(bible, bookname, i)
elif i == echapter:
start = 1
end = everse
else:
start = 1
end = self.get_book_verse_count(bible, bookname, i)
txt = self.bible_db_cache[bible].get_bible_text(
bookname, i, start, end)
text.extend(txt)
return text
def _is_new_bible(self, name):
def exists(self, name):
"""
Check cache to see if new bible
"""
for bible, o in self.bible_db_cache.iteritems():
if not isinstance(name, unicode):
name = unicode(name)
for bible, db_object in self.db_cache.iteritems():
log.debug(u'Bible from cache in is_new_bible %s', bible)
if not isinstance(bible, unicode):
bible = unicode(bible)
if bible == name:
return False
return True
return True
return False

View File

@ -31,13 +31,19 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import MediaManagerItem, Receiver, str_to_bool, \
BaseListWithDnD
from openlp.plugins.bibles.forms import ImportWizardForm
from openlp.plugins.bibles.lib.manager import BibleMode
class BibleListView(BaseListWithDnD):
"""
Drag and drop capable list for Bibles.
"""
def __init__(self, parent=None):
self.PluginName = u'Bibles'
BaseListWithDnD.__init__(self, parent)
def resizeEvent(self, event):
self.parent.onListViewResize(event.size().width(), event.size().width())
class BibleMediaItem(MediaManagerItem):
"""
This is the custom media manager item for Bibles.
@ -52,6 +58,7 @@ class BibleMediaItem(MediaManagerItem):
self.IconPath = u'songs/song'
self.ListViewWithDnD_class = BibleListView
self.servicePath = None
self.lastReference = []
MediaManagerItem.__init__(self, parent, icon, title)
# place to store the search results
self.search_results = {}
@ -237,6 +244,24 @@ class BibleMediaItem(MediaManagerItem):
QtCore.SIGNAL(u'pressed()'), self.onQuickSearchButton)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'config_updated'), self.configUpdated)
# Other stuff
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'bible_showprogress'), self.onSearchProgressShow)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'bible_hideprogress'), self.onSearchProgressHide)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'bible_nobook'), self.onNoBookFound)
def addListViewToToolBar(self):
MediaManagerItem.addListViewToToolBar(self)
# Progress Bar
self.SearchProgress = QtGui.QProgressBar(self)
self.SearchProgress.setFormat('%p%')
self.SearchProgress.setMaximum(3)
self.SearchProgress.setGeometry(self.ListView.geometry().left(),
self.ListView.geometry().top(), 81, 23)
self.SearchProgress.setVisible(False)
self.SearchProgress.setObjectName(u'SearchProgress')
def configUpdated(self):
if str_to_bool(
@ -277,7 +302,7 @@ class BibleMediaItem(MediaManagerItem):
def initialise(self):
log.debug(u'bible manager initialise')
self.parent.biblemanager.media = self
self.parent.manager.media = self
self.loadBibles()
self.configUpdated()
log.debug(u'bible manager initialise complete')
@ -297,23 +322,40 @@ class BibleMediaItem(MediaManagerItem):
self.AdvancedSecondBibleComboBox.clear()
self.QuickSecondBibleComboBox.addItem(u'')
self.AdvancedSecondBibleComboBox.addItem(u'')
bibles = self.parent.biblemanager.get_bibles(BibleMode.Full)
bibles = self.parent.manager.get_bibles()
# load bibles into the combo boxes
first = True
for bible in bibles:
self.QuickVersionComboBox.addItem(bible)
self.QuickSecondBibleComboBox.addItem(bible)
# Without HTTP
bibles = self.parent.biblemanager.get_bibles(BibleMode.Partial)
first = True
# load bibles into the combo boxes
for bible in bibles:
self.AdvancedVersionComboBox.addItem(bible)
self.AdvancedSecondBibleComboBox.addItem(bible)
if first:
first = False
# use the first bible as the trigger
self.initialiseBible(bible)
def onListViewResize(self, width, height):
self.SearchProgress.setGeometry(self.ListView.geometry().x(),
(self.ListView.geometry().y() + self.ListView.geometry().height())\
- 23, 81, 23)
def onSearchProgressShow(self):
self.SearchProgress.setVisible(True)
self.SearchProgress.setMinimum(0)
self.SearchProgress.setMaximum(2)
self.SearchProgress.setValue(1)
def onSearchProgressHide(self):
self.SearchProgress.setVisible(False)
def onNoBookFound(self):
QtGui.QMessageBox.critical(self,
self.trUtf8('No Book Found'),
self.trUtf8('No matching book could be found in this Bible.'),
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok),
QtGui.QMessageBox.Ok
)
def onAdvancedVersionComboBox(self):
self.initialiseBible(
unicode(self.AdvancedVersionComboBox.currentText()))
@ -326,11 +368,8 @@ class BibleMediaItem(MediaManagerItem):
self.AdvancedBookComboBox.itemData(item).toInt()[0])
def onNewClick(self):
#self.bibleimportform = BibleImportForm(
# self.parent.config, self.parent.biblemanager, self)
#self.bibleimportform.exec_()
self.bibleimportform = ImportWizardForm(self, self.parent.config,
self.parent.biblemanager, self.parent)
self.parent.manager, self.parent)
self.bibleimportform.exec_()
self.reloadBibles()
@ -339,14 +378,13 @@ class BibleMediaItem(MediaManagerItem):
self.adjustComboBox(frm, self.verses, self.AdvancedToVerse)
def onAdvancedToChapter(self):
text1 = unicode(self.AdvancedFromChapter.currentText())
text2 = unicode(self.AdvancedToChapter.currentText())
if text1 != text2:
frm = unicode(self.AdvancedFromChapter.currentText())
to = unicode(self.AdvancedToChapter.currentText())
if frm != to:
bible = unicode(self.AdvancedVersionComboBox.currentText())
book = unicode(self.AdvancedBookComboBox.currentText())
# get the verse count for new chapter
verses = self.parent.biblemanager.get_book_verse_count(
bible, book, int(text2))
verses = self.parent.manager.get_verse_count(bible, book, int(to))
self.adjustComboBox(1, verses, self.AdvancedToVerse)
def onAdvancedSearchButton(self):
@ -357,10 +395,13 @@ class BibleMediaItem(MediaManagerItem):
chapter_to = int(self.AdvancedToChapter.currentText())
verse_from = int(self.AdvancedFromVerse.currentText())
verse_to = int(self.AdvancedToVerse.currentText())
self.search_results = self.parent.biblemanager.get_verse_text(
bible, book, chapter_from, chapter_to, verse_from, verse_to)
versetext = u'%s %s:%s-%s:%s' % (book, chapter_from, verse_from, \
chapter_to, verse_to)
self.search_results = self.parent.manager.get_verses(bible, versetext)
if self.ClearAdvancedSearchComboBox.currentIndex() == 0:
self.ListView.clear()
self.lastReference = []
self.lastReference.append(versetext)
self.displayResults(bible)
def onAdvancedFromChapter(self):
@ -369,7 +410,7 @@ class BibleMediaItem(MediaManagerItem):
cf = int(self.AdvancedFromChapter.currentText())
self.adjustComboBox(cf, self.chapters_from, self.AdvancedToChapter)
# get the verse count for new chapter
vse = self.parent.biblemanager.get_book_verse_count(bible, book, cf)
vse = self.parent.manager.get_verse_count(bible, book, cf)
self.adjustComboBox(1, vse, self.AdvancedFromVerse)
self.adjustComboBox(1, vse, self.AdvancedToVerse)
@ -379,11 +420,9 @@ class BibleMediaItem(MediaManagerItem):
text = unicode(self.QuickSearchEdit.displayText())
if self.ClearQuickSearchComboBox.currentIndex() == 0:
self.ListView.clear()
if self.QuickSearchComboBox.currentIndex() == 1:
self.search_results = self.parent.biblemanager.get_verse_from_text(
bible, text)
else:
self.searchByReference(bible, text)
self.lastReference = []
self.lastReference.append(text)
self.search_results = self.parent.manager.get_verses(bible, text)
if self.search_results:
self.displayResults(bible)
@ -396,60 +435,63 @@ class BibleMediaItem(MediaManagerItem):
raw_slides = []
raw_footer = []
bible_text = u''
#If we want to use a 2nd translation / version
bible2 = u''
if self.SearchTabWidget.currentIndex() == 0:
bible2 = unicode(self.QuickSecondBibleComboBox.currentText())
else:
bible2 = unicode(self.AdvancedSecondBibleComboBox.currentText())
if bible2:
bible2_verses = []
for scripture in self.lastReference:
bible2_verses.extend(self.parent.manager.get_verses(bible2, scripture))
bible2_version = self.parent.manager.get_meta_data(bible2, u'Version')
bible2_copyright = self.parent.manager.get_meta_data(bible2, u'Copyright')
bible2_permission = self.parent.manager.get_meta_data(bible2, u'Permission')
# Let's loop through the main lot, and assemble our verses
for item in items:
bitem = self.ListView.item(item.row())
text = unicode((bitem.data(QtCore.Qt.UserRole)).toString())
search_verse = text[:text.find(u'(')]
bible = text[text.find(u'(') + 1:-1]
self.searchByReference(bible, search_verse)
book = self.search_results[0].book.name
chapter = unicode(self.search_results[0].chapter)
verse = unicode(self.search_results[0].verse)
text = self.search_results[0].text
reference = bitem.data(QtCore.Qt.UserRole).toPyObject()
bible = unicode(reference[QtCore.QString('bible')])
book = unicode(reference[QtCore.QString('book')])
chapter = unicode(reference[QtCore.QString('chapter')])
verse = unicode(reference[QtCore.QString('verse')])
text = unicode(reference[QtCore.QString('text')])
version = unicode(reference[QtCore.QString('version')])
copyright = unicode(reference[QtCore.QString('copyright')])
permission = unicode(reference[QtCore.QString('permission')])
if self.parent.settings_tab.display_style == 1:
loc = self.formatVerse(old_chapter, chapter, verse, u'(u', u')')
verse_text = self.formatVerse(old_chapter, chapter, verse, u'(u', u')')
elif self.parent.settings_tab.display_style == 2:
loc = self.formatVerse(old_chapter, chapter, verse, u'{', u'}')
verse_text = self.formatVerse(old_chapter, chapter, verse, u'{', u'}')
elif self.parent.settings_tab.display_style == 3:
loc = self.formatVerse(old_chapter, chapter, verse, u'[', u']')
verse_text = self.formatVerse(old_chapter, chapter, verse, u'[', u']')
else:
loc = self.formatVerse(old_chapter, chapter, verse, u'', u'')
verse_text = self.formatVerse(old_chapter, chapter, verse, u'', u'')
old_chapter = chapter
footer = u'%s (%s %s)' % (book, self.version, self.copyright)
footer = u'%s (%s %s)' % (book, version, copyright)
#If not found throws and error so add.s
try:
raw_footer.index(footer)
except:
if footer not in raw_footer:
raw_footer.append(footer)
#If we want to use a 2nd translation / version
bible2 = u''
if self.SearchTabWidget.currentIndex() == 0:
bible2 = unicode(self.QuickSecondBibleComboBox.currentText())
else:
bible2 = unicode(self.AdvancedSecondBibleComboBox.currentText())
if len(bible2) > 0:
self.searchByReference(bible2, search_verse)
footer = u'%s (%s %s)' % (book, self.version, self.copyright)
if bible2:
footer = u'%s (%s %s)' % (book, version, copyright)
#If not found throws and error so add.s
try:
raw_footer.index(footer)
except:
if footer not in raw_footer:
raw_footer.append(footer)
bible_text = u'%s %s \n\n\n %s %s)' % \
(loc, text, loc, self.search_results[0].text)
bible_text = u'%s %s \n\n %s %s' % \
(verse_text, text, verse_text, bible2_verses[item.row()].text)
raw_slides.append(bible_text)
bible_text = u''
else:
#Paragraph style force new line per verse
if self.parent.settings_tab.layout_style == 1:
text = text + u'\n\n'
bible_text = u'%s %s %s' % (bible_text, loc, text)
bible_text = u'%s %s %s' % (bible_text, verse_text, text)
#if we are verse per slide then create slide
if self.parent.settings_tab.layout_style == 0:
raw_slides.append(bible_text)
bible_text = u''
service_item.title = u'%s %s' % (book, loc)
service_item.title = u'%s %s' % (book, verse_text)
if len(self.parent.settings_tab.bible_theme) == 0:
service_item.theme = None
else:
@ -463,40 +505,39 @@ class BibleMediaItem(MediaManagerItem):
return True
def formatVerse(self, old_chapter, chapter, verse, opening, closing):
loc = opening
verse_text = opening
if old_chapter != chapter:
loc += chapter + u':'
verse_text += chapter + u':'
elif not self.parent.settings_tab.show_new_chapters:
loc += chapter + u':'
loc += verse
loc += closing
return loc
verse_text += chapter + u':'
verse_text += verse
verse_text += closing
return verse_text
def reloadBibles(self):
log.debug(u'Reloading Bibles')
self.parent.biblemanager.reload_bibles()
self.parent.manager.reload_bibles()
self.loadBibles()
def initialiseBible(self, bible):
log.debug(u'initialiseBible %s', bible)
book_data = self.parent.biblemanager.get_bible_books()
book_data = self.parent.manager.get_books(bible)
self.AdvancedBookComboBox.clear()
first = True
for book in book_data:
row = self.AdvancedBookComboBox.count()
self.AdvancedBookComboBox.addItem(book[u'book'])
self.AdvancedBookComboBox.addItem(book[u'name'])
self.AdvancedBookComboBox.setItemData(
row, QtCore.QVariant(book[u'total']))
row, QtCore.QVariant(book[u'chapters']))
if first:
first = False
self.initialiseChapterVerse(
bible, book[u'book'], book[u'total'])
bible, book[u'name'], book[u'chapters'])
def initialiseChapterVerse(self, bible, book, chapters):
log.debug(u'initialiseChapterVerse %s, %s', bible, book)
self.chapters_from = chapters
self.verses = self.parent.biblemanager.get_book_verse_count(bible,
book, 1)
self.verses = self.parent.manager.get_verse_count(bible, book, 1)
if self.verses == 0:
self.AdvancedSearchButton.setEnabled(False)
self.AdvancedMessage.setText(self.trUtf8('Bible not fully loaded'))
@ -515,12 +556,30 @@ class BibleMediaItem(MediaManagerItem):
combo.addItem(unicode(i))
def displayResults(self, bible):
version = self.parent.manager.get_meta_data(bible, u'Version')
copyright = self.parent.manager.get_meta_data(bible, u'Copyright')
permission = self.parent.manager.get_meta_data(bible, u'Permission')
if not permission:
permission = u''
else:
permission = permission.value
for count, verse in enumerate(self.search_results):
bible_text = u' %s %d:%d (%s)' % (verse.book.name,
verse.chapter, verse.verse, bible)
bible_text = u' %s %d:%d (%s)' % \
(verse.book.name, verse.chapter, verse.verse, bible)
bible_verse = QtGui.QListWidgetItem(bible_text)
bible_verse.setData(QtCore.Qt.UserRole,
QtCore.QVariant(bible_text))
#bible_verse.setData(QtCore.Qt.UserRole,
# QtCore.QVariant(bible_text))
vdict = {
'bible': QtCore.QVariant(bible),
'version': QtCore.QVariant(version.value),
'copyright': QtCore.QVariant(copyright.value),
'permission': QtCore.QVariant(permission),
'book': QtCore.QVariant(verse.book.name),
'chapter': QtCore.QVariant(verse.chapter),
'verse': QtCore.QVariant(verse.verse),
'text': QtCore.QVariant(verse.text)
}
bible_verse.setData(QtCore.Qt.UserRole, QtCore.QVariant(vdict))
self.ListView.addItem(bible_verse)
row = self.ListView.setCurrentRow(count)
if row:
@ -528,85 +587,4 @@ class BibleMediaItem(MediaManagerItem):
def searchByReference(self, bible, search):
log.debug(u'searchByReference %s, %s', bible, search)
book = u''
start_chapter = u''
end_chapter = u''
start_verse = u''
end_verse = u''
search = search.replace(u' ', u' ').strip()
#original = search
message = None
# Remove book beware 0 index arrays
for i in range (len(search)-1, 0, - 1):
if search[i] == u' ':
book = search[:i]
# remove book from string
search = search[i:]
break
# allow V or v for verse instead of :
search = search.replace(u'v', ':')
search = search.replace(u'V', ':')
search = search.strip()
colon = search.find(u':')
if colon == -1:
# number : found
i = search.rfind(u' ')
if i == -1:
chapter = u''
else:
chapter = search[i:len(search)]
hyphen = chapter.find(u'-')
if hyphen != -1:
start_chapter= chapter[:hyphen]
end_chapter= chapter[hyphen + 1:len(chapter)]
else:
start_chapter = chapter
else:
# more complex
sp = search.split(u'-') #find first
sp1 = sp[0].split(u':')
if len(sp1) == 1:
start_chapter = sp1[0]
start_verse = 1
else:
start_chapter = sp1[0]
start_verse = sp1[1]
if len(sp)== 1:
end_chapter = start_chapter
end_verse = start_verse
else:
sp1 = sp[1].split(u':')
if len(sp1) == 1:
end_chapter = start_chapter
end_verse = sp1[0]
else:
end_chapter = sp1[0]
end_verse = sp1[1]
if end_chapter == u'':
end_chapter = start_chapter.rstrip()
if start_verse == u'':
if end_verse == u'':
start_verse = 1
else:
start_verse = end_verse
if end_verse == u'':
end_verse = 99
if start_chapter == u'':
message = self.trUtf8('No chapter found for search criteria')
log.debug(u'results = %s @ %s : %s @ %s : %s'% \
(unicode(book), unicode(start_chapter), unicode(end_chapter),
unicode(start_verse), unicode(end_verse)))
if message is None:
self.search_results = None
self.search_results = self.parent.biblemanager.get_verse_text(
bible, book, int(start_chapter), int(end_chapter),
int(start_verse), int(end_verse))
self.copyright = unicode(self.parent.biblemanager.get_meta_data(
bible, u'Copyright').value)
self.permissions = unicode(self.parent.biblemanager.get_meta_data(
bible, u'Permissions').value)
self.version = unicode(self.parent.biblemanager.get_meta_data(
bible, u'Version').value)
else:
QtGui.QMessageBox.information(
self, self.trUtf8('Information'), message)
self.search_results = self.parent.manager.get_verses(bible, search)

View File

@ -50,7 +50,7 @@ class BibleMeta(BaseModel):
pass
class ONTestament(BaseModel):
class Testament(BaseModel):
"""
Bible Testaments
"""
@ -101,8 +101,8 @@ verse_table = Table(u'verse', metadata,
Column(u'text', types.UnicodeText, index=True),
)
mapper(BibleMeta, meta_table)
mapper(ONTestament, testament_table,
mapper(Testament, testament_table,
properties={'books': relation(Book, backref='testament')})
mapper(Book, book_table,
properties={'verses': relation(Verse, backref='book')})
mapper(Verse, verse_table)
mapper(Verse, verse_table)

View File

@ -24,101 +24,86 @@
###############################################################################
import logging
import chardet
import codecs
from lxml import objectify
from PyQt4 import QtCore
from openlp.core.lib import Receiver
from db import BibleDB
class BibleOpenSongImpl():
log = logging.getLogger(__name__)
class OpenSongBible(BibleDB):
"""
OSIS Bible format importer class.
OpenSong Bible format importer class.
"""
global log
log = logging.getLogger(__name__)
log.info(u'BibleOpenSongImpl loaded')
def __init__(self, biblepath, bibledb):
def __init__(self, parent, **kwargs):
"""
Constructor to create and set up an instance of the
BibleOpenSongImpl class.
``biblepath``
This does not seem to be used.
``bibledb``
A reference to a Bible database object.
Constructor to create and set up an instance of the OpenSongBible
class. This class is used to import Bibles from OpenSong's XML format.
"""
log.info(u'BibleOpenSongImpl Initialising')
self.bibledb = bibledb
self.loadbible = True
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'openlpstopimport'), self.stop_import)
log.debug(__name__)
BibleDB.__init__(self, parent, **kwargs)
if 'filename' not in kwargs:
raise KeyError(u'You have to supply a file name to import from.')
self.filename = kwargs['filename']
#QtCore.QObject.connect(Receiver.get_receiver(),
# QtCore.SIGNAL(u'openlpstopimport'), self.stop_import)
def stop_import(self):
"""
Stops the import of the Bible.
"""
self.loadbible = False
log.debug('Stopping import!')
self.stop_import = True
def load_data(self, bible_file, dialogobject=None):
def do_import(self):
"""
Loads a Bible from file.
``bible_file``
The file to import from.
``dialogobject``
The Import dialog, so that we can increase the counter on
the progress bar.
"""
log.info(u'Load data for %s' % bible_file)
bible_file = unicode(bible_file)
detect_file = None
try:
detect_file = open(bible_file, u'r')
details = chardet.detect(detect_file.read(2048))
except:
log.exception(u'Failed to detect OpenSong file encoding')
return
finally:
if detect_file:
detect_file.close()
opensong_bible = None
log.debug(u'Starting OpenSong import from "%s"' % self.filename)
self.filename = unicode(self.filename, u'utf-8')
self.wizard.incrementProgressBar(u'Preparing for import...')
file = None
success = True
try:
opensong_bible = codecs.open(bible_file, u'r', details['encoding'])
opensong = objectify.parse(opensong_bible)
# NOTE: We don't need to do any of the normal encoding detection
# here, because lxml does it's own encoding detection, and the two
# mechanisms together interfere with each other.
file = open(self.filename, u'r')
opensong = objectify.parse(file)
bible = opensong.getroot()
for book in bible.b:
if not self.loadbible:
if self.stop_import:
break
dbbook = self.bibledb.create_book(book.attrib[u'n'],
book.attrib[u'n'][:4])
db_book = self.create_book(unicode(book.attrib[u'n']),
unicode(book.attrib[u'n'][:4]))
for chapter in book.c:
if not self.loadbible:
if self.stop_import:
break
for verse in chapter.v:
if not self.loadbible:
if self.stop_import:
break
self.bibledb.add_verse(dbbook.id, chapter.attrib[u'n'],
verse.attrib[u'n'], verse.text)
self.create_verse(
db_book.id,
int(chapter.attrib[u'n']),
int(verse.attrib[u'n']),
unicode(verse.text)
)
Receiver.send_message(u'process_events')
dialogobject.incrementProgressBar(u'Importing %s %s' % \
(dbbook.name, str(chapter.attrib[u'n'])))
self.bibledb.save_verses()
self.wizard.incrementProgressBar(
QtCore.QString('%s %s %s' % (self.trUtf8('Importing'),\
db_book.name, chapter.attrib[u'n'])))
self.commit()
except:
log.exception(u'Loading bible from OpenSong file failed')
success = False
finally:
if opensong_bible:
opensong_bible.close()
if not self.loadbible:
dialogobject.incrementProgressBar(u'Import canceled!')
dialogobject.ImportProgressBar.setValue(
dialogobject.ImportProgressBar.maximum())
if file:
file.close()
if self.stop_import:
self.wizard.incrementProgressBar(u'Import canceled!')
return False
else:
return success

View File

@ -30,11 +30,10 @@ import chardet
import codecs
import re
from PyQt4 import QtCore
from openlp.core.lib import Receiver
from db import BibleDB
class BibleOSISImpl():
class OSISBible(BibleDB):
"""
OSIS Bible format importer class.
"""
@ -42,18 +41,16 @@ class BibleOSISImpl():
log = logging.getLogger(u'BibleOSISImpl')
log.info(u'BibleOSISImpl loaded')
def __init__(self, biblepath, bibledb):
def __init__(self, parent, **kwargs):
"""
Constructor to create and set up an instance of the
BibleOSISImpl class.
``biblepath``
This does not seem to be used.
``bibledb``
A reference to a Bible database object.
Constructor to create and set up an instance of the OpenSongBible
class. This class is used to import Bibles from OpenSong's XML format.
"""
log.info(u'BibleOSISImpl Initialising')
log.debug(__name__)
BibleDB.__init__(self, parent, **kwargs)
if u'filename' not in kwargs:
raise KeyError(u'You have to supply a file name to import from.')
self.filename = kwargs[u'filename']
self.verse_regex = re.compile(
r'<verse osisID="([a-zA-Z0-9 ]*).([0-9]*).([0-9]*)">(.*?)</verse>')
self.note_regex = re.compile(r'<note(.*?)>(.*?)</note>')
@ -66,13 +63,11 @@ class BibleOSISImpl():
self.w_regex = re.compile(r'<w (.*?)>')
self.q_regex = re.compile(r'<q (.*?)>')
self.spaces_regex = re.compile(r'([ ]{2,})')
self.bibledb = bibledb
self.books = {}
filepath = os.path.split(os.path.abspath(__file__))[0]
filepath = os.path.abspath(os.path.join(
filepath, u'..', u'resources', u'osisbooks.csv'))
fbibles = None
self.loadbible = True
try:
fbibles = open(filepath, u'r')
for line in fbibles:
@ -84,31 +79,24 @@ class BibleOSISImpl():
finally:
if fbibles:
fbibles.close()
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'openlpstopimport'), self.stop_import)
#QtCore.QObject.connect(Receiver.get_receiver(),
# QtCore.SIGNAL(u'openlpstopimport'), self.stop_import)
def stop_import(self):
"""
Stops the import of the Bible.
"""
log.debug('Stopping import!')
self.loadbible = False
self.stop_import = True
def load_data(self, osisfile_record, dialogobject=None):
def do_import(self):
"""
Loads a Bible from file.
``osisfile_record``
The file to import from.
``dialogobject``
The Import dialog, so that we can increase the counter on
the progress bar.
"""
log.info(u'Load data for %s' % osisfile_record)
log.debug(u'Starting OSIS import from "%s"' % self.filename)
detect_file = None
try:
detect_file = open(osisfile_record, u'r')
detect_file = open(self.filename, u'r')
details = chardet.detect(detect_file.read(3000))
except:
log.exception(u'Failed to detect OSIS file encoding')
@ -119,12 +107,12 @@ class BibleOSISImpl():
osis = None
success = True
try:
osis = codecs.open(osisfile_record, u'r', details['encoding'])
osis = codecs.open(self.filename, u'r', details['encoding'])
last_chapter = 0
testament = 1
db_book = None
for file_record in osis:
if not self.loadbible:
if self.stop_import:
break
match = self.verse_regex.search(file_record)
if match:
@ -142,13 +130,13 @@ class BibleOSISImpl():
testament)
if last_chapter == 0:
if book == u'Gen':
dialogobject.ImportProgressBar.setMaximum(1188)
self.wizard.ImportProgressBar.setMaximum(1188)
else:
dialogobject.ImportProgressBar.setMaximum(260)
self.wizard.ImportProgressBar.setMaximum(260)
if last_chapter != chapter:
if last_chapter != 0:
self.bibledb.save_verses()
dialogobject.incrementProgressBar(
self.wizard.incrementProgressBar(
u'Importing %s %s...' % \
(self.books[match.group(1)][0], chapter))
last_chapter = chapter
@ -170,20 +158,19 @@ class BibleOSISImpl():
.replace(u'</lg>', u'').replace(u'</q>', u'')\
.replace(u'</div>', u'')
verse_text = self.spaces_regex.sub(u' ', verse_text)
self.bibledb.add_verse(db_book.id, chapter, verse, verse_text)
self.create_verse(db_book.id, chapter, verse, verse_text)
Receiver.send_message(u'process_events')
self.bibledb.save_verses()
dialogobject.incrementProgressBar(u'Finishing import...')
self.commit()
self.wizard.incrementProgressBar(u'Finishing import...')
except:
log.exception(u'Loading bible from OSIS file failed')
success = False
finally:
if osis:
osis.close()
if not self.loadbible:
dialogobject.incrementProgressBar(u'Import canceled!')
dialogobject.ImportProgressBar.setValue(
dialogobject.ImportProgressBar.maximum())
if self.stop_import:
self.wizard.incrementProgressBar(u'Import canceled!')
return False
else:
return success
return success

View File

@ -1,66 +0,0 @@
Genesis,Gen,1,50
Exodus,Exod,1,40
Leviticus,Lev,1,27
Numbers,Num,1,36
Deuteronomy,Deut,1,34
Joshua,Josh,1,24
Judges,Judg,1,21
Ruth,Ruth,1,4
1 Samual,1Sam,1,31
2 Samual,2Sam,1,24
1 Kings,1Kgs,1,22
2 Kings,2Kgs,1,25
1 Chronicles,1Chr,1,29
2 Chronicles,2Chr,1,36
Ezra,Esra,1,10
Nehemiah,Neh,1,13
Esther,Esth,1,10
Job,Job,1,42
Psalms,Ps,1,150
Proverbs,Prov,1,31
Ecclesiastes,Eccl,1,12
Song of Songs,Song,1,8
Isaiah,Isa,1,66
Jeremiah,Jer,1,5
Lamentations,Lam,1,5
Ezekiel,Ezek,1,48
Daniel,Dan,1,12
Hosea,Hos,1,14
Joel,Joel,1,3
Amos,Amos,1,9
Obad,Obad,1,1
Jonah,Jonah,1,4
Micah,Mic,1,7
Naham,Nah,1,3
Habakkuk,Hab,1,3
Zephaniah,Zeph,1,3
Haggai,Hag,1,2
Zechariah,Zech,1,3
Malachi,Mal,1,4
Matthew,Matt,2,28
Mark,Mark,2,16
Luke,Luke,2,24
John,John,2,21
Acts,Acts,2,28
Romans,Rom,2,16
1 Corinthans,1Cor,2,16
2 Corinthans,2Cor,2,13
Galatians,Gal,2,6
Ephesians,Eph,2,6
Philippians,Phil,2,4
Colossians,Col,2,4
1 Thessalonians,1Thess,2,5
2 Thessalonians,2Thess,2,3
1 Timothy,1Tim,2,6
2 Timothy,2Tim,2,4
Titus,Titus,2,3
Philemon,Phlm,2,1
Hebrews,Heb,2,13
James,Jas,2,5
1 Peter,1Pet,2,5
2 Peter,2Pet,2,3
1 John,1John,2,5
2 John,2John,2,1
3 John,3John,2,1
Jude,Jude,2,1
Revelation,Rev,2,22
1 Genesis Gen 1 50
2 Exodus Exod 1 40
3 Leviticus Lev 1 27
4 Numbers Num 1 36
5 Deuteronomy Deut 1 34
6 Joshua Josh 1 24
7 Judges Judg 1 21
8 Ruth Ruth 1 4
9 1 Samual 1Sam 1 31
10 2 Samual 2Sam 1 24
11 1 Kings 1Kgs 1 22
12 2 Kings 2Kgs 1 25
13 1 Chronicles 1Chr 1 29
14 2 Chronicles 2Chr 1 36
15 Ezra Esra 1 10
16 Nehemiah Neh 1 13
17 Esther Esth 1 10
18 Job Job 1 42
19 Psalms Ps 1 150
20 Proverbs Prov 1 31
21 Ecclesiastes Eccl 1 12
22 Song of Songs Song 1 8
23 Isaiah Isa 1 66
24 Jeremiah Jer 1 5
25 Lamentations Lam 1 5
26 Ezekiel Ezek 1 48
27 Daniel Dan 1 12
28 Hosea Hos 1 14
29 Joel Joel 1 3
30 Amos Amos 1 9
31 Obad Obad 1 1
32 Jonah Jonah 1 4
33 Micah Mic 1 7
34 Naham Nah 1 3
35 Habakkuk Hab 1 3
36 Zephaniah Zeph 1 3
37 Haggai Hag 1 2
38 Zechariah Zech 1 3
39 Malachi Mal 1 4
40 Matthew Matt 2 28
41 Mark Mark 2 16
42 Luke Luke 2 24
43 John John 2 21
44 Acts Acts 2 28
45 Romans Rom 2 16
46 1 Corinthans 1Cor 2 16
47 2 Corinthans 2Cor 2 13
48 Galatians Gal 2 6
49 Ephesians Eph 2 6
50 Philippians Phil 2 4
51 Colossians Col 2 4
52 1 Thessalonians 1Thess 2 5
53 2 Thessalonians 2Thess 2 3
54 1 Timothy 1Tim 2 6
55 2 Timothy 2Tim 2 4
56 Titus Titus 2 3
57 Philemon Phlm 2 1
58 Hebrews Heb 2 13
59 James Jas 2 5
60 1 Peter 1Pet 2 5
61 2 Peter 2Pet 2 3
62 1 John 1John 2 5
63 2 John 2John 2 1
64 3 John 3John 2 1
65 Jude Jude 2 1
66 Revelation Rev 2 22

Binary file not shown.

View File

@ -153,10 +153,10 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog):
sxml.add_verse_to_lyrics(u'custom', unicode(count),
unicode(self.VerseListView.item(i).text()))
count += 1
self.customSlide.title = unicode(self.TitleEdit.displayText())
self.customSlide.text = unicode(sxml.extract_xml())
self.customSlide.credits = unicode(self.CreditEdit.displayText())
self.customSlide.theme_name = unicode(self.ThemeComboBox.currentText())
self.customSlide.title = unicode(self.TitleEdit.displayText(), u'utf-8')
self.customSlide.text = unicode(sxml.extract_xml(), u'utf-8')
self.customSlide.credits = unicode(self.CreditEdit.displayText(), u'utf-8')
self.customSlide.theme_name = unicode(self.ThemeComboBox.currentText(), u'utf-8')
self.custommanager.save_slide(self.customSlide)
return True
@ -257,4 +257,4 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog):
if len(self.VerseTextEdit.toPlainText()) > 0:
self.VerseTextEdit.setFocus()
return False, self.trUtf8('You have unsaved data')
return True, u''
return True, u''

View File

@ -172,7 +172,6 @@ class ImageMediaItem(MediaManagerItem):
filename = unicode((bitem.data(QtCore.Qt.UserRole)).toString())
self.OverrideLabel.setText(bitem.text())
frame = QtGui.QImage(unicode(filename))
self.parent.render_manager.override_background = frame
self.parent.render_manager.override_background_changed = True
self.parent.live_controller.parent.mainDisplay.addImageWithText(frame)
else:
MediaManagerItem.onPreviewClick(self)
MediaManagerItem.onPreviewClick(self)

View File

@ -62,10 +62,12 @@ class ImpressController(PresentationController):
"""
log.debug(u'Initialising')
PresentationController.__init__(self, plugin, u'Impress')
self.supports= [u'.odp', u'.ppt', u'.pps', u'.pptx', u'.ppsx']
self.process = None
self.document = None
self.presentation = None
self.controller = None
self.desktop = None
def check_available(self):
"""
@ -85,7 +87,7 @@ class ImpressController(PresentationController):
It is not displayed to the user but is available to the UNO interface
when required.
"""
log.debug(u'start Openoffice')
log.debug(u'start process Openoffice')
if os.name == u'nt':
self.manager = self.get_com_servicemanager()
self.manager._FlagAsMethod(u'Bridge_GetStruct')
@ -101,7 +103,7 @@ class ImpressController(PresentationController):
"""
Called at system exit to clean up any running presentations
"""
log.debug(u'Kill')
log.debug(u'Kill OpenOffice')
self.close_presentation()
if os.name != u'nt':
desktop = self.get_uno_desktop()
@ -121,8 +123,9 @@ class ImpressController(PresentationController):
``presentation``
The file name of the presentatios to the run.
"""
log.debug(u'LoadPresentation')
log.debug(u'Load Presentation OpenOffice')
self.store_filename(presentation)
#print "s.dsk1 ", self.desktop
if os.name == u'nt':
desktop = self.get_com_desktop()
if desktop is None:
@ -135,6 +138,7 @@ class ImpressController(PresentationController):
if desktop is None:
return
self.desktop = desktop
#print "s.dsk2 ", self.desktop
properties = []
properties.append(self.create_property(u'Minimized', True))
properties = tuple(properties)
@ -153,9 +157,9 @@ class ImpressController(PresentationController):
"""
Create thumbnail images for presentation
"""
log.debug(u'create thumbnails OpenOffice')
if self.check_thumbnails():
return
if os.name == u'nt':
thumbdir = u'file:///' + self.thumbnailpath.replace(
u'\\', u'/').replace(u':', u'|').replace(u' ', u'%20')
@ -170,13 +174,14 @@ class ImpressController(PresentationController):
page = pages.getByIndex(idx)
doc.getCurrentController().setCurrentPage(page)
path = u'%s/%s%s.png'% (thumbdir, self.thumbnailprefix,
unicode(idx+1))
unicode(idx + 1))
try:
doc.storeToURL(path , props)
except:
log.exception(u'%s\nUnable to store preview' % path)
def create_property(self, name, value):
log.debug(u'create property OpenOffice')
if os.name == u'nt':
prop = self.manager.Bridge_GetStruct(u'com.sun.star.beans.PropertyValue')
else:
@ -186,7 +191,7 @@ class ImpressController(PresentationController):
return prop
def get_uno_desktop(self):
log.debug(u'getUNODesktop')
log.debug(u'get UNO Desktop Openoffice')
ctx = None
loop = 0
context = uno.getComponentContext()
@ -196,6 +201,7 @@ class ImpressController(PresentationController):
try:
ctx = resolver.resolve(u'uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext')
except:
log.exception(u'Unable to fine running instance ')
self.start_process()
loop += 1
try:
@ -208,7 +214,7 @@ class ImpressController(PresentationController):
return None
def get_com_desktop(self):
log.debug(u'getCOMDesktop')
log.debug(u'get COM Desktop OpenOffice')
try:
desktop = self.manager.createInstance(u'com.sun.star.frame.Desktop')
return desktop
@ -217,7 +223,7 @@ class ImpressController(PresentationController):
return None
def get_com_servicemanager(self):
log.debug(u'get_com_servicemanager')
log.debug(u'get_com_servicemanager openoffice')
try:
return Dispatch(u'com.sun.star.ServiceManager')
except:
@ -230,6 +236,7 @@ class ImpressController(PresentationController):
Triggerent by new object being added to SlideController orOpenLP
being shut down
"""
log.debug(u'close Presentation OpenOffice')
if self.document:
if self.presentation:
try:
@ -242,32 +249,44 @@ class ImpressController(PresentationController):
self.document = None
def is_loaded(self):
log.debug(u'is loaded OpenOffice')
#print "is_loaded "
if self.presentation is None or self.document is None:
#print "no present or document"
return False
try:
if self.document.getPresentation() is None:
#print "no getPresentation"
return False
except:
return False
return True
def is_active(self):
log.debug(u'is active OpenOffice')
#print "is_active "
if not self.is_loaded():
#print "False "
return False
#print "self.con ", self.controller
if self.controller is None:
return False
return self.controller.isRunning() and self.controller.isActive()
return True
def unblank_screen(self):
log.debug(u'unblank screen OpenOffice')
return self.controller.resume()
def blank_screen(self):
log.debug(u'blank screen OpenOffice')
self.controller.blankScreen(0)
def stop_presentation(self):
log.debug(u'stop presentation OpenOffice')
self.controller.deactivate()
def start_presentation(self):
log.debug(u'start presentation OpenOffice')
if self.controller is None or not self.controller.isRunning():
self.presentation.start()
# start() returns before the getCurrentComponent is ready. Try for 5 seconds

View File

@ -63,7 +63,13 @@ class PresentationMediaItem(MediaManagerItem):
def retranslateUi(self):
self.OnNewPrompt = self.trUtf8('Select Presentation(s)')
self.OnNewFileMasks = self.trUtf8('Presentations (*.ppt *.pps *.odp)')
fileType = u''
for controller in self.controllers:
if self.controllers[controller].enabled:
for type in self.controllers[controller].supports:
if fileType.find(type) == -1:
fileType += type + u' '
self.OnNewFileMasks = self.trUtf8('Presentations (%s)' % fileType)
def requiredIcons(self):
MediaManagerItem.requiredIcons(self)
@ -151,4 +157,4 @@ class PresentationMediaItem(MediaManagerItem):
service_item.add_from_command(path, name, img)
i = i + 1
img = controller.get_slide_preview_file(i)
return True
return True

View File

@ -52,6 +52,7 @@ class PowerpointController(PresentationController):
"""
log.debug(u'Initialising')
PresentationController.__init__(self, plugin, u'Powerpoint')
self.supports= [u'.ppt', u'.pps']
self.process = None
self.presentation = None
@ -255,4 +256,4 @@ class PowerpointController(PresentationController):
if os.path.isfile(path):
return path
else:
return None
return None

View File

@ -49,6 +49,7 @@ class PptviewController(PresentationController):
log.debug(u'Initialising')
self.process = None
PresentationController.__init__(self, plugin, u'Powerpoint Viewer')
self.supports= [u'.ppt', u'.pps']
self.pptid = None
def check_available(self):

View File

@ -118,7 +118,7 @@ class PresentationController(object):
"""
global log
log = logging.getLogger(u'PresentationController')
log.info(u'loaded')
log.info(u'PresentationController loaded')
def __init__(self, plugin=None, name=u'PresentationController'):
"""
@ -136,6 +136,7 @@ class PresentationController(object):
``name``
Name of the application, to appear in the application
"""
self.supports = []
self.plugin = plugin
self.name = name
self.available = self.check_available()
@ -313,4 +314,4 @@ class PresentationController(object):
else:
prefix = u'preview'
Receiver.send_message(u'%s_slidecontroller_change' % prefix,
self.slidenumber - 1)
self.slidenumber - 1)

View File

@ -26,7 +26,7 @@
import os
import logging
from openlp.core.lib import Plugin, build_icon
from openlp.core.lib import Plugin, build_icon, Receiver
from openlp.plugins.presentations.lib import *
class PresentationPlugin(Plugin):
@ -51,6 +51,12 @@ class PresentationPlugin(Plugin):
log.info(u'Presentations Initialising')
Plugin.initialise(self)
self.insert_toolbox_item()
presentation_types = []
for controller in self.controllers:
if self.controllers[controller].enabled:
presentation_types.append({u'%s' % controller : self.controllers[controller].supports})
Receiver.send_message(
u'presentation types', presentation_types)
def finalise(self):
log.info(u'Plugin Finalise')
@ -106,4 +112,4 @@ class PresentationPlugin(Plugin):
'the ability to show presentations using a number of different '
'programs. The choice of available presentation programs is '
'available to the user in a drop down box.')
return about_text
return about_text

View File

@ -185,8 +185,13 @@ class SongMediaItem(MediaManagerItem):
if author_list != u'':
author_list = author_list + u', '
author_list = author_list + author.display_name
song_detail = unicode(self.trUtf8('%s (%s)' % \
(unicode(song.title), unicode(author_list))))
if not isinstance(author_list, unicode):
author_list = unicode(author_list, u'utf8')
if isinstance(song.title, unicode):
song_title = song.title
else:
song_title = unicode(song.title, u'utf8')
song_detail = u'%s (%s)' % (song_title, author_list)
song_name = QtGui.QListWidgetItem(song_detail)
song_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(song.id))
self.ListView.addItem(song_name)
@ -339,4 +344,4 @@ class SongMediaItem(MediaManagerItem):
service_item.audit = [
song.title, author_audit, song.copyright, song.ccli_number
]
return True
return True

View File

@ -33,11 +33,11 @@ class SongUsageDeleteForm(QtGui.QDialog, Ui_SongUsageDeleteDialog):
"""
Class documentation goes here.
"""
def __init__(self, auditmanager, parent=None):
def __init__(self, songusagemanager, parent=None):
"""
Constructor
"""
self.auditmanager = auditmanager
self.songusagemanager = songusagemanager
QtGui.QDialog.__init__(self, parent)
self.setupUi(self)
@ -52,5 +52,5 @@ class SongUsageDeleteForm(QtGui.QDialog, Ui_SongUsageDeleteDialog):
if ret == QtGui.QMessageBox.Ok:
qDeleteDate = self.DeleteCalendar.selectedDate()
deleteDate = date(qDeleteDate.year(), qDeleteDate.month(), qDeleteDate.day())
self.auditmanager.delete_to_date(deleteDate)
self.close()
self.songusagemanager.delete_to_date(deleteDate)
self.close()

View File

@ -25,10 +25,14 @@
import os
from PyQt4 import QtCore, QtGui
import logging
from songusagedetaildialog import Ui_SongUsageDetailDialog
class SongUsageDetailForm(QtGui.QDialog, Ui_SongUsageDetailDialog):
global log
log = logging.getLogger(u'SongUsageDetailForm')
log.info(u'SongUsage Detail Form loaded')
"""
Class documentation goes here.
"""
@ -106,19 +110,19 @@ class SongUsageDetailForm(QtGui.QDialog, Ui_SongUsageDetailDialog):
self.close()
def detailedReport(self):
print "detailed"
filename = u'audit_det_%s_%s.txt' % \
log.debug(u'Detailed report generated')
filename = u'usage_detail_%s_%s.txt' % \
(self.FromDateEdit.date().toString(u'ddMMyyyy'),
self.ToDateEdit.date().toString(u'ddMMyyyy'))
audits = self.parent.auditmanager.get_all_audits()
usage = self.parent.songusagemanager.get_all_songusage()
outname = os.path.join(unicode(self.FileLineEdit.text()), filename)
file = None
try:
file = open(outname, u'w')
for audit in audits:
for instance in usage:
record = u'\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"\n' % \
(audit.auditdate,audit.audittime, audit.title,
audit.copyright, audit.ccl_number , audit.authors)
(instance.usagedate,instance.usagetime, instance.title,
instance.copyright, instance.ccl_number , instance.authors)
file.write(record)
except:
log.exception(u'Failed to write out audit records')
@ -127,8 +131,7 @@ class SongUsageDetailForm(QtGui.QDialog, Ui_SongUsageDetailDialog):
file.close()
def summaryReport(self):
print "summary"
log.debug(u'Summary report generated')
filename = u'audit_sum_%s_%s.txt' % \
(self.FromDateEdit.date().toString(u'ddMMyyyy'),
self.ToDateEdit.date().toString(u'ddMMyyyy'))
print filename

View File

@ -141,7 +141,7 @@ class SongUsagePlugin(Plugin):
SongUsageitem.authors = u''
for author in SongUsageData[1]:
SongUsageitem.authors += author + u' '
self.songusagemanager.insert_SongUsage(SongUsageitem)
self.songusagemanager.insert_songusage(SongUsageitem)
def onSongUsageDelete(self):
self.SongUsagedeleteform.exec_()
@ -154,4 +154,4 @@ class SongUsagePlugin(Plugin):
about_text = self.trUtf8('<b>SongUsage Plugin</b><br>This plugin '
'records the use of songs and when they have been used during '
'a live service')
return about_text
return about_text

306
scripts/bible-1to2-converter.py Executable file
View File

@ -0,0 +1,306 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
# Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# 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 #
###############################################################################
import sys
import os
import sqlite
import sqlite3
from optparse import OptionParser
from traceback import format_tb as get_traceback
# Some global options to be used throughout the import process
verbose = False
debug = False
old_cursor = None
new_cursor = None
# SQL create statments
create_statements = [
(u'table "book"', u"""CREATE TABLE book (
id INTEGER NOT NULL,
testament_id INTEGER,
name VARCHAR(30),
abbreviation VARCHAR(5),
PRIMARY KEY (id),
FOREIGN KEY(testament_id) REFERENCES testament (id)
)"""),
(u'table "metadata"', u"""CREATE TABLE metadata (
"key" VARCHAR(255) NOT NULL,
value VARCHAR(255),
PRIMARY KEY ("key")
)"""),
(u'table "testament"', u"""CREATE TABLE testament (
id INTEGER NOT NULL,
name VARCHAR(30),
PRIMARY KEY (id)
)"""),
(u'table "verse"', u"""CREATE TABLE verse (
id INTEGER NOT NULL,
book_id INTEGER,
chapter INTEGER,
verse INTEGER,
text TEXT,
PRIMARY KEY (id),
FOREIGN KEY(book_id) REFERENCES book (id)
)"""),
(u'index "idx_abbrev"',
u"""CREATE INDEX idx_abbrev ON book (abbreviation, id)"""),
(u'index "idx_chapter_verse_book',
u"""CREATE INDEX idx_chapter_verse_book ON verse (chapter, verse, book_id, id)"""),
(u'index "idx_chapter_verse_text"',
u"""CREATE INDEX idx_chapter_verse_text ON verse (text, verse, book_id, id)"""),
(u'index "idx_name"',
u"""CREATE INDEX idx_name ON book (name, id)""")
]
def display_sql(sql, params):
prepared_params = []
for param in params:
if isinstance(param, basestring):
prepared_params.append(u'"%s"' % param)
elif isinstance(param, (int, long)):
prepared_params.append(u'%d' % param)
elif isinstance(param, (float, complex)):
prepared_params.append(u'%f' % param)
else:
prepared_params.append(u'"%s"' % str(param))
for prepared_param in prepared_params:
sql = sql.replace(u'?', prepared_param, 1)
return sql
def create_database():
global new_cursor, create_statements
if debug or verbose:
print 'Creating new database:'
else:
print 'Creating new database...',
for statement_type, sql_create in create_statements:
if debug:
print '... ', sql_create.replace('\n', ' ').replace(' ', ' ')
elif verbose:
print '... creating %s...' % statement_type,
new_cursor.execute(sql_create)
if verbose and not debug:
print 'done.'
if not verbose and not debug:
print 'done.'
def import_bible():
global old_cursor, new_cursor, debug, verbose
if debug or verbose:
print 'Importing metadata:'
else:
print 'Importing metadata...',
if debug:
print '... SELECT "key", "value" FROM metadata'
elif verbose:
print '... fetching metadata from old database...',
old_cursor.execute(u'SELECT "key", "value" FROM metadata')
rows = old_cursor.fetchall()
if not debug and verbose:
print 'done.'
for row in rows:
key = unicode(row[0], u'cp1252')
value = unicode(row[1], u'cp1252')
sql_insert = u'INSERT INTO metadata '\
'("key", "value") '\
'VALUES (?, ?)'
sql_params = (key, value)
if debug:
print '...', display_sql(sql_insert, sql_params)
elif verbose:
print '... importing "%s"' % key
new_cursor.execute(sql_insert, sql_params)
if not verbose and not debug:
print 'done.'
if debug or verbose:
print 'Importing testaments:'
else:
print 'Importing testaments...',
if debug:
print '... SELECT id, name FROM testament'
elif verbose:
print '... fetching testaments from old database...',
old_cursor.execute(u'SELECT id, name FROM testament')
rows = old_cursor.fetchall()
if not debug and verbose:
print 'done.'
for row in rows:
id = int(row[0])
name = unicode(row[1], u'cp1252')
sql_insert = u'INSERT INTO testament '\
'(id, name) '\
'VALUES (?, ?)'
sql_params = (id, name)
if debug:
print '...', display_sql(sql_insert, sql_params)
elif verbose:
print '... importing "%s"' % name
new_cursor.execute(sql_insert, sql_params)
if not verbose and not debug:
print 'done.'
if debug or verbose:
print 'Importing books:'
else:
print 'Importing books...',
if debug:
print '... SELECT id, testament_id, name, abbreviation FROM book'
elif verbose:
print '... fetching books from old database...',
old_cursor.execute(u'SELECT id, testament_id, name, abbreviation FROM book')
rows = old_cursor.fetchall()
if not debug and verbose:
print 'done.'
book_map = {}
for row in rows:
testament_id = int(row[1])
name = unicode(row[2], u'cp1252')
abbreviation = unicode(row[3], u'cp1252')
sql_insert = u'INSERT INTO book '\
'(id, testament_id, name, abbreviation) '\
'VALUES (NULL, ?, ?, ?)'
sql_params = (testament_id, name, abbreviation)
if debug:
print '...', display_sql(sql_insert, sql_params)
elif verbose:
print '... importing "%s"' % name
new_cursor.execute(sql_insert, sql_params)
book_map[row[0]] = new_cursor.lastrowid
if debug:
print ' >>> (old) books.id =', row[0], ' (new) books.id =', book_map[row[0]]
if not verbose and not debug:
print 'done.'
if debug or verbose:
print 'Importing verses:'
else:
print 'Importing verses...',
if debug:
print '... SELECT id, book_id, chapter, verse, text || \'\' AS text FROM verse...',
elif verbose:
print '... fetching verses from old database...',
old_cursor.execute(u'SELECT id, book_id, chapter, verse, text || \'\' AS text FROM verse')
rows = old_cursor.fetchall()
if debug or verbose:
print 'done.'
song_map = {}
for row in rows:
book_id = int(row[1])
chapter = int(row[2])
verse = int(row[3])
text = unicode(row[4], u'cp1252')
sql_insert = u'INSERT INTO verse '\
'(id, book_id, chapter, verse, text) '\
'VALUES (NULL, ?, ?, ?, ?)'
sql_params = (book_map[book_id], chapter, verse, text)
if debug:
print '...', display_sql(sql_insert, sql_params)
elif verbose:
print '... importing "%s..."' % text[:17]
new_cursor.execute(sql_insert, sql_params)
if not verbose and not debug:
print 'done.'
def main(old_db, new_db):
global old_cursor, new_cursor, debug
old_connection = None
new_connection = None
try:
old_connection = sqlite.connect(old_db)
except:
if debug:
errormsg = '\n' + ''.join(get_traceback(sys.exc_info()[2]))\
+ str(sys.exc_info()[1])
else:
errormsg = sys.exc_info()[1]
print 'There was a problem connecting to the old database:', errormsg
return 1
try:
new_connection = sqlite3.connect(new_db)
except:
if debug:
errormsg = '\n' + ''.join(get_traceback(sys.exc_info()[2]))\
+ str(sys.exc_info()[1])
else:
errormsg = sys.exc_info()[1]
print 'There was a problem creating the new database:', errormsg
return 1
old_cursor = old_connection.cursor()
new_cursor = new_connection.cursor()
try:
create_database()
except:
if debug:
errormsg = '\n' + ''.join(get_traceback(sys.exc_info()[2]))\
+ str(sys.exc_info()[1])
else:
errormsg = sys.exc_info()[1]
print 'There was a problem creating the database:', errormsg
return 1
try:
import_bible()
new_connection.commit()
except:
new_connection.rollback()
if debug:
errormsg = '\n' + ''.join(get_traceback(sys.exc_info()[2]))\
+ str(sys.exc_info()[1])
else:
errormsg = sys.exc_info()[1]
print 'There was a problem importing songs:', errormsg
return 1
print 'Import complete.'
if __name__ == u'__main__':
option_parser = OptionParser(usage='Usage: %prog [options] OLDDATABASE NEWDATABASE')
option_parser.add_option('-o', '--overwrite', dest='overwrite', default=False,
action=u'store_true', help='Overwrite database file if it already exists.')
option_parser.add_option('-v', '--verbose', dest='verbose', default=False,
action=u'store_true', help='Outputs additional progress data.')
option_parser.add_option('-d', '--debug', dest='debug', default=False,
action=u'store_true', help='Outputs raw SQL statements (overrides verbose).')
options, arguments = option_parser.parse_args()
if len(arguments) < 2:
if len(arguments) == 0:
option_parser.error('Please specify an old database and a new database.')
else:
option_parser.error('Please specify a new database.')
old_db = os.path.abspath(arguments[0])
new_db = os.path.abspath(arguments[1])
if not os.path.isfile(old_db):
option_parser.error('Old database file ("%s") is not a file.' % old_db)
if not os.path.exists(old_db):
option_parser.error('Old database file ("%s") does not exist.' % old_db)
if os.path.exists(new_db):
if not options.overwrite:
option_parser.error('New database file ("%s") exists. If you want to overwrite it, specify the --overwrite option.' % new_db)
else:
if not os.path.isfile(new_db):
option_parser.error('New database file ("%s") is not a file.' % new_db)
os.unlink(new_db)
verbose = options.verbose
debug = options.debug
main(old_db, new_db)

View File

@ -1 +1 @@
1.9.0-696
1.9.0-700