From 57fa6715389f3ccf69d38bff2af4c0bb45b97c84 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Tue, 20 Jan 2009 19:50:37 +0000 Subject: [PATCH] Big bible cleanup! bzr-revno: 286 --- openlp/plugins/bibles/bibleplugin.py | 15 +- openlp/plugins/bibles/lib/__init__.py | 4 +- openlp/plugins/bibles/lib/bibleCSVimpl.py | 5 +- openlp/plugins/bibles/lib/bibleDBimpl.py | 212 +++++++----------- openlp/plugins/bibles/lib/bibleHTTPimpl.py | 2 +- openlp/plugins/bibles/lib/bibleOSISimpl.py | 7 +- openlp/plugins/bibles/lib/classes.py | 67 ++++++ .../bibles/lib/{biblecommon.py => common.py} | 0 .../lib/{biblemanager.py => manager.py} | 30 +-- openlp/plugins/bibles/lib/tables.py | 52 +++++ 10 files changed, 216 insertions(+), 178 deletions(-) create mode 100644 openlp/plugins/bibles/lib/classes.py rename openlp/plugins/bibles/lib/{biblecommon.py => common.py} (100%) rename openlp/plugins/bibles/lib/{biblemanager.py => manager.py} (90%) create mode 100644 openlp/plugins/bibles/lib/tables.py diff --git a/openlp/plugins/bibles/bibleplugin.py b/openlp/plugins/bibles/bibleplugin.py index 6a309f18d..972b2e63d 100644 --- a/openlp/plugins/bibles/bibleplugin.py +++ b/openlp/plugins/bibles/bibleplugin.py @@ -24,9 +24,13 @@ from PyQt4 import QtCore, QtGui from openlp.core.resources import * from openlp.core.lib import Plugin,PluginUtils, MediaManagerItem + from openlp.plugins.bibles.lib import BibleManager from openlp.plugins.bibles.forms import BibleImportForm +from openlp.plugins.bibles.lib.tables import * +from openlp.plugins.bibles.lib.classes import * + class BiblePlugin(Plugin, PluginUtils): global log log=logging.getLogger("BiblePlugin") @@ -234,7 +238,7 @@ class BiblePlugin(Plugin, PluginUtils): pass def onBibleNewClick(self): - self.bibleimportform = BibleImportForm(self.biblemanager) + self.bibleimportform = BibleImportForm(self.config, self.biblemanager) self.bibleimportform.setModal(True) self.bibleimportform.show() pass @@ -258,7 +262,7 @@ class BiblePlugin(Plugin, PluginUtils): bibles = self.biblemanager.get_bibles("partial") # Without HTTP first = True for b in bibles: # load bibles into the combo boxes - self.AdvancedVersionComboBox.addItem(b) + self.AdvancedVersionComboBox.addItem(b) if first: first = False self._initialise_bible_advanced(b) # use the first bible as the trigger @@ -272,12 +276,11 @@ class BiblePlugin(Plugin, PluginUtils): books = self.biblemanager.get_bible_books(str(self.AdvancedVersionComboBox.currentText())) self.AdvancedBookComboBox.clear() first = True - for b in books: - self.AdvancedBookComboBox.addItem(b[0]) + for book in books: + self.AdvancedBookComboBox.addItem(book.name) if first: - book = b first = False - self._initialise_chapter_verse(bible, b[0]) + self._initialise_chapter_verse(bible, book.name) def _initialise_chapter_verse(self, bible, book): log.debug("_initialise_chapter_verse %s , %s", bible, book) diff --git a/openlp/plugins/bibles/lib/__init__.py b/openlp/plugins/bibles/lib/__init__.py index 2c5856080..ad6a0c0b3 100644 --- a/openlp/plugins/bibles/lib/__init__.py +++ b/openlp/plugins/bibles/lib/__init__.py @@ -18,7 +18,7 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA """ -from biblecommon import BibleCommon -from biblemanager import BibleManager +from common import BibleCommon +from manager import BibleManager __all__ = ['BibleCommon', 'BibleManager'] diff --git a/openlp/plugins/bibles/lib/bibleCSVimpl.py b/openlp/plugins/bibles/lib/bibleCSVimpl.py index 2c6aab305..8b1a0f39c 100644 --- a/openlp/plugins/bibles/lib/bibleCSVimpl.py +++ b/openlp/plugins/bibles/lib/bibleCSVimpl.py @@ -19,10 +19,9 @@ import os, os.path import sys import urllib2 -#mypath=os.path.split(os.path.abspath(__file__))[0] -#sys.path.insert(0,(os.path.join(mypath, '..', '..', '..'))) + from openlp.plugins.bibles.lib.bibleDBimpl import BibleDBImpl -from openlp.plugins.bibles.lib.biblecommon import BibleCommon +from openlp.plugins.bibles.lib.common import BibleCommon import logging diff --git a/openlp/plugins/bibles/lib/bibleDBimpl.py b/openlp/plugins/bibles/lib/bibleDBimpl.py index c07a468a6..0fdcd3efa 100644 --- a/openlp/plugins/bibles/lib/bibleDBimpl.py +++ b/openlp/plugins/bibles/lib/bibleDBimpl.py @@ -24,183 +24,129 @@ import string from sqlalchemy import * from sqlalchemy.sql import select -from sqlalchemy.orm import sessionmaker, mapper +from sqlalchemy.orm import sessionmaker, mapper, scoped_session -from openlp.plugins.bibles.lib.biblecommon import BibleCommon +from openlp.plugins.bibles.lib.tables import * +from openlp.plugins.bibles.lib.classes import * + +from common import BibleCommon from openlp.core.utils import ConfigHelper import logging -class BibleDBException(Exception): - pass -class BibleInvalidDatabaseError(Exception): - pass - -metadata = MetaData() -#Define the tables and indexes -meta_table = Table('metadata', metadata, - Column('key', String(255), primary_key=True), - Column('value', String(255)), -) - -testament_table = Table('testament', metadata, - Column('id', Integer, primary_key=True), - Column('name', String(30)), -) - -book_table = Table('book', metadata, - Column('id', Integer, primary_key=True), - Column('testament_id', Integer), - Column('name', String(30)), - Column('abbrev', String(5)), -) -Index('idx_name', book_table.c.name, book_table.c.id) -Index('idx_abbrev', book_table.c.abbrev, book_table.c.id) - -#Column('book_id', None, ForeignKey('book.id')), -verse_table = Table('verse', metadata, - Column('id', Integer, primary_key=True), - Column('book_id', Integer ), - Column('chapter', Integer), - Column('verse', Integer), - Column('text', Text), -) -Index('idx_chapter_verse_book', verse_table.c.chapter, verse_table.c.verse, verse_table.c.book_id, verse_table.c.id) -Index('idx_chapter_verse_text', verse_table.c.text, verse_table.c.verse, verse_table.c.book_id, verse_table.c.id) - -class BibleMeta(object): - def __init__(self, key, value): - self.key = key - self.value =value - - def __repr__(self): - return "" %(self.key, self.value) - -class ONTestament(object): - def __init__(self, name): - self.name = name - - def __repr__(self): - return "" %(self.name) - -class Book(object): - def __init__(self, testament_id, name, abbrev): - self.testament_id = testament_id - self.name = name - self.abbrev = abbrev - - def __repr__(self): - return "" %(self.id, self.testament_id, self.name, self.abbrev) - -class Verse(object): - def __init__(self, book_id, chapter, verse, text): - self.book_id = book_id - self.chapter = chapter - self.verse = verse - self.text = text - - def __repr__(self): - return "" %(self.book_id, self.chapter, self.verse, self.text) - -mapper(BibleMeta, meta_table) -mapper(ONTestament, testament_table) -mapper(Book, book_table) -mapper(Verse, verse_table) - class BibleDBImpl(BibleCommon): global log log=logging.getLogger("BibleDBImpl") - log.info("BibleDBimpl loaded") - def __init__(self, biblepath , biblename, suffix, btype = 'sqlite'): - # Connect to database - self.biblefile = os.path.join(biblepath, biblename+"."+suffix) + log.info("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( "Load bible %s on path %s", biblename, self.biblefile) - if btype == 'sqlite': + db_type = self.config.get_config(u'db type') + db_type = u'sqlite' + if db_type == u'sqlite': self.db = create_engine("sqlite:///"+self.biblefile) - elif btype == 'mysql': - self.db = create_engine("mysql://tim:@192.168.0.100:3306/openlp_rsv_bible") else: - raise BibleInvalidDatabaseError("Database not mysql or sqlite") + self.db_url = db_type + 'u://' + \ + self.config.get_config(u'db username') + u':' + \ + self.config.get_config(u'db password') + u'@' + \ + self.config.get_config(u'db hostname') + u'/' + \ + self.config.get_config(u'db database') self.db.echo = False - #self.metadata = metaData() metadata.bind = self.db metadata.bind.echo = False - self.Session = sessionmaker() - self.Session.configure(bind=self.db) + self.session = scoped_session(sessionmaker(autoflush=True, autocommit=False)) + self.session.configure(bind=self.db) + metadata.create_all(self.db) def create_tables(self): log.debug( "createTables") if os.path.exists(self.biblefile): # delete bible file and set it up again os.remove(self.biblefile) - meta_table.create() - testament_table.create() - book_table.create() - verse_table.create() + #meta_table.create() + #testament_table.create() + #book_table.create() + #verse_table.create() self.save_meta("dbversion", "2") self._load_testaments() - def add_verse(self, bookid, chap, verse, text): - log.debug( "add_verse %s,%s,%s,%s", bookid, chap, verse, text) + def add_verse(self, bookid, chap, vse, text): + log.debug( "add_verse %s,%s,%s,%s", bookid, chap, vse, text) metadata.bind.echo = False - session = self.Session() - versemeta = Verse(book_id=int(bookid), chapter=int(chap), verse=int(verse), text=(text)) - session.add(versemeta) + session = self.session() + verse = Verse() + verse.book_id = bookid + verse.chapter = chap + verse.verse = vse + verse.text = text + session.add(verse) session.commit() def create_chapter(self, bookid, chap, textlist): log.debug( "create_chapter %s,%s,%s", bookid, chap, textlist) metadata.bind.echo = False - session = self.Session() - #s = text (""" select id FROM book where book.name == :b """) - #data = self.db.execute(s, b=bookname).fetchone() - #id = data[0] # id is first record in list. - #log.debug( "id = " , id + session = self.session() for v , t in textlist.iteritems(): - versemeta = Verse(book_id=bookid, chapter=int(chap), verse=int(v), text=(t)) - session.add(versemeta) + verse = Verse() + verse.book_id = bookid + verse.chapter = chap + verse.verse = v + verse.text = t + session.add(verse) session.commit() def create_book(self, bookid, bookname, bookabbrev): log.debug( "create_book %s,%s,%s", bookid, bookname, bookabbrev) metadata.bind.echo = False - session = self.Session() - bookmeta = Book(int(5), bookname, bookabbrev) - session.add(bookmeta) + session = self.session() + book = Book() + book.tetsament_id = 1 + book.name = bookname + book.abbreviation = bookabbrev + session.add(book) session.commit() + return book.id def save_meta(self, key, value): metadata.bind.echo = False - session = self.Session() - bmeta= BibleMeta(key, value) + session = self.session() + bmeta= BibleMeta() + bmeta.key = key + bmeta.value = value session.add(bmeta) session.commit() - def get_meta(self, key): - s = text (""" select value FROM metadata where key == :k """) - return self.db.execute(s, k=key).fetchone() + def get_meta(self, metakey): + log.debug( "get meta %s", metakey) + return self.session.query(BibleMeta).filter_by(key = metakey).first() - def delete_meta(self, key): - metadata.bind.echo = False - s = text (""" delete FROM meta where key == :k """) - self.db.execute(s, k=key) + def delete_meta(self, metakey): + biblemeta = self.get_meta(metakey) + try: + session.delete(biblemeta) + session.commit() + return True + except: + return False def _load_testaments(self): log.debug("load_testaments") metadata.bind.echo = False - session = self.Session() - testmeta = ONTestament(name="Old Testament") - session.add(testmeta) - testmeta = ONTestament(name="New Testament") - session.add(testmeta) - testmeta = ONTestament(name="Apocrypha") - session.add(testmeta) + session = self.session() + test = ONTestament() + test.name = "Old Testament" + session.add(test) + test.name = "New Testament" + session.add(test) + test.name = "Apocrypha" + session.add(test) session.commit() def get_bible_books(self): - log.debug( "get_bible_book ") - metadata.bind.echo = False - s = text (""" select name FROM book order by id """) - return self.db.execute(s).fetchall() + log.debug( "get_bible_books ") + return self.session.query(Book).order_by(Book.id).all() def get_max_bible_book_verses(self, bookname, chapter): log.debug( "get_max_bible_book_verses %s,%s ", bookname , chapter) @@ -216,15 +162,7 @@ class BibleDBImpl(BibleCommon): def get_bible_book(self, bookname): log.debug( "get_bible_book %s", bookname) - metadata.bind.echo = False - s = text (""" select name FROM book where book.name == :b """) - return self.db.execute(s, b=bookname).fetchone() - - def get_bible_book_Id(self, bookname): - log.debug( "get_bible_book_id %s", bookname) - metadata.bind.echo = False - s = text (""" select id FROM book where book.name == :b """) - return self.db.execute(s, b=bookname).fetchone() + return self.session.query(Book).filter_by(name = bookname).first() def get_bible_chapter(self, bookname, chapter): log.debug( "get_bible_chapter %s,%s", bookname, chapter ) diff --git a/openlp/plugins/bibles/lib/bibleHTTPimpl.py b/openlp/plugins/bibles/lib/bibleHTTPimpl.py index b6342ce00..4245986a0 100644 --- a/openlp/plugins/bibles/lib/bibleHTTPimpl.py +++ b/openlp/plugins/bibles/lib/bibleHTTPimpl.py @@ -20,7 +20,7 @@ import os, os.path import sys import urllib2 -from biblecommon import BibleCommon +from common import BibleCommon import logging diff --git a/openlp/plugins/bibles/lib/bibleOSISimpl.py b/openlp/plugins/bibles/lib/bibleOSISimpl.py index 8ff712a3b..0accfb9dc 100644 --- a/openlp/plugins/bibles/lib/bibleOSISimpl.py +++ b/openlp/plugins/bibles/lib/bibleOSISimpl.py @@ -19,8 +19,6 @@ import os, os.path import sys import urllib2 -#mypath=os.path.split(os.path.abspath(__file__))[0] -#sys.path.insert(0,(os.path.join(mypath, '..', '..', '..'))) from openlp.plugins.bibles.lib.bibleDBimpl import BibleDBImpl import logging @@ -86,10 +84,9 @@ class BibleOSISImpl(): p = ref.split(".", 3) # split u[ the reference if book_ptr != p[0]: book_ptr = p[0] - self.bibledb.create_book(int(p[1]), self.booksOfBible[p[0]] , self.abbrevOfBible[p[0]]) - id = self.bibledb.get_bible_book_id(self.booksOfBible[p[0]]) + id = self.bibledb.create_book(int(p[1]), self.booksOfBible[p[0]] , self.abbrevOfBible[p[0]]) dialogobject.incrementBar() - self.bibledb.add_verse(id[0], p[1], p[2], t) + self.bibledb.add_verse(id, p[1], p[2], t) diff --git a/openlp/plugins/bibles/lib/classes.py b/openlp/plugins/bibles/lib/classes.py new file mode 100644 index 000000000..6b6048faa --- /dev/null +++ b/openlp/plugins/bibles/lib/classes.py @@ -0,0 +1,67 @@ +# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 +""" +OpenLP - Open Source Lyrics Projection +Copyright (c) 2008 Raoul Snyman +Portions copyright (c) 2008 Martin Thompson, Tim Bentley, + +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 sqlalchemy.orm import mapper, relation +from openlp.plugins.bibles.lib.tables import * + +class BaseModel(object): + """ + BaseModel provides a base object with a set of generic functions + """ + + @classmethod + def populate(cls, **kwargs): + """ + Creates an instance of a class and populates it, returning the instance + """ + me = cls() + keys = kwargs.keys() + for key in keys: + me.__setattr__(key, kwargs[key]) + return me + +class BibleMeta(BaseModel): + """ + Bible Meta Data + """ + pass + +class ONTestament(BaseModel): + """ + Bible Testaments + """ + pass + +class Book(BaseModel): + """ + Song model + """ + pass + +class Verse(BaseModel): + """ + Topic model + """ + pass + +mapper(BibleMeta, meta_table) +mapper(ONTestament, testament_table, + properties={'books': relation(Book, backref='testament')}) +mapper(Book, book_table, + properties={'verses': relation(Verse, backref='book')}) +mapper(Verse, verse_table) diff --git a/openlp/plugins/bibles/lib/biblecommon.py b/openlp/plugins/bibles/lib/common.py similarity index 100% rename from openlp/plugins/bibles/lib/biblecommon.py rename to openlp/plugins/bibles/lib/common.py diff --git a/openlp/plugins/bibles/lib/biblemanager.py b/openlp/plugins/bibles/lib/manager.py similarity index 90% rename from openlp/plugins/bibles/lib/biblemanager.py rename to openlp/plugins/bibles/lib/manager.py index 0d78a9fee..0ec37411a 100644 --- a/openlp/plugins/bibles/lib/biblemanager.py +++ b/openlp/plugins/bibles/lib/manager.py @@ -25,6 +25,8 @@ from bibleOSISimpl import BibleOSISImpl from bibleCSVimpl import BibleCSVImpl from bibleDBimpl import BibleDBImpl from bibleHTTPimpl import BibleHTTPImpl +from openlp.plugins.bibles.lib.tables import * +from openlp.plugins.bibles.lib.classes import * import logging @@ -55,7 +57,7 @@ class BibleManager(): for f in files: nme = f.split('.') bname = nme[0] - self.bibleDBCache[bname] = BibleDBImpl(self.biblePath, bname, self.bibleSuffix) + self.bibleDBCache[bname] = BibleDBImpl(self.biblePath, bname, self.config) biblesource = self.bibleDBCache[bname].get_meta("WEB") # look to see if lazy load bible exists and get create getter. if biblesource: nhttp = BibleHTTPImpl() @@ -79,7 +81,7 @@ class BibleManager(): """ log.debug( "register_HTTP_bible %s,%s,%s,%s,%s", biblename, biblesource, proxyurl, proxyid, proxypass, mode) if self._is_new_bible(biblename): - nbible = BibleDBImpl(self.biblePath, biblename, self.bibleSuffix) # Create new Bible + nbible = BibleDBImpl(self.biblePath, biblename, self.config) # Create new Bible nbible.create_tables() # Create Database self.bibleDBCache[biblename] = nbible @@ -103,7 +105,7 @@ class BibleManager(): from scratch. """ if self._is_new_bible(biblename): - nbible = BibleDBImpl(self.biblePath, biblename, self.bibleSuffix) # Create new Bible + nbible = BibleDBImpl(self.biblePath, biblename, self.config) # Create new Bible nbible.create_tables() # Create Database self.bibleDBCache[biblename] = nbible # cache the database for use later bcsv = BibleCSVImpl(nbible) # create the loader and pass in the database @@ -117,32 +119,12 @@ class BibleManager(): """ log.debug( "register_OSIS_file_bible %s , %s", biblename, osisfile) if self._is_new_bible(biblename): - nbible = BibleDBImpl(self.biblePath, biblename, self.bibleSuffix) # Create new Bible + nbible = BibleDBImpl(self.biblePath, biblename, self.config) # Create new Bible nbible.create_tables() # Create Database self.bibleDBCache[biblename] = nbible # cache the database for use later bcsv = BibleOSISImpl(self.biblePath, nbible) # create the loader and pass in the database bcsv.load_data(osisfile, self.dialogobject) - -# def loadBible(self,biblename): -# """ -# Downloads all the books of the bible -# and loads it into the database -# """ -# log.debug( "loadBible %s", biblename) -# bookabbrev = "" -# for bookname in self.listOfBooks: -# cptrs = self.booksChapters[ self.booksOfBible[bookname]] -# log.debug( "book and chapter %s %s", bookname , self.booksChapters[ self.booksOfBible[bookname]] ) -# for chptr in range(1 , int(cptrs)): # loop through all the chapters in book -# c = self.bibleDBCache[biblename].getBibleChapter(bookname, chptr) # check to see if book/chapter exists -# log.debug( "got chapter %s", c) -# if not c: -# bookid = self.booksOfBible[bookname] # convert to id ie Genesis --> 1 Revelation --> 73 -# log.debug( "missing %s,%s", bookname, chptr) -# self._loadBook(biblename,bookid, bookname, bookabbrev) -# self._loadChapter(biblename,bookid, bookname, chptr) - def get_bibles(self, mode="full"): """ Returns a list of Books of the bible diff --git a/openlp/plugins/bibles/lib/tables.py b/openlp/plugins/bibles/lib/tables.py new file mode 100644 index 000000000..4981ce57d --- /dev/null +++ b/openlp/plugins/bibles/lib/tables.py @@ -0,0 +1,52 @@ +# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 +""" +OpenLP - Open Source Lyrics Projection +Copyright (c) 2008 Raoul Snyman +Portions copyright (c) 2008 Martin Thompson, Tim Bentley, + +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 string +from sqlalchemy import * +from sqlalchemy import Column, Table, MetaData, ForeignKey, schema + +metadata = MetaData() +#Define the tables and indexes +meta_table = Table('metadata', metadata, + Column('key', String(255), primary_key=True), + Column('value', String(255)), +) + +testament_table = Table('testament', metadata, + Column('id', Integer, primary_key=True), + Column('name', String(30)), +) + +book_table = Table('book', metadata, + Column('id', Integer, primary_key=True), + Column('testament_id', Integer, schema.ForeignKey('testament.id')), + Column('name', String(30)), + Column('abbreviation', String(5)), +) +Index('idx_name', book_table.c.name, book_table.c.id) +Index('idx_abbrev', book_table.c.abbreviation, book_table.c.id) + +verse_table = Table('verse', metadata, + Column('id', Integer, primary_key=True), + Column('book_id', Integer , schema.ForeignKey('book.id')), + Column('chapter', Integer), + Column('verse', Integer), + Column('text', Text), +) +Index('idx_chapter_verse_book', verse_table.c.chapter, verse_table.c.verse, verse_table.c.book_id, verse_table.c.id) +Index('idx_chapter_verse_text', verse_table.c.text, verse_table.c.verse, verse_table.c.book_id, verse_table.c.id)