forked from openlp/openlp
Some major work on the Bibles plugin:
- Reworked import system to make it pluggable. - Created a Bible Import Wizard. - Converted Crosswalk to use BeautifulSoup. - Merged HTTP and DB Bible list. - Made all Bibles descend from BibleDB. - Lots of other changes and fixes. bzr-revno: 700
This commit is contained in:
commit
bebe01e80e
@ -148,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",
|
||||
|
@ -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)
|
||||
|
||||
|
@ -165,3 +165,4 @@ class Receiver():
|
||||
Get the global ``eventreceiver`` instance.
|
||||
"""
|
||||
return Receiver.eventreceiver
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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%')
|
||||
|
@ -27,6 +27,7 @@ import logging
|
||||
import os
|
||||
import os.path
|
||||
from time import sleep
|
||||
import csv
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
@ -59,7 +60,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
|
||||
'''
|
||||
@ -68,10 +69,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,
|
||||
@ -96,9 +97,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:
|
||||
@ -107,14 +108,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'),
|
||||
@ -169,6 +162,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
|
||||
@ -209,8 +211,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(
|
||||
@ -238,23 +238,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):
|
||||
"""
|
||||
@ -267,29 +266,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,
|
||||
@ -317,22 +320,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
|
||||
@ -344,21 +347,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(
|
||||
@ -368,4 +372,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')
|
@ -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)
|
@ -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")
|
@ -26,8 +26,98 @@
|
||||
import urllib2
|
||||
import chardet
|
||||
import logging
|
||||
import re
|
||||
import sqlite3
|
||||
|
||||
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 +171,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 +249,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()
|
||||
|
@ -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
|
||||
|
286
openlp/plugins/bibles/lib/db.py
Normal file
286
openlp/plugins/bibles/lib/db.py
Normal 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)
|
||||
|
361
openlp/plugins/bibles/lib/http.py
Normal file
361
openlp/plugins/bibles/lib/http.py
Normal 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
|
||||
|
@ -25,38 +25,62 @@
|
||||
|
||||
import logging
|
||||
import os
|
||||
import csv
|
||||
|
||||
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 +90,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 +230,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
|
||||
|
||||
|
@ -32,12 +32,20 @@ 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
|
||||
from openlp.plugins.bibles.lib.common import parse_reference
|
||||
|
||||
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 +60,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 +246,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 +304,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 +324,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 +370,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 +380,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 +397,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 +412,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 +422,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 +437,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 +507,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 +558,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 +589,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)
|
||||
|
@ -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)
|
||||
|
@ -33,94 +33,81 @@ 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
|
@ -33,8 +33,9 @@ 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 +43,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 +65,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 +81,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 +109,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 +132,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 +160,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
|
||||
|
@ -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
|
|
BIN
openlp/plugins/bibles/resources/httpbooks.sqlite
Normal file
BIN
openlp/plugins/bibles/resources/httpbooks.sqlite
Normal file
Binary file not shown.
@ -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''
|
||||
|
@ -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
|
||||
|
@ -1 +1 @@
|
||||
1.9.0-698
|
||||
1.9.0-700
|
||||
|
Loading…
Reference in New Issue
Block a user