From 8f095a2fc55ef1dcae000707f605ecc2654b6575 Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Fri, 26 Mar 2010 22:50:55 +0200 Subject: [PATCH 1/5] Fixed a bug with Strongs in CrossWalk. --- openlp/plugins/bibles/lib/http.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/openlp/plugins/bibles/lib/http.py b/openlp/plugins/bibles/lib/http.py index 4a447de98..2c3e433f6 100644 --- a/openlp/plugins/bibles/lib/http.py +++ b/openlp/plugins/bibles/lib/http.py @@ -27,6 +27,7 @@ import logging import urllib2 import os import sqlite3 +import re from BeautifulSoup import BeautifulSoup, Tag, NavigableString @@ -293,18 +294,22 @@ class CWExtract(BibleCommon): soup = BeautifulSoup(page) htmlverses = soup.findAll(u'span', u'versetext') verses = {} + reduce_spaces = re.compile(r'[ ]{2,}') for verse in htmlverses: Receiver.send_message(u'process_events') versenumber = int(verse.contents[0].contents[0]) versetext = u'' for part in verse.contents: - if str(part)[0] != u'<': + if isinstance(part, NavigableString): versetext = versetext + part - elif part and part.attrMap and part.attrMap[u'class'] == u'WordsOfChrist': + elif part and part.attrMap and \ + (part.attrMap[u'class'] == u'WordsOfChrist' or \ + part.attrMap[u'class'] == u'strongs'): for subpart in part.contents: - if str(subpart)[0] != '<': + if isinstance(subpart, NavigableString): versetext = versetext + subpart versetext = versetext.strip(u'\n\r\t ') + versetext = reduce_spaces.sub(u' ', versetext) verses[versenumber] = versetext return SearchResults(bookname, chapter, verses) From abfc977b17c5d14fc716138fb794e53f90f43188 Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Sat, 27 Mar 2010 14:37:21 +0200 Subject: [PATCH 2/5] Fix to deal with "X.Y.Z" style version (i.e. without the "-bzrXXX"). --- openlp.pyw | 23 +++++++---- openlp/.version | 2 +- openlp/core/ui/aboutdialog.py | 2 +- openlp/core/ui/aboutform.py | 15 ++++--- openlp/core/ui/mainwindow.py | 13 +++--- openlp/core/utils/__init__.py | 13 +++--- openlp/plugins/bibles/lib/db.py | 70 ++++++++++++++++++++++++++++++++- 7 files changed, 110 insertions(+), 28 deletions(-) diff --git a/openlp.pyw b/openlp.pyw index d9880865b..f1b627940 100755 --- a/openlp.pyw +++ b/openlp.pyw @@ -92,16 +92,23 @@ class OpenLP(QtGui.QApplication): app_version = { u'full': full_version, u'version': bits[0], - u'build': bits[1] + u'build': bits[1] if len(bits) > 1 else None } - log.info(u'Openlp version %s build %s' % ( - app_version[u'version'], app_version[u'build'])) + if app_version[u'build']: + log.info( + u'Openlp version %s build %s', + app_version[u'version'], + app_version[u'build'] + ) + else: + log.info(u'Openlp version %s' % app_version[u'version']) except: - app_version = { - u'full': u'1.9.0-bzr000', - u'version': u'1.9.0', - u'build': u'bzr000' - } + log.exception('Error in version file.') + app_version = { + u'full': u'1.9.0-bzr000', + u'version': u'1.9.0', + u'build': u'bzr000' + } finally: if fversion: fversion.close() diff --git a/openlp/.version b/openlp/.version index 338414e8c..f8e233b27 100644 --- a/openlp/.version +++ b/openlp/.version @@ -1 +1 @@ -1.9.0-bzr743 +1.9.0 diff --git a/openlp/core/ui/aboutdialog.py b/openlp/core/ui/aboutdialog.py index 0f38b02f0..c74246f5c 100644 --- a/openlp/core/ui/aboutdialog.py +++ b/openlp/core/ui/aboutdialog.py @@ -115,7 +115,7 @@ class Ui_AboutDialog(object): def retranslateUi(self, AboutDialog): AboutDialog.setWindowTitle(self.trUtf8('About OpenLP')) self.AboutTextEdit.setPlainText(self.trUtf8( - 'OpenLP build - Open Source Lyrics ' + 'OpenLP - Open Source Lyrics ' 'Projection\n' '\n' 'OpenLP is free church presentation software, or lyrics ' diff --git a/openlp/core/ui/aboutform.py b/openlp/core/ui/aboutform.py index fe576767f..c79324515 100644 --- a/openlp/core/ui/aboutform.py +++ b/openlp/core/ui/aboutform.py @@ -39,11 +39,16 @@ class AboutForm(QtGui.QDialog, Ui_AboutDialog): QtGui.QDialog.__init__(self, parent) self.applicationVersion = applicationVersion self.setupUi(self) - self.AboutTextEdit.setPlainText( - self.AboutTextEdit.toPlainText()\ - .replace(u'', self.applicationVersion[u'version'])\ - .replace(u'', self.applicationVersion[u'build']) - ) + about_text = self.AboutTextEdit.toPlainText() + about_text = about_text.replace(u'', + self.applicationVersion[u'version']) + if self.applicationVersion[u'build']: + build_text = u' %s %s' % (self.trUtf8('build'), + self.applicationVersion[u'build']) + else: + build_text = u'' + about_text = about_text.replace(u'', build_text) + self.AboutTextEdit.setPlainText(about_text) QtCore.QObject.connect(self.ContributeButton, QtCore.SIGNAL(u'clicked()'), self.onContributeButtonClicked) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 0fc0588ae..13d880407 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -71,7 +71,7 @@ class VersionThread(QtCore.QThread): Receiver.send_message(u'blank_check') version = check_latest_version(self.generalConfig, self.app_version) #new version has arrived - if version != self.app_version: + if version != self.app_version[u'full']: Receiver.send_message(u'version_check', u'%s' % version) @@ -554,11 +554,12 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): Checks the version of the Application called from openlp.pyw """ app_version = self.applicationVersion[u'full'] - version_text = unicode(self.trUtf8('OpenLP version %s has been updated ' - 'to version %s\n\nYou can obtain the latest version from http://openlp.org')) + version_text = unicode(self.trUtf8('Version %s of OpenLP is now ' + 'available for download (you are currently running version %s).' + '\n\nYou can download the latest version from http://openlp.org')) QtGui.QMessageBox.question(self, self.trUtf8('OpenLP Version Updated'), - version_text % (app_version, version), + version_text % (version, app_version), QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok), QtGui.QMessageBox.Ok) @@ -597,8 +598,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): QtGui.QMessageBox.Ok) def versionThread(self): - app_version = self.applicationVersion[u'full'] - vT = VersionThread(self, app_version, self.generalConfig) + #app_version = self.applicationVersion[u'full'] + vT = VersionThread(self, self.applicationVersion, self.generalConfig) vT.start() def onHelpAboutItemClicked(self): diff --git a/openlp/core/utils/__init__.py b/openlp/core/utils/__init__.py index a64b0c06b..faa3b2dfb 100644 --- a/openlp/core/utils/__init__.py +++ b/openlp/core/utils/__init__.py @@ -105,19 +105,20 @@ def check_latest_version(config, current_version): ``current_version`` The current version of OpenLP. """ - version_string = current_version + version_string = current_version[u'full'] #set to prod in the distribution confif file. last_test = config.get_config(u'last version test', datetime.now().date()) this_test = unicode(datetime.now().date()) config.set_config(u'last version test', this_test) if last_test != this_test: version_string = u'' - req = urllib2.Request(u'http://www.openlp.org/files/version.txt') - req.add_header(u'User-Agent', u'OpenLP/%s' % current_version) + if current_version[u'build']: + req = urllib2.Request(u'http://www.openlp.org/files/dev_version.txt') + else: + req = urllib2.Request(u'http://www.openlp.org/files/version.txt') + req.add_header(u'User-Agent', u'OpenLP/%s' % current_version[u'full']) try: - handle = urllib2.urlopen(req, None) - html = handle.read() - version_string = unicode(html).rstrip() + version_string = unicode(urllib2.urlopen(req, None).read()).strip() except IOError, e: if hasattr(e, u'reason'): log.exception(u'Reason for failure: %s', e.reason) diff --git a/openlp/plugins/bibles/lib/db.py b/openlp/plugins/bibles/lib/db.py index c57ecb83e..66b956109 100644 --- a/openlp/plugins/bibles/lib/db.py +++ b/openlp/plugins/bibles/lib/db.py @@ -95,6 +95,9 @@ class BibleDB(QtCore.QObject): self.get_name() def get_name(self): + """ + Returns the version name of the Bible. + """ version_name = self.get_meta(u'Version') if version_name: self.name = version_name.value @@ -103,12 +106,22 @@ class BibleDB(QtCore.QObject): return self.name def clean_filename(self, old_filename): + """ + Clean up the version name of the Bible and convert it into a valid + file name. + + ``old_filename`` + The "dirty" file name or version name. + """ if not isinstance(old_filename, unicode): old_filename = unicode(old_filename, u'utf-8') old_filename = re.sub(r'[^\w]+', u'_', old_filename).strip(u'_') return old_filename + u'.sqlite' def delete(self): + """ + Remove the Bible database file. Used when a Bible import fails. + """ try: os.remove(self.db_file) return True @@ -119,18 +132,27 @@ class BibleDB(QtCore.QObject): """ This method basically just initialialises the database. It is called from the Bible Manager when a Bible is imported. Descendant classes - may want to override this method to suVersionpply their own custom + may want to override this method to supply their own custom initialisation as well. + + ``wizard`` + The actual Qt wizard form. """ self.wizard = wizard self.create_tables() return self.name def commit(self): + """ + Perform a database commit. + """ log.debug('Committing...') self.session.commit() def create_tables(self): + """ + Create some initial metadata. + """ log.debug(u'createTables') self.create_meta(u'dbversion', u'2') self.create_testament(u'Old Testament') @@ -138,11 +160,29 @@ class BibleDB(QtCore.QObject): self.create_testament(u'Apocrypha') def create_testament(self, testament): + """ + Add a testament to the database. + + ``testament`` + The testament name. + """ log.debug(u'BibleDB.create_testament("%s")', testament) self.session.add(Testament.populate(name=testament)) self.commit() def create_book(self, name, abbrev, testament=1): + """ + Add a book to the database. + + ``name`` + The name of the book. + + ``abbrev`` + The abbreviation of the book. + + ``testament`` + *Defaults to 1.* The id 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) @@ -151,6 +191,19 @@ class BibleDB(QtCore.QObject): return book def create_chapter(self, book_id, chapter, textlist): + """ + Add a chapter and it's verses to a book. + + ``book_id`` + The id of the book being appended. + + ``chapter`` + The chapter number. + + ``textlist`` + A dict of the verses to be inserted. The key is the verse number, + and the value is the verse text. + """ log.debug(u'create_chapter %s,%s', book_id, chapter) #text list has book and chapter as first two elements of the array for verse_number, verse_text in textlist.iteritems(): @@ -164,6 +217,21 @@ class BibleDB(QtCore.QObject): self.commit() def create_verse(self, book_id, chapter, verse, text): + """ + Add a single verse to a chapter. + + ``book_id`` + The id of the book being appended. + + ``chapter`` + The chapter number. + + ``verse`` + The verse number. + + ``text`` + The verse text. + """ if not isinstance(text, unicode): details = chardet.detect(text) text = unicode(text, details[u'encoding']) From 08ee7be551c3e059e922a7187f50a5fe4cbcaf47 Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Sat, 27 Mar 2010 16:53:41 +0200 Subject: [PATCH 3/5] Fixed the "Bible" item in the "Import" menu. --- openlp/plugins/bibles/bibleplugin.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openlp/plugins/bibles/bibleplugin.py b/openlp/plugins/bibles/bibleplugin.py index 01c92141f..61724ffb6 100644 --- a/openlp/plugins/bibles/bibleplugin.py +++ b/openlp/plugins/bibles/bibleplugin.py @@ -73,7 +73,7 @@ class BiblePlugin(Plugin): self.ImportBibleItem.setText(import_menu.trUtf8('&Bible')) # Signals and slots QtCore.QObject.connect(self.ImportBibleItem, - QtCore.SIGNAL(u'triggered()'), self.onBibleNewClick) + QtCore.SIGNAL(u'triggered()'), self.onBibleImportClick) self.ImportBibleItem.setVisible(False) def add_export_menu_item(self, export_menu): @@ -83,9 +83,9 @@ class BiblePlugin(Plugin): self.ExportBibleItem.setText(export_menu.trUtf8('&Bible')) self.ExportBibleItem.setVisible(False) - def onBibleNewClick(self): + def onBibleImportClick(self): if self.media_item: - self.media_item.onNewClick() + self.media_item.onImportClick() def about(self): about_text = self.trUtf8('Bible Plugin
This ' From fb3abf7f36ab5c5197c66fa639c9d6c23a136b31 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sat, 27 Mar 2010 16:46:52 +0000 Subject: [PATCH 4/5] Fix date --- openlp/core/ui/aboutdialog.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openlp/core/ui/aboutdialog.py b/openlp/core/ui/aboutdialog.py index c74246f5c..7d8d27103 100644 --- a/openlp/core/ui/aboutdialog.py +++ b/openlp/core/ui/aboutdialog.py @@ -166,9 +166,9 @@ class Ui_AboutDialog(object): self.AboutNotebook.indexOf(self.CreditsTab), self.trUtf8('Credits')) self.LicenseTextEdit.setPlainText(self.trUtf8( - 'Copyright ' + u'\u00a9'.encode('utf8') + ' 2004-2009 Raoul ' + 'Copyright ' + u'\u00a9'.encode('utf8') + ' 2004-2010 Raoul ' 'Snyman\n' - 'Portions copyright ' + u'\u00a9'.encode('utf8') + ' 2004-2009 ' + 'Portions copyright ' + u'\u00a9'.encode('utf8') + ' 2004-2010 ' 'Tim Bentley, Jonathan Corwin, Michael Gorven, Scott Guerrieri, ' 'Christian Richter, Maikel Stuivenberg, Martin Thompson, Jon ' 'Tibble, Carsten Tinggaard\n' From d2670b1cb077d9fd2be008b5057c4a77117233c6 Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Sat, 27 Mar 2010 21:59:35 +0200 Subject: [PATCH 5/5] Bible fixes: - Red letter text on CrossWalk import. - Removed text on web download progress, moved to an "indeterminable" progress style. - Some unicode optimisations. --- openlp/core/utils/__init__.py | 17 +++++++++++--- .../plugins/bibles/forms/importwizardform.py | 3 ++- openlp/plugins/bibles/lib/common.py | 2 +- openlp/plugins/bibles/lib/http.py | 22 +++++++++++++++++++ openlp/plugins/bibles/lib/mediaitem.py | 12 +++++----- 5 files changed, 46 insertions(+), 10 deletions(-) diff --git a/openlp/core/utils/__init__.py b/openlp/core/utils/__init__.py index a64b0c06b..67bdf4778 100644 --- a/openlp/core/utils/__init__.py +++ b/openlp/core/utils/__init__.py @@ -29,6 +29,8 @@ import logging import urllib2 from datetime import datetime +from PyQt4 import QtCore + import openlp log = logging.getLogger(__name__) @@ -123,16 +125,25 @@ def check_latest_version(config, current_version): log.exception(u'Reason for failure: %s', e.reason) return version_string +def string_to_unicode(string): + """ + Converts a QString to a Python unicode object. + """ + if isinstance(string, QtCore.QString): + string = unicode(string.toUtf8(), u'utf8') + return string + def variant_to_unicode(variant): """ - Converts a QVariant to a unicode string. + Converts a QVariant to a Python unicode object. ``variant`` The QVariant instance to convert to unicode. """ - string = variant.toString() + if isinstance(variant, QtCore.QVariant): + string = variant.toString() if not isinstance(string, unicode): - string = unicode(string, u'utf8') + string = string_to_unicode(string) return string from registry import Registry diff --git a/openlp/plugins/bibles/forms/importwizardform.py b/openlp/plugins/bibles/forms/importwizardform.py index a717a4f44..a803b7481 100644 --- a/openlp/plugins/bibles/forms/importwizardform.py +++ b/openlp/plugins/bibles/forms/importwizardform.py @@ -32,7 +32,7 @@ from PyQt4 import QtCore, QtGui from bibleimportwizard import Ui_BibleImportWizard from openlp.core.lib import Receiver -from openlp.core.utils import AppLocation, variant_to_unicode +from openlp.core.utils import AppLocation, variant_to_unicode, string_to_unicode from openlp.plugins.bibles.lib.manager import BibleFormat log = logging.getLogger(__name__) @@ -425,3 +425,4 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard): self.finishButton.setVisible(True) self.cancelButton.setVisible(False) Receiver.send_message(u'process_events') + diff --git a/openlp/plugins/bibles/lib/common.py b/openlp/plugins/bibles/lib/common.py index eef9b4dc3..48e55cb7e 100644 --- a/openlp/plugins/bibles/lib/common.py +++ b/openlp/plugins/bibles/lib/common.py @@ -33,7 +33,7 @@ only_verses = re.compile(r'([\w .]+)[ ]+([0-9]+)[ ]*[:|v|V][ ]*([0-9]+)' r'(?:[ ]*-[ ]*([0-9]+|end))?(?:[ ]*,[ ]*([0-9]+)(?:[ ]*-[ ]*([0-9]+|end))?)?', re.UNICODE) chapter_range = re.compile(r'([\w .]+)[ ]+([0-9]+)[ ]*[:|v|V][ ]*' - r'([0-9]+)[ ]*-[ ]*([0-9]+)[ ]*[:|v|V][ ]*([0-9]+)', + r'([0-9]+|end)[ ]*-[ ]*([0-9]+)[ ]*[:|v|V][ ]*([0-9]+|end)', re.UNICODE) log = logging.getLogger(__name__) diff --git a/openlp/plugins/bibles/lib/http.py b/openlp/plugins/bibles/lib/http.py index 2c3e433f6..b14f9b3a2 100644 --- a/openlp/plugins/bibles/lib/http.py +++ b/openlp/plugins/bibles/lib/http.py @@ -203,7 +203,9 @@ class BGExtract(BibleCommon): # Let's get the page, and then open it in BeautifulSoup, so as to # attempt to make "easy" work of bad HTML. page = urllib2.urlopen(urlstring) + Receiver.send_message(u'process_events') soup = BeautifulSoup(page) + Receiver.send_message(u'process_events') verses = soup.find(u'div', u'result-text-style-normal') verse_number = 0 verse_list = {0: u''} @@ -211,6 +213,7 @@ class BGExtract(BibleCommon): # This is a PERFECT example of opening the Cthulu tag! # O Bible Gateway, why doth ye such horrific HTML produce? for verse in verses: + Receiver.send_message(u'process_events') if isinstance(verse, Tag) and verse.name == u'div' and filter(lambda a: a[0] == u'class', verse.attrs)[0][1] == u'footnotes': break if isinstance(verse, Tag) and verse.name == u'sup' and filter(lambda a: a[0] == u'class', verse.attrs)[0][1] != u'versenum': @@ -219,6 +222,7 @@ class BGExtract(BibleCommon): continue if isinstance(verse, Tag) and (verse.name == u'p' or verse.name == u'font') and verse.contents: for item in verse.contents: + Receiver.send_message(u'process_events') if isinstance(item, Tag) and (item.name == u'h4' or item.name == u'h5'): continue if isinstance(item, Tag) and item.name == u'sup' and filter(lambda a: a[0] == u'class', item.attrs)[0][1] != u'versenum': @@ -231,6 +235,7 @@ class BGExtract(BibleCommon): continue if isinstance(item, Tag) and item.name == u'font': for subitem in item.contents: + Receiver.send_message(u'process_events') if isinstance(subitem, Tag) and subitem.name == u'sup' and filter(lambda a: a[0] == u'class', subitem.attrs)[0][1] != u'versenum': continue if isinstance(subitem, Tag) and subitem.name == u'p' and not subitem.contents: @@ -289,27 +294,42 @@ class CWExtract(BibleCommon): (version, urlbookname.lower(), chapter) log.debug(u'URL: %s', chapter_url) page = urllib2.urlopen(chapter_url) + Receiver.send_message(u'process_events') if not page: return None soup = BeautifulSoup(page) + Receiver.send_message(u'process_events') htmlverses = soup.findAll(u'span', u'versetext') verses = {} reduce_spaces = re.compile(r'[ ]{2,}') + fix_punctuation = re.compile(r'[ ]+([.,;])') for verse in htmlverses: Receiver.send_message(u'process_events') versenumber = int(verse.contents[0].contents[0]) versetext = u'' for part in verse.contents: + Receiver.send_message(u'process_events') if isinstance(part, NavigableString): versetext = versetext + part elif part and part.attrMap and \ (part.attrMap[u'class'] == u'WordsOfChrist' or \ part.attrMap[u'class'] == u'strongs'): for subpart in part.contents: + Receiver.send_message(u'process_events') if isinstance(subpart, NavigableString): versetext = versetext + subpart + elif subpart and subpart.attrMap and \ + subpart.attrMap[u'class'] == u'strongs': + for subsub in subpart.contents: + Receiver.send_message(u'process_events') + if isinstance(subsub, NavigableString): + versetext = versetext + subsub + Receiver.send_message(u'process_events') + # Fix up leading and trailing spaces, multiple spaces, and spaces + # between text and , and . versetext = versetext.strip(u'\n\r\t ') versetext = reduce_spaces.sub(u' ', versetext) + versetext = fix_punctuation.sub(r'\1', versetext) verses[versenumber] = versetext return SearchResults(bookname, chapter, verses) @@ -410,10 +430,12 @@ class HTTPBible(BibleDB): ## we get a correct book. For example it is possible ## to request ac and get Acts back. bookname = search_results.get_book() + Receiver.send_message(u'process_events') # check to see if book/chapter exists db_book = self.get_book(bookname) self.create_chapter(db_book.id, search_results.get_chapter(), search_results.get_verselist()) + Receiver.send_message(u'process_events') Receiver.send_message(u'bible_hideprogress') Receiver.send_message(u'process_events') return BibleDB.get_verses(self, reference_list) diff --git a/openlp/plugins/bibles/lib/mediaitem.py b/openlp/plugins/bibles/lib/mediaitem.py index 3bcc0b426..cf17a4e12 100644 --- a/openlp/plugins/bibles/lib/mediaitem.py +++ b/openlp/plugins/bibles/lib/mediaitem.py @@ -266,8 +266,9 @@ class BibleMediaItem(MediaManagerItem): MediaManagerItem.addListViewToToolBar(self) # Progress Bar self.SearchProgress = QtGui.QProgressBar(self) - self.SearchProgress.setFormat('%p%') - self.SearchProgress.setMaximum(3) + self.SearchProgress.setFormat('') + self.SearchProgress.setMinimum(0) + self.SearchProgress.setMaximum(0) self.SearchProgress.setGeometry(self.ListView.geometry().left(), self.ListView.geometry().top(), 81, 23) self.SearchProgress.setVisible(False) @@ -351,9 +352,10 @@ class BibleMediaItem(MediaManagerItem): def onSearchProgressShow(self): self.SearchProgress.setVisible(True) - self.SearchProgress.setMinimum(0) - self.SearchProgress.setMaximum(2) - self.SearchProgress.setValue(1) + Receiver.send_message(u'process_events') + #self.SearchProgress.setMinimum(0) + #self.SearchProgress.setMaximum(2) + #self.SearchProgress.setValue(1) def onSearchProgressHide(self): self.SearchProgress.setVisible(False)