← Back to team overview

openlp-core team mailing list archive

[Merge] lp:~orangeshirt/openlp/bibles into lp:openlp

 

Armin Köhler has proposed merging lp:~orangeshirt/openlp/bibles into lp:openlp.

Requested reviews:
  OpenLP Core (openlp-core)

For more details, see:
https://code.launchpad.net/~orangeshirt/openlp/bibles/+merge/53968

changed bible database layout and the import of webbibles, it now import all books while register.

-- 
https://code.launchpad.net/~orangeshirt/openlp/bibles/+merge/53968
Your team OpenLP Core is requested to review the proposed merge of lp:~orangeshirt/openlp/bibles into lp:openlp.
=== modified file 'openlp/plugins/bibles/forms/__init__.py'
--- openlp/plugins/bibles/forms/__init__.py	2011-02-24 05:47:38 +0000
+++ openlp/plugins/bibles/forms/__init__.py	2011-03-18 10:11:29 +0000
@@ -52,5 +52,6 @@
 """
 
 from bibleimportform import BibleImportForm
+from bibleimportrequestform import BibleImportRequest
 
 __all__ = ['BibleImportForm']

=== modified file 'openlp/plugins/bibles/forms/bibleimportform.py'
--- openlp/plugins/bibles/forms/bibleimportform.py	2011-03-05 17:14:13 +0000
+++ openlp/plugins/bibles/forms/bibleimportform.py	2011-03-18 10:11:29 +0000
@@ -39,6 +39,7 @@
 from openlp.core.ui.wizard import OpenLPWizard, WizardStrings
 from openlp.core.utils import AppLocation, string_is_unicode
 from openlp.plugins.bibles.lib.manager import BibleFormat
+from openlp.plugins.bibles.lib.db import BiblesResourcesDB
 
 log = logging.getLogger(__name__)
 
@@ -634,46 +635,27 @@
         """
         Load the lists of Crosswalk, BibleGateway and Bibleserver bibles.
         """
-        filepath = AppLocation.get_directory(AppLocation.PluginsDir)
-        filepath = os.path.join(filepath, u'bibles', u'resources')
         # Load Crosswalk Bibles.
-        self.loadBibleResourceFile(
-            os.path.join(filepath, u'crosswalkbooks.csv'),
-            WebDownload.Crosswalk)
+        self.loadBibleResource(WebDownload.Crosswalk)
         # Load BibleGateway Bibles.
-        self.loadBibleResourceFile(os.path.join(filepath, u'biblegateway.csv'),
-            WebDownload.BibleGateway)
+        self.loadBibleResource(WebDownload.BibleGateway)
         # Load and Bibleserver Bibles.
-        self.loadBibleResourceFile(os.path.join(filepath, u'bibleserver.csv'),
-            WebDownload.Bibleserver)
+        self.loadBibleResource(WebDownload.Bibleserver)
 
-    def loadBibleResourceFile(self, file_path_name, download_type):
+    def loadBibleResource(self, download_type):
         """
-        Loads a web bible resource file.
-
-        ``file_path_name``
-            The file to load including the file's path.
+        Loads a web bible from bible_resources.sqlite.
 
         ``download_type``
-            The WebDownload type this file is for.
+            The WebDownload type e.g. bibleserver.
         """
         self.web_bible_list[download_type] = {}
-        books_file = None
-        try:
-            books_file = open(file_path_name, 'rb')
-            dialect = csv.Sniffer().sniff(books_file.read(1024))
-            books_file.seek(0)
-            books_reader = csv.reader(books_file, dialect)
-            for line in books_reader:
-                ver = string_is_unicode(line[0])
-                name = string_is_unicode(line[1])
-                self.web_bible_list[download_type][ver] = name.strip()
-        except IOError:
-            log.exception(u'%s resources missing' %
-                WebDownload.Names[download_type])
-        finally:
-            if books_file:
-                books_file.close()
+        bibles = BiblesResourcesDB.get_webbibles(
+            WebDownload.Names[download_type])
+        for bible in bibles:
+            ver = bible[u'name']
+            name = bible[u'abbreviation']
+            self.web_bible_list[download_type][ver] = name.strip()
 
     def preWizard(self):
         """

=== added file 'openlp/plugins/bibles/forms/bibleimportrequestdialog.py'
--- openlp/plugins/bibles/forms/bibleimportrequestdialog.py	1970-01-01 00:00:00 +0000
+++ openlp/plugins/bibles/forms/bibleimportrequestdialog.py	2011-03-18 10:11:29 +0000
@@ -0,0 +1,95 @@
+# -*- coding: utf-8 -*-
+# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
+
+###############################################################################
+# OpenLP - Open Source Lyrics Projection                                      #
+# --------------------------------------------------------------------------- #
+# Copyright (c) 2008-2011 Raoul Snyman                                        #
+# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael      #
+# Gorven, Scott Guerrieri, Meinert Jordan, Armin Köhler, Andreas Preikschat,  #
+# Christian Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon  #
+# Tibble, Carsten Tinggaard, Frode Woldsund                                   #
+# --------------------------------------------------------------------------- #
+# This program is free software; you can redistribute it and/or modify it     #
+# under the terms of the GNU General Public License as published by the Free  #
+# Software Foundation; version 2 of the License.                              #
+#                                                                             #
+# This program is distributed in the hope that it will be useful, but WITHOUT #
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       #
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for    #
+# more details.                                                               #
+#                                                                             #
+# You should have received a copy of the GNU General Public License along     #
+# with this program; if not, write to the Free Software Foundation, Inc., 59  #
+# Temple Place, Suite 330, Boston, MA 02111-1307 USA                          #
+###############################################################################
+
+from PyQt4 import QtCore, QtGui
+
+from openlp.core.lib import translate
+from openlp.core.lib.ui import create_accept_reject_button_box
+
+class Ui_BibleImportRequest(object):
+    def setupUi(self, bibleImportRequest):
+        bibleImportRequest.setObjectName("BibleImportRequest")
+        bibleImportRequest.resize(400, 175)
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, 
+            QtGui.QSizePolicy.MinimumExpanding)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(bibleImportRequest.sizePolicy()
+            .hasHeightForWidth())
+        bibleImportRequest.setSizePolicy(sizePolicy)
+        self.widget = QtGui.QWidget(bibleImportRequest)
+        self.widget.setGeometry(QtCore.QRect(10, 15, 381, 151))
+        self.widget.setObjectName("widget")
+        self.verticalLayout = QtGui.QVBoxLayout(self.widget)
+        self.verticalLayout.setObjectName("verticalLayout")
+        self.headlineLabel = QtGui.QLabel(self.widget)
+        font = QtGui.QFont()
+        font.setFamily("Arial")
+        font.setPointSize(11)
+        font.setWeight(75)
+        font.setBold(True)
+        self.headlineLabel.setFont(font)
+        self.headlineLabel.setObjectName("HeadlineLabel")
+        self.verticalLayout.addWidget(self.headlineLabel)
+        self.infoLabel = QtGui.QLabel(self.widget)
+        self.infoLabel.setObjectName("InfoLabel")
+        self.verticalLayout.addWidget(self.infoLabel)
+        self.formLayout = QtGui.QFormLayout()
+        self.formLayout.setObjectName("formLayout")
+        self.requestLabel = QtGui.QLabel(self.widget)
+        self.requestLabel.setObjectName("RequestLabel")
+        self.formLayout.setWidget(0, QtGui.QFormLayout.LabelRole, 
+            self.requestLabel)
+        self.requestComboBox = QtGui.QComboBox(self.widget)
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, 
+            QtGui.QSizePolicy.Fixed)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(self.requestComboBox.sizePolicy()
+            .hasHeightForWidth())
+        self.requestComboBox.setSizePolicy(sizePolicy)
+        self.requestComboBox.setObjectName("RequestComboBox")
+        self.formLayout.setWidget(0, QtGui.QFormLayout.FieldRole, 
+            self.requestComboBox)
+        self.verticalLayout.addLayout(self.formLayout)
+        spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, 
+            QtGui.QSizePolicy.Expanding)
+        self.verticalLayout.addItem(spacerItem)
+        self.formLayout.addWidget(
+            create_accept_reject_button_box(bibleImportRequest))
+        self.retranslateUi(bibleImportRequest)
+        QtCore.QMetaObject.connectSlotsByName(bibleImportRequest)
+
+    def retranslateUi(self, bibleImportRequest):
+        bibleImportRequest.setWindowTitle(
+            translate("BiblesPlugin.bibleImportRequest", "Dialog"))
+        self.headlineLabel.setText(
+            translate("BiblesPlugin.bibleImportRequest", "Choose Book:"))
+        self.infoLabel.setText(translate("BiblesPlugin.bibleImportRequest", 
+            "The following books cannot be clearly attributed. \n"
+            "Please choose the book it is."))
+        self.requestLabel.setText(translate("BiblesPlugin.bibleImportRequest", 
+            "Book:"))

=== added file 'openlp/plugins/bibles/forms/bibleimportrequestform.py'
--- openlp/plugins/bibles/forms/bibleimportrequestform.py	1970-01-01 00:00:00 +0000
+++ openlp/plugins/bibles/forms/bibleimportrequestform.py	2011-03-18 10:11:29 +0000
@@ -0,0 +1,82 @@
+# -*- coding: utf-8 -*-
+# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
+
+###############################################################################
+# OpenLP - Open Source Lyrics Projection                                      #
+# --------------------------------------------------------------------------- #
+# Copyright (c) 2008-2011 Raoul Snyman                                        #
+# Portions copyright (c) 2008-2011 Tim Bentley, Jonathan Corwin, Michael      #
+# Gorven, Scott Guerrieri, Meinert Jordan, Armin Köhler, Andreas Preikschat,  #
+# Christian Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon  #
+# Tibble, Carsten Tinggaard, Frode Woldsund                                   #
+# --------------------------------------------------------------------------- #
+# This program is free software; you can redistribute it and/or modify it     #
+# under the terms of the GNU General Public License as published by the Free  #
+# Software Foundation; version 2 of the License.                              #
+#                                                                             #
+# This program is distributed in the hope that it will be useful, but WITHOUT #
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       #
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for    #
+# more details.                                                               #
+#                                                                             #
+# You should have received a copy of the GNU General Public License along     #
+# with this program; if not, write to the Free Software Foundation, Inc., 59  #
+# Temple Place, Suite 330, Boston, MA 02111-1307 USA                          #
+###############################################################################
+
+"""
+Module implementing BibleImportRequest.
+"""
+import logging
+
+from PyQt4.QtGui import QDialog
+
+from openlp.core.lib import translate
+from openlp.core.lib.ui import critical_error_message_box
+from openlp.plugins.bibles.forms.bibleimportrequestdialog import \
+    Ui_BibleImportRequest
+from openlp.plugins.bibles.lib.db import BiblesResourcesDB
+
+log = logging.getLogger(__name__)
+
+class BibleImportRequest(QDialog, Ui_BibleImportRequest):
+    """
+    Class documentation goes here.
+    """
+    log.info(u'BibleImportRequest loaded')
+    
+    def __init__(self, parent = None):
+        """
+        Constructor
+        """
+        QDialog.__init__(self, parent)
+        self.setupUi(self)
+
+    def exec_(self, case,  name=None):
+        items = []
+        self.requestComboBox.addItem(u'')
+        if case == u'language':
+            self.headlineLabel.setText(translate(
+                "BiblesPlugin.BibleImportRequest", "Choose Language:"))
+            self.infoLabel.setText(translate("BiblesPlugin.BibleImportRequest", 
+                "Please choose the language the bible is."))
+            self.requestLabel.setText(
+                translate("BiblesPlugin.BibleImportRequest", "Language:"))
+            items = BiblesResourcesDB.get_languages()
+        elif case == u'book':
+            self.requestLabel.setText(
+                translate("BiblesPlugin.BibleImportRequest", name))
+            items = BiblesResourcesDB.get_books()
+        for item in items:
+            self.requestComboBox.addItem(item[u'name'])
+        return QDialog.exec_(self)
+    
+    def accept(self):
+        if self.requestComboBox.currentText() == u"":
+            critical_error_message_box(
+                message=translate('BiblesPlugin.BibleImportRequest',
+                'You need to choose an item.'))
+            self.requestComboBox.setFocus()
+            return False
+        else:
+            return QDialog.accept(self)

=== modified file 'openlp/plugins/bibles/lib/csvbible.py'
--- openlp/plugins/bibles/lib/csvbible.py	2011-03-04 13:57:39 +0000
+++ openlp/plugins/bibles/lib/csvbible.py	2011-03-18 10:11:29 +0000
@@ -70,7 +70,7 @@
 import csv
 
 from openlp.core.lib import Receiver, translate
-from openlp.plugins.bibles.lib.db import BibleDB, Testament
+from openlp.plugins.bibles.lib.db import BibleDB, Testament, BiblesResourcesDB
 
 log = logging.getLogger(__name__)
 
@@ -86,6 +86,7 @@
         """
         log.info(self.__class__.__name__)
         BibleDB.__init__(self, parent, **kwargs)
+        self.parent = parent
         try:
             self.testamentsfile = kwargs[u'testamentsfile']
         except KeyError:
@@ -135,6 +136,14 @@
         self.wizard.progressBar.setMinimum(0)
         self.wizard.progressBar.setMaximum(66)
         success = True
+        language = self.parent.mediaItem.importRequest(u'language')
+        if not language:
+            log.exception(u'Importing books from %s " '\
+                'failed' % self.booksfile)
+            return False
+        language = BiblesResourcesDB.get_language(language)
+        language_id = language[u'id']
+        self.create_meta(u'language_id', language_id)
         books_file = None
         book_list = {}
         # Populate the Tables
@@ -148,8 +157,15 @@
                 self.wizard.incrementProgressBar(unicode(
                     translate('BibleDB.Wizard', 'Importing books... %s')) %
                     unicode(line[2], details['encoding']))
+                book_ref_id = self.parent.manager.get_book_ref_id_by_name(
+                    unicode(line[2], details['encoding']), language_id)
+                if not book_ref_id:
+                    log.exception(u'Importing books from %s " '\
+                        'failed' % self.booksfile)
+                    return False
+                book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
                 self.create_book(unicode(line[2], details['encoding']),
-                    unicode(line[3], details['encoding']), int(line[1]))
+                    book_ref_id, book_details[u'testament_id'])
                 book_list[int(line[0])] = unicode(line[2], details['encoding'])
             Receiver.send_message(u'openlp_process_events')
         except (IOError, IndexError):

=== modified file 'openlp/plugins/bibles/lib/db.py'
--- openlp/plugins/bibles/lib/db.py	2011-03-10 16:05:12 +0000
+++ openlp/plugins/bibles/lib/db.py	2011-03-18 10:11:29 +0000
@@ -26,7 +26,9 @@
 
 import logging
 import chardet
+import os
 import re
+import sqlite3
 
 from PyQt4 import QtCore
 from sqlalchemy import Column, ForeignKey, or_, Table, types
@@ -36,6 +38,7 @@
 from openlp.core.lib import Receiver, translate
 from openlp.core.lib.db import BaseModel, init_db, Manager
 from openlp.core.lib.ui import critical_error_message_box
+from openlp.core.utils import AppLocation
 
 log = logging.getLogger(__name__)
 
@@ -66,6 +69,12 @@
     """
     pass
 
+class Spelling(BaseModel):
+    """
+    Spelling model
+    """
+    pass
+
 
 def init_schema(url):
     """
@@ -86,9 +95,9 @@
     )
     book_table = Table(u'book', metadata,
         Column(u'id', types.Integer, primary_key=True),
-        Column(u'testament_id', types.Integer, ForeignKey(u'testament.id')),
+        Column(u'book_reference_id', types.Integer),
+        Column(u'testament_reference_id', types.Integer),
         Column(u'name', types.Unicode(50), index=True),
-        Column(u'abbreviation', types.Unicode(5), index=True),
     )
     verse_table = Table(u'verse', metadata,
         Column(u'id', types.Integer, primary_key=True, index=True),
@@ -105,8 +114,7 @@
     try:
         class_mapper(Testament)
     except UnmappedClassError:
-        mapper(Testament, testament_table,
-            properties={'books': relation(Book, backref='testament')})
+        mapper(Testament, testament_table)
     try:
         class_mapper(Book)
     except UnmappedClassError:
@@ -120,6 +128,29 @@
     metadata.create_all(checkfirst=True)
     return session
 
+def init_schema_spelling_extension(url):
+    """
+    Setup a spelling database connection and initialise the database schema.
+
+    ``url``
+        The database to setup.
+    """
+    session, metadata = init_db(url)
+
+    spelling_table = Table(u'spelling', metadata,
+        Column(u'id', types.Integer, primary_key=True),
+        Column(u'book_reference_id', types.Integer),
+        Column(u'language_id', types.Integer),
+        Column(u'name', types.Unicode(50), index=True),
+    )
+
+    try:
+        class_mapper(Spelling)
+    except UnmappedClassError:
+        mapper(Spelling, spelling_table)
+
+    metadata.create_all(checkfirst=True)
+    return session
 
 class BibleDB(QtCore.QObject, Manager):
     """
@@ -219,22 +250,23 @@
         self.save_object(Testament.populate(name=u'New Testament'))
         self.save_object(Testament.populate(name=u'Apocrypha'))
 
-    def create_book(self, name, abbrev, testament=1):
+    def create_book(self, name, bk_ref_id, testament=1):
         """
         Add a book to the database.
 
         ``name``
             The name of the book.
 
-        ``abbrev``
-            The abbreviation of the book.
+        ``bk_ref_id``
+            The book_reference_id from bibles_resources.sqlite of the book.
 
         ``testament``
-            *Defaults to 1.* The id of the testament this book belongs to.
+            *Defaults to 1.* The testament_reference_id from 
+            bibles_resources.sqlite of the testament this book belongs to.
         """
-        log.debug(u'create_book %s,%s', name, abbrev)
-        book = Book.populate(name=name, abbreviation=abbrev,
-            testament_id=testament)
+        log.debug(u'create_book %s,%s', name, bk_ref_id)
+        book = Book.populate(name=name, book_reference_id=bk_ref_id,
+            testament_reference_id=testament)
         self.save_object(book)
         return book
 
@@ -302,6 +334,8 @@
         ``value``
             The value for this instance.
         """
+        if not isinstance(value, unicode):
+            value = unicode(value)
         log.debug(u'save_meta %s/%s', key, value)
         self.save_object(BibleMeta.populate(key=key, value=value))
 
@@ -314,9 +348,6 @@
         """
         log.debug(u'BibleDb.get_book("%s")', book)
         db_book = self.get_object_filtered(Book, Book.name.like(book + u'%'))
-        if db_book is None:
-            db_book = self.get_object_filtered(Book,
-                Book.abbreviation.like(book + u'%'))
         return db_book
 
     def get_books(self):
@@ -326,7 +357,19 @@
         """
         return self.get_all_objects(Book, order_by_ref=Book.id)
 
-    def get_verses(self, reference_list):
+    def get_book_by_book_ref_id(self, id):
+        """
+        Return a book object from the database.
+
+        ``book``
+            The name of the book to return.
+        """
+        log.debug(u'BibleDb.get_book_by_book_ref_id("%s")', id)
+        db_book = self.get_object_filtered(Book, 
+            Book.book_reference_id.like(id))
+        return db_book
+
+    def get_verses(self, reference_list, en_reference_list):
         """
         This is probably the most used function. It retrieves the list of
         verses based on the user's query.
@@ -344,15 +387,18 @@
 
                 [(u'Genesis', 1, 1, 1), (u'Genesis', 2, 2, 3)]
         """
-        log.debug(u'BibleDB.get_verses: %s', reference_list)
+        log.debug(u'BibleDB.get_verses: %s - %s', reference_list, 
+            en_reference_list)
         verse_list = []
-        for book, chapter, start_verse, end_verse in reference_list:
+        for (book, chapter, start_verse, end_verse), (en_book, en_chapter, 
+            en_start_verse, en_end_verse) in zip(reference_list, 
+            en_reference_list):
             db_book = self.get_book(book)
             if db_book:
                 book = db_book.name
                 log.debug(u'Book name corrected to "%s"', book)
                 if end_verse == -1:
-                    end_verse = self.get_verse_count(book, chapter)
+                    end_verse = self.get_verse_count(en_book, chapter)
                 verses = self.session.query(Verse)\
                     .filter_by(book_id=db_book.id)\
                     .filter_by(chapter=chapter)\
@@ -444,3 +490,408 @@
         log.debug(u'...............................Verses ')
         verses = self.session.query(Verse).all()
         log.debug(verses)
+
+
+class BiblesResourcesDB(QtCore.QObject, Manager):
+    """
+    This class represents the database-bound Bible Resources. It provide
+    some resources which are used in the Bibles plugin.
+    A wrapper class around a small SQLite database which contains the download
+    resources, a biblelist from the different download resources, the books,
+    chapter counts and verse counts for the web download Bibles, a language 
+    reference, the testament reference and some basic spelling variants. This 
+    class contains a singleton "cursor" so that only one connection to the 
+    SQLite database is ever used.
+    """
+    cursor = None
+
+    @staticmethod
+    def get_cursor():
+        """
+        Return the cursor object. Instantiate one if it doesn't exist yet.
+        """
+        if BiblesResourcesDB.cursor is None:
+            filepath = os.path.join(
+                AppLocation.get_directory(AppLocation.PluginsDir), u'bibles',
+                u'resources', u'bibles_resources.sqlite')
+            conn = sqlite3.connect(filepath)
+            BiblesResourcesDB.cursor = conn.cursor()
+        return BiblesResourcesDB.cursor
+
+    @staticmethod
+    def run_sql(query, parameters=()):
+        """
+        Run an SQL query on the database, returning the results.
+
+        ``query``
+            The actual SQL query to run.
+
+        ``parameters``
+            Any variable parameters to add to the query.
+        """
+        cursor = BiblesResourcesDB.get_cursor()
+        cursor.execute(query, parameters)
+        return cursor.fetchall()
+
+    @staticmethod
+    def get_books():
+        """
+        Return a list of all the books of the Bible.
+        """
+        books = BiblesResourcesDB.run_sql(u'SELECT id, testament_id, name, '
+                u'abbreviation, chapters FROM book_reference ORDER BY id')
+        book_list = []
+        for book in books:
+            book_list.append({
+                u'id': book[0],
+                u'testament_id': book[1],
+                u'name': unicode(book[2]),
+                u'abbreviation': unicode(book[3]),
+                u'chapters': book[4]
+            })
+        return book_list
+
+    @staticmethod
+    def get_book(name):
+        """
+        Return a book by name or abbreviation.
+
+        ``name``
+            The name or abbreviation of the book.
+        """
+        log.debug(u'get_book: %s', name)
+        if not isinstance(name, unicode):
+            name = unicode(name)
+        books = BiblesResourcesDB.run_sql(u'SELECT id, testament_id, name, '
+                u'abbreviation, chapters FROM book_reference WHERE name = ? OR '
+                u'abbreviation = ?', (name, name))
+        if books:
+            return {
+                u'id': books[0][0],
+                u'testament_id': books[0][1],
+                u'name': unicode(books[0][2]),
+                u'abbreviation': unicode(books[0][3]),
+                u'chapters': books[0][4]
+            }
+        else:
+            return None
+
+    @staticmethod
+    def get_book_by_id(id):
+        """
+        Return a book by id.
+
+        ``id``
+            The id of the book.
+        """
+        if not isinstance(id, int):
+            id = int(id)
+        books = BiblesResourcesDB.run_sql(u'SELECT id, testament_id, name, '
+                u'abbreviation, chapters FROM book_reference WHERE id = ?', 
+                (id, ))
+        if books:
+            return {
+                u'id': books[0][0],
+                u'testament_id': books[0][1],
+                u'name': unicode(books[0][2]),
+                u'abbreviation': unicode(books[0][3]),
+                u'chapters': books[0][4]
+            }
+        else:
+            return None
+
+    @staticmethod
+    def get_chapter(name, chapter):
+        """
+        Return the chapter details for a specific chapter of a book.
+
+        ``name``
+            The name or abbreviation of a book.
+
+        ``chapter``
+            The chapter number.
+        """
+        if not isinstance(name, int):
+            chapter = int(chapter)
+        book = BiblesResourcesDB.get_book(name)
+        chapters = BiblesResourcesDB.run_sql(u'SELECT id, book_reference_id, '
+            u'chapter, verse_count FROM chapters WHERE book_reference_id = ?', 
+            (book[u'id'],))
+        if chapters:
+            return {
+                u'id': chapters[chapter-1][0],
+                u'book_reference_id': chapters[chapter-1][1],
+                u'chapter': chapters[chapter-1][2],
+                u'verse_count': chapters[chapter-1][3]
+            }
+        else:
+            return None
+
+    @staticmethod
+    def get_chapter_count(book):
+        """
+        Return the number of chapters in a book.
+
+        ``book``
+            The name or abbreviation of the book.
+        """
+        details = BiblesResourcesDB.get_book(book)
+        if details:
+            return details[u'chapters']
+        return 0
+
+    @staticmethod
+    def get_verse_count(book, chapter):
+        """
+        Return the number of verses in a chapter.
+
+        ``book``
+            The name or abbreviation of the book.
+
+        ``chapter``
+            The number of the chapter.
+        """
+        details = BiblesResourcesDB.get_chapter(book, chapter)
+        if details:
+            return details[u'verse_count']
+        return 0
+
+    @staticmethod
+    def get_download_source(source):
+        """
+        Return a download_source_id by source.
+
+        ``name``
+            The name or abbreviation of the book.
+        """
+        if not isinstance(source, unicode):
+            source = unicode(source)
+        source = source.title()
+        dl_source = BiblesResourcesDB.run_sql(u'SELECT id, source FROM '
+                u'download_source WHERE source = ?', (source.lower(),))
+        if dl_source:
+            return {
+                u'id': dl_source[0][0],
+                u'source': dl_source[0][1]
+            }
+        else:
+            return None
+    
+    @staticmethod
+    def get_webbibles(source):
+        """
+        Return the bibles a webbible provide for download.
+
+        ``source``
+            The source of the webbible.
+        """
+        if not isinstance(source,  unicode):
+            source = unicode(source)
+        source = BiblesResourcesDB.get_download_source(source)
+        bibles = BiblesResourcesDB.run_sql(u'SELECT id, name, abbreviation, '
+            u'language_id, download_source_id FROM webbibles WHERE '
+            u'download_source_id = ?', (source[u'id'],))
+        if bibles:
+            bibles_temp = []
+            for bible in bibles:
+                bibles_temp.append({
+                    u'id': bible[0],
+                    u'name': bible[1],
+                    u'abbreviation': bible[2],
+                    u'language_id': bible[3], 
+                    u'download_source_id': bible[4]
+                    })
+            return bibles_temp
+        else:
+            return None
+
+    @staticmethod
+    def get_webbible(abbreviation, source):
+        """
+        Return the bibles a webbible provide for download.
+
+        ``abbreviation``
+            The abbreviation of the webbible.
+            
+        ``source``
+            The source of the webbible.
+        """
+        if not isinstance(abbreviation, unicode):
+            abbreviation = unicode(abbreviation)
+        if not isinstance(source, unicode):
+            source = unicode(source)
+        source = BiblesResourcesDB.get_download_source(source)
+        bible = BiblesResourcesDB.run_sql(u'SELECT id, name, abbreviation, '
+            u'language_id, download_source_id FROM webbibles WHERE '
+            u'download_source_id = ? AND abbreviation = ?', (source[u'id'], 
+            abbreviation))
+        if bible:
+            bibles_temp = {
+                u'id': bible[0][0],
+                u'name': bible[0][1],
+                u'abbreviation': bible[0][2],
+                u'language_id': bible[0][3], 
+                u'download_source_id': bible[0][4]
+                }
+            return bibles_temp
+        else:
+            return None
+
+    @staticmethod
+    def get_spelling(name, language_id=None):
+        """
+        Return a book_reference_id if the name matches.
+        """
+        if language_id:
+            id = BiblesResourcesDB.run_sql(u'SELECT book_reference_id '
+                u'FROM spelling WHERE name = ? and language_id = ? ORDER BY id',
+                (name, language_id))
+        else:
+            id = BiblesResourcesDB.run_sql(u'SELECT book_reference_id '
+                u'FROM spelling WHERE name = ? ORDER BY id', (name, ))
+        if id:
+            return int(id[0][0])
+        else:
+            return None
+
+    @staticmethod
+    def get_language(name):
+        """
+        Return a dict containing the language id, name and code by name or 
+        abbreviation.
+
+        ``name``
+            The name or abbreviation of the language.
+        """
+        if not isinstance(name, unicode):
+            name = unicode(name)
+        name = name.title()
+        language = BiblesResourcesDB.run_sql(u'SELECT id, name, code FROM '
+                u'language WHERE name = ? OR code = ?', (name, name.lower()))
+        if language:
+            return {
+                u'id': language[0][0],
+                u'name': unicode(language[0][1]),
+                u'code': unicode(language[0][2])
+            }
+        else:
+            return None
+
+    @staticmethod
+    def get_languages():
+        """
+        Return a dict containing all languages with id, name and code.
+        """
+        languages = BiblesResourcesDB.run_sql(u'SELECT id, name, code FROM '
+                u'language ORDER by name')
+        if languages:
+            languages_temp = []
+            for language in languages:
+                languages_temp.append({
+                    u'id': language[0],
+                    u'name': unicode(language[1]),
+                    u'code': unicode(language[2])
+                })
+            return languages_temp
+        else:
+            return None
+
+    @staticmethod
+    def get_testament_reference():
+        """
+        Return a list of all testaments and their id of the Bible.
+        """
+        testaments = BiblesResourcesDB.run_sql(u'SELECT id, name FROM '
+                u'testament_reference ORDER BY id')
+        testament_list = []
+        for testament in testaments:
+            testament_list.append({
+                u'id': testament[0],
+                u'name': unicode(testament[1])
+            })
+        return testament_list
+
+class SpellingDB(QtCore.QObject, Manager):
+    """
+    This class represents a database-bound spelling. 
+    """
+
+    def __init__(self, parent, **kwargs):
+        """
+        The constructor loads up the database and creates and initialises the
+        tables if the database doesn't exist.
+
+        **Required keyword arguments:**
+
+        ``path``
+            The path to the bible database file.
+
+        ``name``
+            The name of the database. This is also used as the file name for
+            SQLite databases.
+        """
+        log.info(u'SpellingDB loaded')
+        QtCore.QObject.__init__(self)
+        self.bible_plugin = parent
+        if u'path' not in kwargs:
+            raise KeyError(u'Missing keyword argument "path".')
+        self.stop_import_flag = False
+        self.name = u'spelling_extension.sqlite'
+        if not isinstance(self.name, unicode):
+            self.name = unicode(self.name, u'utf-8')
+        self.file = self.name
+        Manager.__init__(self, u'bibles/resources', 
+            init_schema_spelling_extension, self.file)
+        self.wizard = None
+        QtCore.QObject.connect(Receiver.get_receiver(),
+            QtCore.SIGNAL(u'openlp_stop_wizard'), self.stop_import)
+
+    def stop_import(self):
+        """
+        Stops the import of the Bible.
+        """
+        log.debug(u'Stopping import')
+        self.stop_import_flag = True
+
+    def get_book_reference_id(self, name,  language=None):
+        """
+        Return the book_reference_id of a book by name.
+
+        ``name``
+            The name to search the id.
+            
+        ``language``
+            The language for which should be searched
+        """
+        log.debug(u'SpellingDB.get_book_reference_id("%s")', name)
+        if language:
+            id = self.session.query(Spelling.book_reference_id)\
+                .filter(Spelling.name.like(name))\
+                .filter(Spelling.language_id.like(language)).first()
+        else:
+            id = self.get_object_filtered(Spelling.book_reference_id,
+                Spelling.name.like(name))
+        if not id:
+            return None
+        else:
+            return id[0]
+
+    def create_spelling(self, name, book_reference_id, language_id):
+        """
+        Add a spelling to the database.
+
+        ``name``
+            The name of the spelling.
+
+        ``book_reference_id``
+            The book_reference_id of the book.
+
+        ``language_id``
+            The language which the spelling of the book name is.
+        """
+        log.debug(u'create_spelling %s, book_reference_id:%s, language_id:%s', 
+            name, book_reference_id, language_id)
+        spelling = Spelling.populate(name=name, 
+            book_reference_id=book_reference_id, language_id=language_id)
+        self.save_object(spelling)
+        return spelling

=== modified file 'openlp/plugins/bibles/lib/http.py'
--- openlp/plugins/bibles/lib/http.py	2011-03-14 19:26:38 +0000
+++ openlp/plugins/bibles/lib/http.py	2011-03-18 10:11:29 +0000
@@ -41,146 +41,11 @@
 from openlp.core.lib.ui import critical_error_message_box
 from openlp.core.utils import AppLocation, get_web_page
 from openlp.plugins.bibles.lib import SearchResults
-from openlp.plugins.bibles.lib.db import BibleDB, Book
+from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB, \
+    SpellingDB, Book
 
 log = logging.getLogger(__name__)
 
-class HTTPBooks(object):
-    """
-    A wrapper class around a small SQLite database which contains the books,
-    chapter counts and verse counts for the web download Bibles. This class
-    contains a singleton "cursor" so that only one connection to the SQLite
-    database is ever used.
-    """
-    cursor = None
-
-    @staticmethod
-    def get_cursor():
-        """
-        Return the cursor object. Instantiate one if it doesn't exist yet.
-        """
-        if HTTPBooks.cursor is None:
-            filepath = os.path.join(
-                AppLocation.get_directory(AppLocation.PluginsDir), u'bibles',
-                u'resources', u'httpbooks.sqlite')
-            conn = sqlite3.connect(filepath)
-            HTTPBooks.cursor = conn.cursor()
-        return HTTPBooks.cursor
-
-    @staticmethod
-    def run_sql(query, parameters=()):
-        """
-        Run an SQL query on the database, returning the results.
-
-        ``query``
-            The actual SQL query to run.
-
-        ``parameters``
-            Any variable parameters to add to the query.
-        """
-        cursor = HTTPBooks.get_cursor()
-        cursor.execute(query, parameters)
-        return cursor.fetchall()
-
-    @staticmethod
-    def get_books():
-        """
-        Return a list of all the books of the Bible.
-        """
-        books = HTTPBooks.run_sql(u'SELECT id, testament_id, name, '
-                u'abbreviation, chapters FROM books ORDER BY id')
-        book_list = []
-        for book in books:
-            book_list.append({
-                u'id': book[0],
-                u'testament_id': book[1],
-                u'name': unicode(book[2]),
-                u'abbreviation': unicode(book[3]),
-                u'chapters': book[4]
-            })
-        return book_list
-
-    @staticmethod
-    def get_book(name):
-        """
-        Return a book by name or abbreviation.
-
-        ``name``
-            The name or abbreviation of the book.
-        """
-        if not isinstance(name, unicode):
-            name = unicode(name)
-        name = name.title()
-        books = HTTPBooks.run_sql(u'SELECT id, testament_id, name, '
-                u'abbreviation, chapters FROM books WHERE name = ? OR '
-                u'abbreviation = ?', (name, name))
-        if books:
-            return {
-                u'id': books[0][0],
-                u'testament_id': books[0][1],
-                u'name': unicode(books[0][2]),
-                u'abbreviation': unicode(books[0][3]),
-                u'chapters': books[0][4]
-            }
-        else:
-            return None
-
-    @staticmethod
-    def get_chapter(name, chapter):
-        """
-        Return the chapter details for a specific chapter of a book.
-
-        ``name``
-            The name or abbreviation of a book.
-
-        ``chapter``
-            The chapter number.
-        """
-        if not isinstance(name, int):
-            chapter = int(chapter)
-        book = HTTPBooks.get_book(name)
-        chapters = HTTPBooks.run_sql(u'SELECT id, book_id, chapter, '
-            u'verses FROM chapters WHERE book_id = ?', (book[u'id'],))
-        if chapters:
-            return {
-                u'id': chapters[chapter-1][0],
-                u'book_id': chapters[chapter-1][1],
-                u'chapter': chapters[chapter-1][2],
-                u'verses': chapters[chapter-1][3]
-            }
-        else:
-            return None
-
-    @staticmethod
-    def get_chapter_count(book):
-        """
-        Return the number of chapters in a book.
-
-        ``book``
-            The name or abbreviation of the book.
-        """
-        details = HTTPBooks.get_book(book)
-        if details:
-            return details[u'chapters']
-        return 0
-
-    @staticmethod
-    def get_verse_count(book, chapter):
-        """
-        Return the number of verses in a chapter.
-
-        ``book``
-            The name or abbreviation of the book.
-
-        ``chapter``
-            The number of the chapter.
-        """
-        details = HTTPBooks.get_chapter(book, chapter)
-        if details:
-            return details[u'verses']
-        return 0
-
-
 class BGExtract(object):
     """
     Extract verses from BibleGateway
@@ -263,6 +128,52 @@
             return None
         return SearchResults(bookname, chapter, verse_list)
 
+    def get_books_from_http(self, version):
+        """
+        Load a list of all books a bible contaions from BibleGateway website.
+
+        ``version``
+            The version of the bible like NIV for New International Version
+        """
+        log.debug(u'get_books_from_http %s', version)
+        url_params = urllib.urlencode(
+            {u'search': 'Bible-List', u'version': u'%s' % version})
+        reference_url = u'http://www.biblegateway.com/passage/?%s' % url_params
+        page = get_web_page(reference_url)
+        if not page:
+            send_error_message(u'download')
+            return None
+        page_source = page.read()
+        page_source = unicode(page_source, 'utf8')
+        page_source_temp = re.search(u'<table id="booklist".*?>.*?</table>',  \
+            page_source,  re.DOTALL)
+        if page_source_temp:
+            soup = page_source_temp.group(0)
+        else:
+            soup = None
+        try:
+            soup = BeautifulSoup(soup)
+        except HTMLParseError:
+            log.exception(u'BeautifulSoup could not parse the bible page.')
+        if not soup:
+            send_error_message(u'parse')
+            return None
+        Receiver.send_message(u'openlp_process_events')
+        content = soup.find(u'table', {u'id': u'booklist'})
+        content = content.findAll(u'tr')
+        #log.debug(content)
+        if not content:
+            log.exception(u'No books found in the Biblegateway response.')
+            send_error_message(u'parse')
+            return None
+        books = []
+        for book in content:
+            book = book.find(u'td')
+            if book:
+                books.append(book.contents[0])
+                log.debug(book.contents[0])
+        return books
+
 
 class BSExtract(object):
     """
@@ -308,6 +219,31 @@
             verses[versenumber] = verse.contents[1].rstrip(u'\n')
         return SearchResults(bookname, chapter, verses)
 
+    def get_books_from_http(self, version):
+        """
+        Load a list of all books a bible contains from Bibleserver mobile 
+        website.
+
+        ``version``
+            The version of the bible like NIV for New International Version
+        """
+        log.debug(u'get_books_from_http %s', version)
+        chapter_url = u'http://m.bibleserver.com/overlay/selectBook?'\
+            'translation=%s' % (version)
+        soup = get_soup_for_bible_ref(chapter_url)
+        if not soup:
+            return None
+        content = soup.find(u'ul')
+        if not content:
+            log.exception(u'No books found in the Bibleserver response.')
+            send_error_message(u'parse')
+            return None
+        content = content.findAll(u'li')
+        books = []
+        for book in content:
+            books.append(book.contents[0].contents[0])
+        return books
+
 
 class CWExtract(object):
     """
@@ -377,6 +313,33 @@
             verses[versenumber] = versetext
         return SearchResults(bookname, chapter, verses)
 
+    def get_books_from_http(self, version):
+        """
+        Load a list of all books  a bible contain from the Crosswalk website.
+
+        ``version``
+            The version of the bible like NIV for New International Version
+        """
+        log.debug(u'get_books_from_http %s', version)
+        chapter_url = u'http://www.biblestudytools.com/%s/'\
+             % (version)
+        soup = get_soup_for_bible_ref(chapter_url)
+        if not soup:
+            return None
+        content = soup.find(u'div', {u'class': u'Body'})
+        content = content.find(u'ul', {u'class': u'parent'})
+        if not content:
+            log.exception(u'No books found in the Crosswalk response.')
+            send_error_message(u'parse')
+            return None
+        content = content.findAll(u'li')
+        books = []
+        for book in content:
+            book = book.find(u'a')
+            books.append(book.contents[0])
+            log.debug(book.contents[0])
+        return books
+
 
 class HTTPBible(BibleDB):
     log.info(u'%s HTTPBible loaded' , __name__)
@@ -392,6 +355,7 @@
         Init confirms the bible exists and stores the database path.
         """
         BibleDB.__init__(self, parent, **kwargs)
+        self.parent = parent
         self.download_source = kwargs[u'download_source']
         self.download_name = kwargs[u'download_name']
         # TODO: Clean up proxy stuff. We probably want one global proxy per
@@ -399,6 +363,8 @@
         self.proxy_server = None
         self.proxy_username = None
         self.proxy_password = None
+        if u'path' in kwargs:
+            self.path = kwargs[u'path']
         if u'proxy_server' in kwargs:
             self.proxy_server = kwargs[u'proxy_server']
         if u'proxy_username' in kwargs:
@@ -423,9 +389,45 @@
         if self.proxy_password:
             # Store the proxy password.
             self.create_meta(u'proxy password', self.proxy_password)
+        if self.download_source.lower() == u'crosswalk':
+            handler = CWExtract(self.proxy_server)
+        elif self.download_source.lower() == u'biblegateway':
+            handler = BGExtract(self.proxy_server)
+        elif self.download_source.lower() == u'bibleserver':
+            handler = BSExtract(self.proxy_server)
+        books = handler.get_books_from_http(self.download_name)
+        if not books:
+            log.exception(u'Importing books from %s - download name: "%s" '\
+                'failed' % (self.download_source,  self.download_name))
+            return False
+        bible = BiblesResourcesDB.get_webbible(self.download_name, 
+                self.download_source.lower())
+        if bible[u'language_id']:
+            language_id = bible[u'language_id']
+        else:
+            language = self.parent.mediaItem.importRequest(u'language')
+            if not language:
+                log.exception(u'Importing books from %s - download name: "%s" '\
+                    'failed' % (self.download_source,  self.download_name))
+                return False
+            language = BiblesResourcesDB.get_language(language)
+            language_id = language[u'id']
+        # Store the language_id.
+        self.create_meta(u'language_id', language_id)
+        for book in books:
+            book_ref_id = self.parent.manager.get_book_ref_id_by_name(book, 
+                language_id)
+            if not book_ref_id:
+                log.exception(u'Importing books from %s - download name: "%s" '\
+                    'failed' % (self.download_source,  self.download_name))
+                return False
+            book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
+            log.debug(u'Book details: Name:%s; id:%s; testament_id:%s', 
+                book, book_ref_id, book_details[u'testament_id'])
+            self.create_book(book, book_ref_id, book_details[u'testament_id'])
         return True
 
-    def get_verses(self, reference_list):
+    def get_verses(self, reference_list,  en_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
@@ -438,6 +440,13 @@
             a list of tuples, with the following format::
 
                 (book, chapter, start_verse, end_verse)
+        
+        ``en_reference_list``
+            This is the list of references the media manager item wants. It is
+            a list of tuples, with the following format with englisch book 
+            names::
+
+                (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
@@ -451,17 +460,12 @@
             book = reference[0]
             db_book = self.get_book(book)
             if not db_book:
-                book_details = HTTPBooks.get_book(book)
-                if not book_details:
-                    critical_error_message_box(
-                        translate('BiblesPlugin', 'No Book Found'),
-                        translate('BiblesPlugin', 'No matching '
-                        'book could be found in this Bible. Check that you '
-                        'have spelled the name of the book correctly.'))
-                    return []
-                db_book = self.create_book(book_details[u'name'],
-                    book_details[u'abbreviation'],
-                    book_details[u'testament_id'])
+                critical_error_message_box(
+                    translate('BiblesPlugin', 'No Book Found'),
+                    translate('BiblesPlugin', 'No matching '
+                    'book could be found in this Bible. Check that you '
+                    'have spelled the name of the book correctly.'))
+                return []
             book = db_book.name
             if BibleDB.get_verse_count(self, book, reference[1]) == 0:
                 Receiver.send_message(u'cursor_busy')
@@ -480,7 +484,7 @@
                     Receiver.send_message(u'openlp_process_events')
                 Receiver.send_message(u'cursor_normal')
             Receiver.send_message(u'openlp_process_events')
-        return BibleDB.get_verses(self, reference_list)
+        return BibleDB.get_verses(self, reference_list, en_reference_list)
 
     def get_chapter(self, book, chapter):
         """
@@ -500,14 +504,13 @@
         """
         Return the list of books.
         """
-        return [Book.populate(name=book['name'])
-            for book in HTTPBooks.get_books()]
+        return self.get_all_objects(Book, order_by_ref=Book.id)
 
     def get_chapter_count(self, book):
         """
         Return the number of chapters in a particular book.
         """
-        return HTTPBooks.get_chapter_count(book)
+        return BiblesResourcesDB.get_chapter_count(book)
 
     def get_verse_count(self, book, chapter):
         """
@@ -519,7 +522,7 @@
         ``chapter``
             The chapter whose verses are being counted.
         """
-        return HTTPBooks.get_verse_count(book, chapter)
+        return BiblesResourcesDB.get_verse_count(book, chapter)
 
 def get_soup_for_bible_ref(reference_url, header=None, pre_parse_regex=None,
     pre_parse_substitute=None, cleaner=None):

=== modified file 'openlp/plugins/bibles/lib/manager.py'
--- openlp/plugins/bibles/lib/manager.py	2011-03-13 15:58:27 +0000
+++ openlp/plugins/bibles/lib/manager.py	2011-03-18 10:11:29 +0000
@@ -32,7 +32,8 @@
 from openlp.core.lib import Receiver, SettingsManager, translate
 from openlp.core.utils import AppLocation, delete_file
 from openlp.plugins.bibles.lib import parse_reference
-from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta
+from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta, SpellingDB,  \
+    Spelling, BiblesResourcesDB
 from csvbible import CSVBible
 from http import HTTPBible
 from opensong import OpenSongBible
@@ -129,6 +130,7 @@
         self.suffix = u'.sqlite'
         self.import_wizard = None
         self.reload_bibles()
+        self.reload_spelling()
         self.media = None
 
     def reload_bibles(self):
@@ -166,6 +168,17 @@
                 self.db_cache[name] = web_bible
         log.debug(u'Bibles reloaded')
 
+    def reload_spelling(self):
+        """
+        Reloads the Spelling from the Spelling table and spelling_extension 
+        database on disk.
+        """
+        log.debug(u'Reload spelling')
+        self.spelling_cache = {}
+        self.spelling_cache[u'spelling'] = SpellingDB(self.parent, 
+            path=self.path)
+        log.debug(u'Spelling reloaded')
+
     def set_process_dialog(self, wizard):
         """
         Sets the reference to the dialog with the progress bar on it.
@@ -207,19 +220,28 @@
             Unicode. The Bible to get the list of books from.
         """
         log.debug(u'BibleManager.get_books("%s")', bible)
-        return [
+        language_id = self.get_meta_data(bible, u'language_id')
+        books = []
+        for book in self.db_cache[bible].get_books():
+            book_id = self.get_book_ref_id_by_name(book.name, int(
+                language_id.value))
+            book_temp = BiblesResourcesDB.get_book_by_id(book_id)
+            book_ref = book_temp[u'name']
+            books.append(
             {
                 u'name': book.name,
-                u'chapters': self.db_cache[bible].get_chapter_count(book.name)
-            }
-            for book in self.db_cache[bible].get_books()
-        ]
+                u'chapters': self.db_cache[bible].get_chapter_count(book_ref)
+            })
+        return 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)
+        log.debug(u'BibleManager.get_book_chapter_count ("%s", "%s")', bible, 
+            book)
+        language_id = self.get_meta_data(bible, u'language_id')
+        book = self.get_book_ref(book, int(language_id.value))
         return self.db_cache[bible].get_chapter_count(book)
 
     def get_verse_count(self, bible, book, chapter):
@@ -229,9 +251,11 @@
         """
         log.debug(u'BibleManager.get_verse_count("%s", "%s", %s)',
             bible, book, chapter)
+        language_id = self.get_meta_data(bible, u'language_id')
+        book = self.get_book_ref(book, int(language_id.value))
         return self.db_cache[bible].get_verse_count(book, chapter)
 
-    def get_verses(self, bible, versetext):
+    def get_verses(self, bible, versetext, secondbible=False):
         """
         Parses a scripture reference, fetches the verses from the Bible
         specified, and returns a list of ``Verse`` objects.
@@ -262,7 +286,31 @@
             return None
         reflist = parse_reference(versetext)
         if reflist:
-            return self.db_cache[bible].get_verses(reflist)
+            # if we use a second bible we have to rename the book names
+            if secondbible:
+                log.debug(u'BibleManager.get_verses("secondbible true")')
+                meta =  self.db_cache[bible].get_object(BibleMeta, 
+                    u'language_id')
+                language_id = meta.value
+                new_reflist = []
+                for item in reflist:
+                    if item:
+                        book = self.get_book_ref(item[0])
+                        book_ref_id = self.parent.manager.\
+                            get_book_ref_id_by_name(book, language_id)
+                        book = self.db_cache[bible].get_book_by_book_ref_id(
+                            book_ref_id)
+                        new_reflist.append((book.name, item[1], item[2], 
+                            item[3]))
+                reflist = new_reflist
+            log.debug(u'BibleManager.get_verses("reflist: %s")', reflist)
+            en_reflist = []
+            for item in reflist:
+                if item:
+                    book = self.get_book_ref(item[0])
+                    en_reflist.append((book, item[1], item[2], item[3]))
+            log.debug(u'BibleManager.get_verses("en_reflist: %s")', en_reflist)
+            return self.db_cache[bible].get_verses(reflist, en_reflist)
         else:
             Receiver.send_message(u'openlp_information_message', {
                 u'title': translate('BiblesPlugin.BibleManager',
@@ -280,6 +328,43 @@
                 })
             return None
 
+    def get_book_ref(self, book,  language_id=None):
+        log.debug(u'BibleManager.get_book_ref("%s", "%s")', book, language_id)
+        book_id = self.get_book_ref_id_by_name(book, language_id)
+        book_temp = BiblesResourcesDB.get_book_by_id(book_id)
+        log.debug(u'get_book_ref - Return:%s', book_temp[u'name'])
+        return book_temp[u'name']
+
+    def get_book_ref_id_by_name(self, book, language_id=None):
+        log.debug(u'BibleManager.get_book_ref_id_by_name:("%s", "%s")', book, 
+            language_id)
+        if BiblesResourcesDB.get_book(book):
+            book_temp = BiblesResourcesDB.get_book(book)
+            book_id = book_temp[u'id']
+        elif BiblesResourcesDB.get_spelling(book, language_id):
+            book_id = BiblesResourcesDB.get_spelling(book, language_id)
+        elif self.spelling_cache[u'spelling'].get_book_reference_id(book, 
+            language_id):
+            book_id = self.spelling_cache[u'spelling'].\
+                get_book_reference_id(book, language_id)
+        else:   
+            book_ref = self.parent.mediaItem.importRequest(u'book', book)
+            log.debug(book_ref)
+            book_temp = BiblesResourcesDB.get_book(book_ref)
+            log.debug(book_temp)
+            if book_temp:
+                book_id = book_temp[u'id']
+            else:
+                return None
+            if book_id:
+                self.spelling_cache[u'spelling'].create_spelling(book, book_id, 
+                    language_id)
+        if book_id:
+            log.debug(u'get_book_ref_id_by_name - Return:%s', book_id)
+            return book_id
+        else:
+            return None
+
     def verse_search(self, bible, second_bible, text):
         """
         Does a verse search for the given bible and text.

=== modified file 'openlp/plugins/bibles/lib/mediaitem.py'
--- openlp/plugins/bibles/lib/mediaitem.py	2011-03-10 17:56:42 +0000
+++ openlp/plugins/bibles/lib/mediaitem.py	2011-03-18 10:11:29 +0000
@@ -36,6 +36,7 @@
 from openlp.plugins.bibles.forms import BibleImportForm
 from openlp.plugins.bibles.lib import LayoutStyle, DisplayStyle, \
     get_reference_match
+from openlp.plugins.bibles.forms import BibleImportRequest
 
 log = logging.getLogger(__name__)
 
@@ -286,6 +287,11 @@
         if self.import_wizard.exec_():
             self.reloadBibles()
 
+    def importRequest(self, case, name=None):
+        self.import_request = BibleImportRequest(self)
+        if self.import_request.exec_(case, name):
+            return unicode(self.import_request.requestComboBox.currentText())
+
     def loadBibles(self):
         log.debug(u'Loading Bibles')
         self.quickVersionComboBox.clear()
@@ -476,7 +482,7 @@
         self.search_results = self.parent.manager.get_verses(bible, versetext)
         if second_bible:
             self.second_search_results = self.parent.manager.get_verses(
-                second_bible, versetext)
+                second_bible, versetext, True)
         if self.advancedClearComboBox.currentIndex() == 0:
             self.listView.clear()
         if self.listView.count() != 0:
@@ -503,7 +509,7 @@
             self.search_results = self.parent.manager.get_verses(bible, text)
             if second_bible and self.search_results:
                 self.second_search_results = self.parent.manager.get_verses(
-                    second_bible, text)
+                    second_bible, text, True)
         else:
             # We are doing a 'Text Search'.
             Receiver.send_message(u'cursor_busy')

=== modified file 'openlp/plugins/bibles/lib/openlp1.py'
--- openlp/plugins/bibles/lib/openlp1.py	2011-03-04 13:57:39 +0000
+++ openlp/plugins/bibles/lib/openlp1.py	2011-03-18 10:11:29 +0000
@@ -29,7 +29,7 @@
 
 from openlp.core.lib import Receiver
 from openlp.core.ui.wizard import WizardStrings
-from openlp.plugins.bibles.lib.db import BibleDB
+from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB
 
 log = logging.getLogger(__name__)
 
@@ -43,6 +43,7 @@
         """
         log.debug(self.__class__.__name__)
         BibleDB.__init__(self, parent, **kwargs)
+        self.parent = parent
         self.filename = kwargs[u'filename']
 
     def do_import(self):
@@ -56,6 +57,15 @@
             cursor = connection.cursor()
         except:
             return False
+        #Create the bible language
+        language = self.parent.mediaItem.importRequest(u'language')
+        if not language:
+            log.exception(u'Importing books from %s   " '\
+                'failed' % self.filename)
+            return False
+        language = BiblesResourcesDB.get_language(language)
+        language_id = language[u'id']
+        self.create_meta(u'language_id', language_id)
         # Create all books.
         cursor.execute(u'SELECT id, testament_id, name, abbreviation FROM book')
         books = cursor.fetchall()
@@ -68,7 +78,14 @@
             testament_id = int(book[1])
             name = unicode(book[2], u'cp1252')
             abbreviation = unicode(book[3], u'cp1252')
-            self.create_book(name, abbreviation, testament_id)
+            book_ref_id = self.parent.manager.get_book_ref_id_by_name(name, 
+                language_id)
+            if not book_ref_id:
+                log.exception(u'Importing books from %s " '\
+                    'failed' % self.filename)
+                return False
+            book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
+            self.create_book(name, book_ref_id, book_details[u'testament_id'])
             # Update the progess bar.
             self.wizard.incrementProgressBar(WizardStrings.ImportingType % name)
             # Import the verses for this book.

=== modified file 'openlp/plugins/bibles/lib/opensong.py'
--- openlp/plugins/bibles/lib/opensong.py	2011-03-04 13:57:39 +0000
+++ openlp/plugins/bibles/lib/opensong.py	2011-03-18 10:11:29 +0000
@@ -28,7 +28,7 @@
 from lxml import objectify
 
 from openlp.core.lib import Receiver, translate
-from openlp.plugins.bibles.lib.db import BibleDB
+from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB
 
 log = logging.getLogger(__name__)
 
@@ -43,6 +43,7 @@
         """
         log.debug(self.__class__.__name__)
         BibleDB.__init__(self, parent, **kwargs)
+        self.parent = parent
         self.filename = kwargs['filename']
 
     def do_import(self):
@@ -61,11 +62,26 @@
             file = open(self.filename, u'r')
             opensong = objectify.parse(file)
             bible = opensong.getroot()
+            language = self.parent.mediaItem.importRequest(u'language')
+            if not language:
+                log.exception(u'Importing books from %s   " '\
+                    'failed' % self.filename)
+            return False
+            language = BiblesResourcesDB.get_language(language)
+            language_id = language[u'id']
+            self.create_meta(u'language_id', language_id)
             for book in bible.b:
                 if self.stop_import_flag:
                     break
-                db_book = self.create_book(unicode(book.attrib[u'n']),
-                    unicode(book.attrib[u'n'][:4]))
+                book_ref_id = self.parent.manager.get_book_ref_id_by_name(
+                    unicode(book.attrib[u'n']), language_id)
+                if not book_ref_id:
+                    log.exception(u'Importing books from %s " '\
+                        'failed' % self.filename)
+                    return False
+                book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
+                db_book = self.create_book(unicode(book.attrib[u'n']), 
+                    book_ref_id, book_details[u'testament_id'])
                 for chapter in book.c:
                     if self.stop_import_flag:
                         break

=== modified file 'openlp/plugins/bibles/lib/osis.py'
--- openlp/plugins/bibles/lib/osis.py	2011-03-04 13:57:39 +0000
+++ openlp/plugins/bibles/lib/osis.py	2011-03-18 10:11:29 +0000
@@ -33,7 +33,7 @@
 
 from openlp.core.lib import Receiver, translate
 from openlp.core.utils import AppLocation
-from openlp.plugins.bibles.lib.db import BibleDB
+from openlp.plugins.bibles.lib.db import BibleDB, BiblesResourcesDB
 
 log = logging.getLogger(__name__)
 
@@ -46,6 +46,7 @@
     def __init__(self, parent, **kwargs):
         log.debug(self.__class__.__name__)
         BibleDB.__init__(self, parent, **kwargs)
+        self.parent = parent
         self.filename = kwargs[u'filename']
         fbibles = None
         self.books = {}
@@ -104,6 +105,15 @@
         finally:
             if detect_file:
                 detect_file.close()
+        # Set meta language_id
+        language = self.parent.mediaItem.importRequest(u'language')
+        if not language:
+            log.exception(u'Importing books from %s   " '\
+                'failed' % self.filename)
+            return False
+        language = BiblesResourcesDB.get_language(language)
+        language_id = language[u'id']
+        self.create_meta(u'language_id', language_id)
         try:
             osis = codecs.open(self.filename, u'r', details['encoding'])
             for file_record in osis:
@@ -120,10 +130,17 @@
                         log.debug(u'New book: "%s"', self.books[book][0])
                         if book == u'Matt' or book == u'Jdt':
                             testament += 1
+                        book_ref_id = self.parent.manager.get_book_ref_id_by_name(
+                            unicode(self.books[book][0]), language_id)
+                        if not book_ref_id:
+                            log.exception(u'Importing books from %s " '\
+                                'failed' % self.filename)
+                            return False
+                        book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
                         db_book = self.create_book(
                             unicode(self.books[book][0]),
-                            unicode(self.books[book][1]),
-                            testament)
+                            book_ref_id,
+                            book_details[u'testament_id'])
                     if last_chapter == 0:
                         if book == u'Gen':
                             self.wizard.progressBar.setMaximum(1188)

=== removed file 'openlp/plugins/bibles/resources/biblegateway.csv'
--- openlp/plugins/bibles/resources/biblegateway.csv	2010-12-17 22:10:29 +0000
+++ openlp/plugins/bibles/resources/biblegateway.csv	1970-01-01 00:00:00 +0000
@@ -1,81 +0,0 @@
-João Ferreira de Almeida Atualizada,AA
-التفسير التطبيقى للكتاب المقدس,ALAB
-Shqip,ALB
-Amplified Bible,AMP
-Amuzgo de Guerrero,AMU
-American Standard Version,ASV
-La Bible du Semeur,BDS
-Български 1940,BG1940
-Български,BULG
-Chinanteco de Comaltepec,CCO
-Contemporary English Version,CEV
-Cakchiquel Occidental,CKW
-Hrvatski,CRO
-Castilian,CST
-聖經和合本 (简体中文),CUVS
-聖經和合本 (繁体中文),CUV
-Darby Translation,DARBY
-Dette er Biblen på dansk,DN1933
-Det Norsk Bibelselskap 1930,DNB1930
-English Standard Version,ESV
-GOD’S WORD Translation,GW
-Holman Christian Standard Bible,HCSB
-Kreyòl ayisyen bib,HCV
-Hiligaynon Bible,HLGN
-Hoffnung für Alle,HOF
-Het Boek,HTB
-Icelandic Bible,ICELAND
-Jacalteco – Oriental,JAC
-Károlyi-biblia,KAR
-Kekchi,KEK
-21st Century King James Version,KJ21
-King James Version,KJV
-La Biblia de las Américas,LBLA
-Levande Bibeln,LB
-La Parola è Vita,LM
-La Nuova Diodati,LND
-Louis Segond,LSG
-Luther Bibel 1545,LUTH1545
-Māori Bible,MAORI
-Македонски Новиот Завет,MNT
-The Message,MSG
-Mam de Comitancillo Central,MVC
-Mam de Todos Santos Cuchumatán,MVJ
-New American Standard Bible,NASB
-New Century Version,NCV
-Náhuatl de Guerrero,NGU
-New International Reader's Version,NIRV
-New International Version 1984,NIV1984
-New International Version 2010,NIV
-New International Version - UK,NIVUK
-New King James Version,NKJV
-New Living Translation,NLT
-Nádej pre kazdého,NPK
-Nueva Versión Internacional,NVI
-O Livro,OL
-Quiché – Centro Occidental,QUT
-Reimer 2001,REIMER
-Română Cornilescu,RMNN
-Новый перевод на русский язык,RUSV
-Reina-Valera Antigua,RVA
-Reina-Valera 1960,RVR1960
-Reina-Valera 1995,RVR1995
-Slovo na cestu,SNC
-Ang Salita ng Diyos,SND
-Swahili New Testament,SNT
-Svenska 1917,SV1917
-Levande Bibeln,SVL
-Создать страницу,SZ
-Traducción en lenguaje actual,TLA
-New Romanian Translation,TLCR
-Today’s New International Version 2005,TNIV
-Textus Receptus Stephanus 1550,TR1550
-Textus Receptus Scrivener 1894,TR1894
-Українська Біблія. Переклад Івана Огієнка,UKR
-Uspanteco,USP
-Kinh Thánh tiếng Việt 1934,VIET
-Worldwide English (New Testament),WE
-Codex Vaticanus Westcott-Hort 1881,WHNU
-Westminster Leningrad Codex,WLC
-Wycliffe New Testament,WYC
-Young's Literal Translation,YLT

=== added file 'openlp/plugins/bibles/resources/bibles_resources.sqlite'
Binary files openlp/plugins/bibles/resources/bibles_resources.sqlite	1970-01-01 00:00:00 +0000 and openlp/plugins/bibles/resources/bibles_resources.sqlite	2011-03-18 10:11:29 +0000 differ
=== removed file 'openlp/plugins/bibles/resources/bibleserver.csv'
--- openlp/plugins/bibles/resources/bibleserver.csv	2011-01-25 01:19:57 +0000
+++ openlp/plugins/bibles/resources/bibleserver.csv	1970-01-01 00:00:00 +0000
@@ -1,39 +0,0 @@
-عربي, ARA
-Bible – překlad 21. století, B21
-Bible du Semeur, BDS
-Българската Библия, BLG
-Český ekumenický překlad, CEP
-Hrvatski, CRO
-Священное Писание, CRS
-Version La Biblia al Dia, CST
-中文和合本(简体), CUVS
-Bibelen på hverdagsdansk, DK
-Revidierte Elberfelder, ELB
-Einheitsübersetzung, EU
-Gute Nachricht Bibel, GNB
-Hoffnung für alle, HFA
-Hungarian, HUN
-Het Boek, HTB
-La Parola è Vita, ITA
-IBS-fordítás (Új Károli), KAR
-King James Version, KJV
-Luther 1984, LUT
-Septuaginta, LXX
-Neue Genfer Ãœbersetzung, NGU
-New International Readers Version, NIRV
-New International Version, NIV
-Neues Leben, NL
-En Levende Bok (NOR), NOR
-Nádej pre kazdého, NPK
-Noua traducere în limba românã, NTR
-Nueva Versión Internacional, NVI
-הברית הישנה, OT
-Słowo Życia, POL
-O Livro, PRT
-Новый перевод на русский язык, RUS
-Slovo na cestu, SNC
-Schlachter 2000, SLT
-En Levande Bok (SWE), SVL
-Today's New International Version, TNIV
-Türkçe, TR
-Biblia Vulgata, VUL

=== removed file 'openlp/plugins/bibles/resources/crosswalkbooks.csv'
--- openlp/plugins/bibles/resources/crosswalkbooks.csv	2010-12-17 22:10:29 +0000
+++ openlp/plugins/bibles/resources/crosswalkbooks.csv	1970-01-01 00:00:00 +0000
@@ -1,27 +0,0 @@
-New American Standard,nas
-American Standard Version,asv
-English Standard Version,esv
-New King James Version,nkj
-King James Version,kjv
-Holman Christian Standard Bible,csb
-Third Millennium Bible,tmb
-New International Version,niv
-New Living Translation,nlt
-New Revised Standard,nrs
-Revised Standard Version,rsv
-Good News Translation,gnt
-Douay-Rheims Bible,rhe
-The Message,msg
-The Complete Jewish Bible,cjb
-New Century Version,ncv
-GOD'S WORD Translation,gwd
-Hebrew Names Version,hnv
-World English Bible,web
-The Bible in Basic English,bbe
-Young's Literal Translation,ylt
-Today's New International Version,tnv
-New International Reader's Version,nrv
-The Darby Translation,dby
-The Webster Bible,wbt
-The Latin Vulgate,vul
-Weymouth New Testament,wnt

=== removed file 'openlp/plugins/bibles/resources/httpbooks.sqlite'
Binary files openlp/plugins/bibles/resources/httpbooks.sqlite	2011-01-22 17:35:02 +0000 and openlp/plugins/bibles/resources/httpbooks.sqlite	1970-01-01 00:00:00 +0000 differ
=== added file 'resources/forms/bibleimportrequestdialog.ui'
--- resources/forms/bibleimportrequestdialog.ui	1970-01-01 00:00:00 +0000
+++ resources/forms/bibleimportrequestdialog.ui	2011-03-18 10:11:29 +0000
@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>BibleImportRequest</class>
+ <widget class="QDialog" name="BibleImportRequest">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>175</height>
+   </rect>
+  </property>
+  <property name="sizePolicy">
+   <sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <widget class="QWidget" name="">
+   <property name="geometry">
+    <rect>
+     <x>10</x>
+     <y>15</y>
+     <width>381</width>
+     <height>151</height>
+    </rect>
+   </property>
+   <layout class="QVBoxLayout" name="verticalLayout">
+    <item>
+     <widget class="QLabel" name="HeadlineLabel">
+      <property name="font">
+       <font>
+        <family>Arial</family>
+        <pointsize>12</pointsize>
+        <weight>75</weight>
+        <bold>true</bold>
+       </font>
+      </property>
+      <property name="text">
+       <string>Choose Book:</string>
+      </property>
+     </widget>
+    </item>
+    <item>
+     <widget class="QLabel" name="InfoLabel">
+      <property name="text">
+       <string>The following books cannot be clearly attributed. 
+Please choose the book it is.</string>
+      </property>
+     </widget>
+    </item>
+    <item>
+     <layout class="QFormLayout" name="formLayout">
+      <item row="0" column="0">
+       <widget class="QLabel" name="RequestLabel">
+        <property name="text">
+         <string>Book:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="0" column="1">
+       <widget class="QComboBox" name="RequestComboBox">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </item>
+    <item>
+     <spacer name="verticalSpacer">
+      <property name="orientation">
+       <enum>Qt::Vertical</enum>
+      </property>
+      <property name="sizeHint" stdset="0">
+       <size>
+        <width>20</width>
+        <height>40</height>
+       </size>
+      </property>
+     </spacer>
+    </item>
+    <item>
+     <widget class="QDialogButtonBox" name="BibleImportRequestButtonBox">
+      <property name="orientation">
+       <enum>Qt::Horizontal</enum>
+      </property>
+      <property name="standardButtons">
+       <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+      </property>
+     </widget>
+    </item>
+   </layout>
+  </widget>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>BibleImportRequestButtonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>BibleImportRequest</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>BibleImportRequestButtonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>BibleImportRequest</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>


Follow ups