2009-09-08 19:58:05 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
|
|
|
|
|
|
|
###############################################################################
|
|
|
|
# OpenLP - Open Source Lyrics Projection #
|
|
|
|
# --------------------------------------------------------------------------- #
|
2009-12-31 12:52:01 +00:00
|
|
|
# Copyright (c) 2008-2010 Raoul Snyman #
|
|
|
|
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
|
2009-11-30 20:29:26 +00:00
|
|
|
# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, #
|
|
|
|
# Carsten Tinggaard #
|
2009-09-08 19:58:05 +00:00
|
|
|
# --------------------------------------------------------------------------- #
|
|
|
|
# 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 #
|
|
|
|
###############################################################################
|
2008-10-30 20:44:54 +00:00
|
|
|
|
2009-09-25 00:43:42 +00:00
|
|
|
import logging
|
2010-01-24 07:08:14 +00:00
|
|
|
import urllib2
|
|
|
|
|
|
|
|
from BeautifulSoup import BeautifulSoup
|
2008-10-30 20:44:54 +00:00
|
|
|
|
2010-01-29 21:26:24 +00:00
|
|
|
from openlp.core.lib import Receiver
|
2009-02-24 20:24:01 +00:00
|
|
|
from common import BibleCommon, SearchResults
|
2009-12-30 17:29:08 +00:00
|
|
|
from db import BibleDB
|
2010-01-24 07:08:14 +00:00
|
|
|
from openlp.plugins.bibles.lib.models import Book
|
2008-11-09 20:11:31 +00:00
|
|
|
|
2008-11-16 07:40:46 +00:00
|
|
|
class BGExtract(BibleCommon):
|
2009-06-16 18:21:24 +00:00
|
|
|
global log
|
2009-09-28 17:45:14 +00:00
|
|
|
log = logging.getLogger(u'BibleHTTPMgr(BG_extract)')
|
2009-06-16 18:21:24 +00:00
|
|
|
log.info(u'BG_extract loaded')
|
|
|
|
|
2009-12-30 17:29:08 +00:00
|
|
|
def __init__(self, proxyurl=None):
|
2009-06-16 18:21:24 +00:00
|
|
|
log.debug(u'init %s', proxyurl)
|
2008-11-16 07:40:46 +00:00
|
|
|
self.proxyurl = proxyurl
|
2009-06-16 18:21:24 +00:00
|
|
|
|
2009-12-30 17:29:08 +00:00
|
|
|
def get_chapter(self, version, bookname, chapter) :
|
2008-11-09 20:11:31 +00:00
|
|
|
"""
|
|
|
|
Access and decode bibles via the BibleGateway website
|
2009-09-21 17:56:36 +00:00
|
|
|
|
|
|
|
``Version``
|
|
|
|
The version of the bible like 31 for New International version
|
|
|
|
|
|
|
|
``bookname``
|
2009-10-26 16:19:26 +00:00
|
|
|
Name of the Book
|
2009-09-21 17:56:36 +00:00
|
|
|
|
|
|
|
``chapter``
|
|
|
|
Chapter number
|
2008-11-09 20:11:31 +00:00
|
|
|
"""
|
2009-12-30 17:29:08 +00:00
|
|
|
log.debug(u'get_bible_chapter %s, %s, %s', version, bookname, chapter)
|
2010-01-24 07:08:14 +00:00
|
|
|
urlstring = u'http://www.biblegateway.com/passage/?search=%s+%s' \
|
2009-12-30 17:29:08 +00:00
|
|
|
u'&version=%s' % (bookname, chapter, version)
|
|
|
|
log.debug(u'BibleGateway url = %s' % urlstring)
|
2008-12-16 17:29:39 +00:00
|
|
|
xml_string = self._get_web_text(urlstring, self.proxyurl)
|
2009-10-27 16:55:09 +00:00
|
|
|
verseSearch = u'<sup class=\"versenum'
|
|
|
|
verseFootnote = u'<sup class=\'footnote'
|
2008-11-09 20:11:31 +00:00
|
|
|
verse = 1
|
2009-10-27 07:20:01 +00:00
|
|
|
i = xml_string.find(u'result-text-style-normal') + 26
|
2008-11-09 20:11:31 +00:00
|
|
|
xml_string = xml_string[i:len(xml_string)]
|
2009-10-27 07:20:01 +00:00
|
|
|
versePos = xml_string.find(verseSearch)
|
2008-11-09 20:11:31 +00:00
|
|
|
bible = {}
|
2008-11-13 20:51:37 +00:00
|
|
|
while versePos > -1:
|
2009-09-26 18:22:10 +00:00
|
|
|
# clear out string
|
2009-09-28 17:45:14 +00:00
|
|
|
verseText = u''
|
2009-10-27 07:20:01 +00:00
|
|
|
versePos = xml_string.find(u'</sup>', versePos) + 6
|
|
|
|
i = xml_string.find(verseSearch, versePos + 1)
|
2009-10-27 20:52:30 +00:00
|
|
|
# Not sure if this is needed now
|
2008-11-09 20:11:31 +00:00
|
|
|
if i == -1:
|
2009-10-27 07:20:01 +00:00
|
|
|
i = xml_string.find(u'</div', versePos + 1)
|
|
|
|
j = xml_string.find(u'<strong', versePos + 1)
|
2008-11-09 20:11:31 +00:00
|
|
|
if j > 0 and j < i:
|
|
|
|
i = j
|
2009-06-16 18:21:24 +00:00
|
|
|
verseText = xml_string[versePos + 7 : i ]
|
2009-10-27 20:52:30 +00:00
|
|
|
# store the verse
|
|
|
|
bible[verse] = self._clean_text(verseText)
|
2008-11-13 20:51:37 +00:00
|
|
|
versePos = -1
|
2008-11-09 20:11:31 +00:00
|
|
|
else:
|
2009-10-27 07:20:01 +00:00
|
|
|
verseText = xml_string[versePos: i]
|
2009-10-27 16:55:09 +00:00
|
|
|
start_tag = verseText.find(verseFootnote)
|
|
|
|
while start_tag > -1:
|
|
|
|
end_tag = verseText.find(u'</sup>')
|
|
|
|
verseText = verseText[:start_tag] + verseText[end_tag + 6:len(verseText)]
|
|
|
|
start_tag = verseText.find(verseFootnote)
|
2009-10-27 07:20:01 +00:00
|
|
|
# Chop off verse and start again
|
|
|
|
xml_string = xml_string[i:]
|
2009-10-27 20:52:30 +00:00
|
|
|
#look for the next verse
|
|
|
|
versePos = xml_string.find(verseSearch)
|
|
|
|
# store the verse
|
|
|
|
bible[verse] = self._clean_text(verseText)
|
2008-11-09 20:11:31 +00:00
|
|
|
verse += 1
|
2009-10-27 07:20:01 +00:00
|
|
|
return SearchResults(bookname, chapter, bible)
|
2009-06-16 18:21:24 +00:00
|
|
|
|
2008-11-16 07:40:46 +00:00
|
|
|
class CWExtract(BibleCommon):
|
2010-01-24 07:08:14 +00:00
|
|
|
log.info(u'%s loaded', __name__)
|
2009-06-16 18:21:24 +00:00
|
|
|
|
2008-11-16 07:40:46 +00:00
|
|
|
def __init__(self, proxyurl=None):
|
2009-06-16 18:21:24 +00:00
|
|
|
log.debug(u'init %s', proxyurl)
|
2008-11-16 07:40:46 +00:00
|
|
|
self.proxyurl = proxyurl
|
2009-06-16 18:21:24 +00:00
|
|
|
|
2010-01-24 07:08:14 +00:00
|
|
|
def get_bible_chapter(self, version, bookname, chapter):
|
|
|
|
log.debug(u'%s %s, %s, %s', __name__, version, bookname, chapter)
|
2008-11-09 20:11:31 +00:00
|
|
|
"""
|
2008-12-06 19:34:48 +00:00
|
|
|
Access and decode bibles via the Crosswalk website
|
2009-09-21 17:56:36 +00:00
|
|
|
|
|
|
|
``version``
|
|
|
|
The version of the bible like niv for New International Version
|
|
|
|
|
|
|
|
``bookname``
|
|
|
|
Text name of in english e.g. 'gen' for Genesis
|
|
|
|
|
|
|
|
``chapter``
|
|
|
|
Chapter number
|
2009-06-16 18:21:24 +00:00
|
|
|
"""
|
2009-10-27 07:20:01 +00:00
|
|
|
log.debug(u'get_bible_chapter %s,%s,%s',
|
|
|
|
version, bookname, chapter)
|
2009-08-02 13:44:41 +00:00
|
|
|
bookname = bookname.replace(u' ', u'')
|
2010-01-24 07:08:14 +00:00
|
|
|
page = urllib2.urlopen(u'http://www.biblestudytools.com/%s/%s/%s.html' % \
|
|
|
|
(version, bookname.lower(), chapter))
|
|
|
|
soup = BeautifulSoup(page)
|
|
|
|
htmlverses = soup.findAll(u'span', u'versetext')
|
|
|
|
verses = {}
|
|
|
|
for verse in htmlverses:
|
2010-01-29 21:35:02 +00:00
|
|
|
Receiver.send_message(u'process_events')
|
2010-01-24 07:08:14 +00:00
|
|
|
versenumber = int(verse.contents[0].contents[0])
|
|
|
|
versetext = u''
|
|
|
|
for part in verse.contents:
|
|
|
|
if str(part)[0] != u'<':
|
|
|
|
versetext = versetext + part
|
|
|
|
versetext = versetext.strip(u'\n\r\t ')
|
|
|
|
verses[versenumber] = versetext
|
|
|
|
return SearchResults(bookname, chapter, verses)
|
|
|
|
|
2009-06-16 18:21:24 +00:00
|
|
|
|
2009-12-30 17:29:08 +00:00
|
|
|
class HTTPBible(BibleDB):
|
2010-01-24 07:08:14 +00:00
|
|
|
log.info(u'%s loaded', __name__)
|
2009-12-30 17:29:08 +00:00
|
|
|
|
|
|
|
def __init__(self, **kwargs):
|
2008-11-16 07:40:46 +00:00
|
|
|
"""
|
|
|
|
Finds all the bibles defined for the system
|
2009-09-21 17:56:36 +00:00
|
|
|
Creates an Interface Object for each bible containing connection
|
|
|
|
information
|
|
|
|
|
2008-11-16 07:40:46 +00:00
|
|
|
Throws Exception if no Bibles are found.
|
|
|
|
|
|
|
|
Init confirms the bible exists and stores the database path.
|
|
|
|
"""
|
2010-01-24 07:08:14 +00:00
|
|
|
BibleDB.__init__(self, **kwargs)
|
2009-12-30 17:29:08 +00:00
|
|
|
if u'download_source' not in kwargs:
|
|
|
|
raise KeyError(u'Missing keyword argument "download_source"')
|
|
|
|
if u'download_name' not in kwargs:
|
|
|
|
raise KeyError(u'Missing keyword argument "download_name"')
|
|
|
|
self.download_source = kwargs[u'download_source']
|
|
|
|
self.download_name = kwargs[u'download_name']
|
|
|
|
if u'proxy_server' in kwargs:
|
|
|
|
self.proxy_server = kwargs[u'proxy_server']
|
|
|
|
else:
|
|
|
|
self.proxy_server = None
|
|
|
|
if u'proxy_username' in kwargs:
|
|
|
|
self.proxy_username = kwargs[u'proxy_username']
|
|
|
|
else:
|
|
|
|
self.proxy_username = None
|
|
|
|
if u'proxy_password' in kwargs:
|
|
|
|
self.proxy_password = kwargs[u'proxy_password']
|
|
|
|
else:
|
|
|
|
self.proxy_password = None
|
|
|
|
|
2010-01-24 07:08:14 +00:00
|
|
|
def do_import(self):
|
|
|
|
self.wizard.ImportProgressBar.setMaximum(2)
|
|
|
|
self.wizard.incrementProgressBar('Registering bible...')
|
2009-12-30 17:29:08 +00:00
|
|
|
self.create_meta(u'download source', self.download_source)
|
|
|
|
self.create_meta(u'download name', self.download_name)
|
|
|
|
if self.proxy_server:
|
|
|
|
self.create_meta(u'proxy server', self.proxy_server)
|
|
|
|
if self.proxy_username:
|
|
|
|
# store the proxy userid
|
|
|
|
self.create_meta(u'proxy username', self.proxy_username)
|
|
|
|
if self.proxy_password:
|
|
|
|
# store the proxy password
|
|
|
|
self.create_meta(u'proxy password', self.proxy_password)
|
2010-01-24 07:08:14 +00:00
|
|
|
self.wizard.incrementProgressBar('Registered.')
|
|
|
|
return True
|
2009-12-30 17:29:08 +00:00
|
|
|
|
2010-01-24 07:08:14 +00:00
|
|
|
def get_verses(self, reference_list):
|
|
|
|
"""
|
|
|
|
A reimplementation of the ``BibleDB.get_verses`` method, this one is
|
|
|
|
specifically for web Bibles. It first checks to see if the particular
|
|
|
|
chapter exists in the DB, and if not it pulls it from the web. If the
|
|
|
|
chapter DOES exist, it simply pulls the verses from the DB using the
|
|
|
|
ancestor method.
|
|
|
|
|
|
|
|
``reference_list``
|
|
|
|
This is the list of references the media manager item wants. It is
|
|
|
|
a list of tuples, with the following format::
|
|
|
|
|
|
|
|
(book, chapter, start_verse, end_verse)
|
|
|
|
|
|
|
|
Therefore, when you are looking for multiple items, simply break
|
|
|
|
them up into references like this, bundle them into a list. This
|
|
|
|
function then runs through the list, and returns an amalgamated
|
|
|
|
list of ``Verse`` objects. For example::
|
|
|
|
|
|
|
|
[(u'Genesis', 1, 1, 1), (u'Genesis', 2, 2, 3)]
|
|
|
|
"""
|
|
|
|
for reference in reference_list:
|
|
|
|
log.debug('Reference: %s', reference)
|
|
|
|
book = reference[0]
|
|
|
|
db_book = self.get_book(book)
|
|
|
|
if not db_book:
|
|
|
|
book_details = self.lookup_book(book)
|
2010-01-29 21:26:24 +00:00
|
|
|
if not book_details:
|
|
|
|
Receiver.send_message(u'bible_nobook')
|
|
|
|
return []
|
2010-01-24 07:08:14 +00:00
|
|
|
db_book = self.create_book(book_details[u'name'],
|
|
|
|
book_details[u'abbr'], book_details[u'test'])
|
|
|
|
book = db_book.name
|
|
|
|
if self.get_verse_count(book, reference[1]) == 0:
|
2010-01-30 08:42:03 +00:00
|
|
|
Receiver.send_message(u'bible_showprogress')
|
|
|
|
Receiver.send_message(u'process_events')
|
2010-01-24 07:08:14 +00:00
|
|
|
search_results = self.get_chapter(self.name, book, reference[1])
|
|
|
|
if search_results and search_results.has_verselist():
|
|
|
|
## We have found a book of the bible lets check to see
|
|
|
|
## if it was there. By reusing the returned book name
|
|
|
|
## we get a correct book. For example it is possible
|
|
|
|
## to request ac and get Acts back.
|
|
|
|
bookname = search_results.get_book()
|
|
|
|
# check to see if book/chapter exists
|
|
|
|
db_book = self.get_book(bookname)
|
|
|
|
self.create_chapter(db_book.id, search_results.get_chapter(),
|
|
|
|
search_results.get_verselist())
|
2010-01-30 08:42:03 +00:00
|
|
|
Receiver.send_message(u'bible_hideprogress')
|
2010-01-29 21:35:02 +00:00
|
|
|
Receiver.send_message(u'process_events')
|
2010-01-24 07:08:14 +00:00
|
|
|
return BibleDB.get_verses(self, reference_list)
|
|
|
|
|
|
|
|
def get_chapter(self, version, book, chapter):
|
2008-11-16 07:40:46 +00:00
|
|
|
"""
|
2009-02-02 19:54:38 +00:00
|
|
|
Receive the request and call the relevant handler methods
|
2008-11-16 07:40:46 +00:00
|
|
|
"""
|
2010-01-24 07:08:14 +00:00
|
|
|
log.debug(u'get_chapter %s, %s, %s', version, book, chapter)
|
|
|
|
log.debug(u'source = %s', self.download_source)
|
2008-11-16 07:40:46 +00:00
|
|
|
try:
|
2010-01-24 07:08:14 +00:00
|
|
|
if self.download_source.lower() == u'crosswalk':
|
|
|
|
ev = CWExtract(self.proxy_server)
|
2008-11-16 07:40:46 +00:00
|
|
|
else:
|
2010-01-24 07:08:14 +00:00
|
|
|
ev = BGExtract(self.proxy_server)
|
|
|
|
return ev.get_bible_chapter(self.download_name, book, chapter)
|
2009-09-25 23:06:54 +00:00
|
|
|
except:
|
2010-01-17 16:48:45 +00:00
|
|
|
log.exception("Failed to get bible chapter")
|
2010-01-24 07:08:14 +00:00
|
|
|
return None
|
|
|
|
|
|
|
|
def get_books(self):
|
2010-01-29 20:20:30 +00:00
|
|
|
return [Book.populate(name=self.books[book]['name']) for book in self.books]
|
2010-01-24 07:08:14 +00:00
|
|
|
|
|
|
|
def get_chapter_count(self, book):
|
|
|
|
return self.books[book][u'chap']
|
|
|
|
|
|
|
|
def set_proxy_server(self, server):
|
|
|
|
self.proxy_server = server
|
|
|
|
|
|
|
|
def set_books(self, books):
|
|
|
|
self.books = books
|
|
|
|
|
|
|
|
def lookup_book(self, book):
|
|
|
|
log.debug('Looking up "%s" in %s', (book, self.books))
|
|
|
|
if book in self.books:
|
|
|
|
return self.books[book]
|
|
|
|
else:
|
|
|
|
for details in self.books:
|
2010-01-29 21:26:24 +00:00
|
|
|
if self.books[details][u'abbr'] == book:
|
|
|
|
return self.books[details]
|
2010-01-24 07:08:14 +00:00
|
|
|
return None
|
2010-01-17 16:48:45 +00:00
|
|
|
|