diff --git a/openlp/core/utils/__init__.py b/openlp/core/utils/__init__.py index d29ff17b4..9c0ec9814 100644 --- a/openlp/core/utils/__init__.py +++ b/openlp/core/utils/__init__.py @@ -44,6 +44,12 @@ class AppLocation(object): @staticmethod def get_directory(dir_type): + """ + Return the appropriate directory according to the directory type. + + ``dir_type`` + The directory type you want, for instance the data directory. + """ if dir_type == AppLocation.AppDir: return os.path.abspath(os.path.split(sys.argv[0])[0]) elif dir_type == AppLocation.ConfigDir: @@ -89,6 +95,16 @@ class AppLocation(object): def check_latest_version(config, current_version): + """ + Check the latest version of OpenLP against the version file on the OpenLP + site. + + ``config`` + The OpenLP config object. + + ``current_version`` + The current version of OpenLP. + """ version_string = current_version #set to prod in the distribution confif file. last_test = config.get_config(u'last version test', datetime.now().date()) @@ -107,6 +123,18 @@ def check_latest_version(config, current_version): log.exception(u'Reason for failure: %s', e.reason) return version_string +def variant_to_unicode(variant): + """ + Converts a QVariant to a unicode string. + + ``variant`` + The QVariant instance to convert to unicode. + """ + string = variant.toString() + if not isinstance(string, unicode): + string = unicode(string, u'utf8') + return string + from registry import Registry from confighelper import ConfigHelper diff --git a/openlp/plugins/bibles/forms/importwizardform.py b/openlp/plugins/bibles/forms/importwizardform.py index a24ccf8a4..67c397001 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 +from openlp.core.utils import AppLocation, variant_to_unicode from openlp.plugins.bibles.lib.manager import BibleFormat log = logging.getLogger(__name__) @@ -60,9 +60,21 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard): log.info(u'BibleImportForm loaded') def __init__(self, parent, config, manager, bibleplugin): - ''' - Constructor - ''' + """ + Instantiate the wizard, and run any extra setup we need to. + + ``parent`` + The QWidget-derived parent of the wizard. + + ``config`` + The configuration object for storing and retrieving settings. + + ``manager`` + The Bible manager. + + ``bibleplugin`` + The Bible plugin. + """ QtGui.QWizard.__init__(self, parent) self.setupUi(self) self.registerFields() @@ -97,10 +109,16 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard): self.onCurrentIdChanged) def exec_(self): + """ + Run the wizard. + """ self.setDefaults() return QtGui.QWizard.exec_(self) def validateCurrentPage(self): + """ + Validate the current page before moving on to the next page. + """ if self.currentId() == 0: # Welcome page return True @@ -144,7 +162,9 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard): return True elif self.currentId() == 2: # License details - if self.field(u'license_version').toString() == u'': + license_version = variant_to_unicode(self.field(u'license_version')) + license_copyright = variant_to_unicode(self.field(u'license_copyright')) + if license_version == u'': QtGui.QMessageBox.critical(self, self.trUtf8('Empty Version Name'), self.trUtf8('You need to specify a version name for your ' @@ -152,7 +172,7 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard): QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok)) self.VersionNameEdit.setFocus() return False - elif self.field(u'license_copyright').toString() == u'': + elif license_copyright == u'': QtGui.QMessageBox.critical(self, self.trUtf8('Empty Copyright'), self.trUtf8('You need to set a copyright for your Bible! ' @@ -161,8 +181,7 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard): QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok)) self.CopyrightEdit.setFocus() return False - elif self.manager.exists( - self.field(u'license_version').toString()): + elif self.manager.exists(license_version): QtGui.QMessageBox.critical(self, self.trUtf8('Bible Exists'), self.trUtf8('This Bible already exists! Please import ' @@ -176,27 +195,49 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard): return True def onLocationComboBoxChanged(self, index): + """ + Setup the list of Bibles when you select a different source on the web + download page. + + ``index`` + The index of the combo box. + """ self.BibleComboBox.clear() - for bible, abbreviation in self.web_bible_list[index].iteritems(): + for bible in self.web_bible_list[index].keys(): self.BibleComboBox.addItem(unicode(self.trUtf8(bible))) def onOsisFileButtonClicked(self): - self.getFileName(self.trUtf8('Open OSIS file'), + """ + Show the file open dialog for the OSIS file. + """ + self.getFileName(self.trUtf8('Open OSIS File'), self.OSISLocationEdit) def onBooksFileButtonClicked(self): - self.getFileName(self.trUtf8('Open Books CSV file'), + """ + Show the file open dialog for the books CSV file. + """ + self.getFileName(self.trUtf8('Open Books CSV File'), self.BooksLocationEdit) def onCsvVersesFileButtonClicked(self): - self.getFileName(self.trUtf8('Open Verses CSV file'), + """ + Show the file open dialog for the verses CSV file. + """ + self.getFileName(self.trUtf8('Open Verses CSV File'), self.CsvVerseLocationEdit) def onOpenSongBrowseButtonClicked(self): + """ + Show the file open dialog for the OpenSong file. + """ self.getFileName(self.trUtf8('Open OpenSong Bible'), self.OpenSongFileEdit) def onCancelButtonClicked(self, checked): + """ + Stop the import on pressing the cancel button. + """ log.debug('Cancel button pressed!') if self.currentId() == 3: Receiver.send_message(u'openlpstopimport') @@ -270,7 +311,7 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard): books_reader = csv.reader(books_file, dialect) for line in books_reader: self.web_bible_list[DownloadLocation.Crosswalk][line[0]] = \ - unicode(line[1], u'utf-8').strip() + unicode(line[1], u'utf8').strip() except: log.exception(u'Crosswalk resources missing') finally: @@ -315,25 +356,28 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard): def performImport(self): bible_type = self.field(u'source_format').toInt()[0] + license_version = variant_to_unicode(self.field(u'license_version')) + license_copyright = variant_to_unicode(self.field(u'license_copyright')) + license_permission = variant_to_unicode(self.field(u'license_permission')) importer = None if bible_type == BibleFormat.OSIS: # Import an OSIS bible importer = self.manager.import_bible(BibleFormat.OSIS, - name=unicode(self.field(u'license_version').toString()), - filename=unicode(self.field(u'osis_location').toString()) + name=license_version, + filename=variant_to_unicode(self.field(u'osis_location')) ) elif bible_type == BibleFormat.CSV: # Import a CSV bible importer = self.manager.import_bible(BibleFormat.CSV, - name=unicode(self.field(u'license_version').toString()), - booksfile=self.field(u'csv_booksfile').toString(), - versefile=self.field(u'csv_versefile').toString() + name=license_version, + booksfile=variant_to_unicode(self.field(u'csv_booksfile')), + versefile=variant_to_unicode(self.field(u'csv_versefile')) ) elif bible_type == BibleFormat.OpenSong: # Import an OpenSong bible importer = self.manager.import_bible(BibleFormat.OpenSong, - name=unicode(self.field(u'license_version').toString()), - filename=self.field(u'opensong_file').toString() + name=license_version, + filename=variant_to_unicode(self.field(u'opensong_file')) ) elif bible_type == BibleFormat.WebDownload: # Import a bible from the web @@ -344,23 +388,20 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard): unicode(self.BibleComboBox.currentText(), u'utf8')] elif download_location == DownloadLocation.BibleGateway: bible = self.web_bible_list[DownloadLocation.BibleGateway][ - self.BibleComboBox.currentText()] - importer = self.manager.import_bible(BibleFormat.WebDownload, - name=unicode(self.field(u'license_version').toString(), u'utf8'), + unicode(self.BibleComboBox.currentText(), u'utf8')] + importer = self.manager.import_bible( + BibleFormat.WebDownload, + name=license_version, download_source=DownloadLocation.get_name(download_location), download_name=bible, - proxy_server=unicode(self.field(u'proxy_server').toString(), u'utf8'), - proxy_username=unicode(self.field(u'proxy_username').toString(), u'utf8'), - proxy_password=unicode(self.field(u'proxy_password').toString(), u'utf8') + proxy_server=variant_to_unicode(self.field(u'proxy_server')), + proxy_username=variant_to_unicode(self.field(u'proxy_username')), + proxy_password=variant_to_unicode(self.field(u'proxy_password')) ) success = importer.do_import() if success: - self.manager.save_meta_data( - unicode(self.field(u'license_version').toString()), - unicode(self.field(u'license_version').toString()), - unicode(self.field(u'license_copyright').toString()), - unicode(self.field(u'license_permission').toString()) - ) + self.manager.save_meta_data(license_version, license_version, + license_copyright, license_permission) self.manager.reload_bibles() self.ImportProgressLabel.setText(self.trUtf8('Finished import.')) else: diff --git a/openlp/plugins/bibles/lib/http.py b/openlp/plugins/bibles/lib/http.py index da129fa22..877c50669 100644 --- a/openlp/plugins/bibles/lib/http.py +++ b/openlp/plugins/bibles/lib/http.py @@ -39,10 +39,19 @@ from openlp.plugins.bibles.lib.models import 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', @@ -53,12 +62,24 @@ class HTTPBooks(object): @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 = [] @@ -74,6 +95,12 @@ class HTTPBooks(object): @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) books = HTTPBooks.run_sql(u'SELECT id, testament_id, name, ' @@ -92,6 +119,15 @@ class HTTPBooks(object): @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) @@ -109,6 +145,12 @@ class HTTPBooks(object): @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'] @@ -116,6 +158,15 @@ class HTTPBooks(object): @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'] @@ -123,7 +174,9 @@ class HTTPBooks(object): class BGExtract(BibleCommon): - log.info(u'%s BGExtract loaded', __name__) + """ + Extract verses from BibleGateway + """ def __init__(self, proxyurl=None): log.debug(u'init %s', proxyurl) @@ -133,7 +186,7 @@ class BGExtract(BibleCommon): """ Access and decode bibles via the BibleGateway website - ``Version`` + ``version`` The version of the bible like 31 for New International version ``bookname`` @@ -196,8 +249,10 @@ class BGExtract(BibleCommon): verse_list[verse_number] = u'' continue if isinstance(verse, NavigableString): + if not isinstance(verse, unicode): + verse = unicode(verse, u'utf8') verse_list[verse_number] = verse_list[verse_number] + \ - unescape(unicode(verse, u'utf-8').replace(u' ', u' ')) + unescape(verse.replace(u' ', u' ')) # Delete the "0" element, since we don't need it, it's just there for # some stupid initial whitespace, courtesy of Bible Gateway. del verse_list[0] @@ -205,14 +260,15 @@ class BGExtract(BibleCommon): return SearchResults(bookname, chapter, verse_list) class CWExtract(BibleCommon): - log.info(u'%s CWExtract loaded', __name__) + """ + Extract verses from CrossWalk/BibleStudyTools + """ def __init__(self, proxyurl=None): log.debug(u'init %s', proxyurl) self.proxyurl = proxyurl def get_bible_chapter(self, version, bookname, chapter): - log.debug(u'%s %s, %s, %s', __name__, version, bookname, chapter) """ Access and decode bibles via the Crosswalk website @@ -227,9 +283,9 @@ class CWExtract(BibleCommon): """ log.debug(u'get_bible_chapter %s,%s,%s', version, bookname, chapter) - bookname = bookname.replace(u' ', u'') + urlbookname = bookname.replace(u' ', u'-') chapter_url = u'http://www.biblestudytools.com/%s/%s/%s.html' % \ - (version, bookname.lower(), chapter) + (version, urlbookname.lower(), chapter) log.debug(u'URL: %s', chapter_url) page = urllib2.urlopen(chapter_url) if not page: @@ -287,6 +343,10 @@ class HTTPBible(BibleDB): self.proxy_password = None def do_import(self): + """ + Run the import. This method overrides the parent class method. Returns + ``True`` on success, ``False`` on failure. + """ self.wizard.ImportProgressBar.setMaximum(2) self.wizard.incrementProgressBar('Registering bible...') self.create_meta(u'download source', self.download_source) @@ -370,17 +430,43 @@ class HTTPBible(BibleDB): return None def get_books(self): + """ + Return the list of books. + """ return [Book.populate(name=book['name']) for book in HTTPBooks.get_books()] def lookup_book(self, book): + """ + Look up the name of a book. + """ return HTTPBooks.get_book(book) def get_chapter_count(self, book): + """ + Return the number of chapters in a particular book. + """ return HTTPBooks.get_chapter_count(book) def get_verse_count(self, book, chapter): + """ + Return the number of verses for the specified chapter and book. + + ``book`` + The name of the book. + + ``chapter`` + The chapter whose verses are being counted. + """ return HTTPBooks.get_verse_count(book, chapter) def set_proxy_server(self, server): + """ + Sets the proxy server. + + **Note: This is not actually used.** + + ``server`` + The hostname or IP address of the proxy server. + """ self.proxy_server = server diff --git a/openlp/plugins/bibles/lib/manager.py b/openlp/plugins/bibles/lib/manager.py index e3647e129..ae9c5507d 100644 --- a/openlp/plugins/bibles/lib/manager.py +++ b/openlp/plugins/bibles/lib/manager.py @@ -60,6 +60,9 @@ class BibleFormat(object): def get_class(id): """ Return the appropriate imeplementation class. + + ``id`` + The Bible format. """ if id == BibleFormat.OSIS: return OSISBible @@ -74,6 +77,9 @@ class BibleFormat(object): @staticmethod def list(): + """ + Return a list of the supported Bible formats. + """ return [ BibleFormat.OSIS, BibleFormat.CSV, @@ -247,7 +253,7 @@ class BibleManager(object): """ if not isinstance(name, unicode): name = unicode(name) - for bible, db_object in self.db_cache.iteritems(): + for bible in self.db_cache.keys(): log.debug(u'Bible from cache in is_new_bible %s', bible) if not isinstance(bible, unicode): bible = unicode(bible) diff --git a/openlp/plugins/bibles/lib/osis.py b/openlp/plugins/bibles/lib/osis.py index 894feb8d8..a36efb645 100644 --- a/openlp/plugins/bibles/lib/osis.py +++ b/openlp/plugins/bibles/lib/osis.py @@ -65,6 +65,7 @@ class OSISBible(BibleDB): self.l_regex = re.compile(r'') self.w_regex = re.compile(r'') self.q_regex = re.compile(r'') + self.trans_regex = re.compile(r'(.*?)') self.spaces_regex = re.compile(r'([ ]{2,})') self.books = {} filepath = os.path.join( @@ -159,10 +160,11 @@ class OSISBible(BibleDB): verse_text = self.l_regex.sub(u'', verse_text) verse_text = self.w_regex.sub(u'', verse_text) verse_text = self.q_regex.sub(u'', verse_text) + verse_text = self.trans_regex.sub(u'', verse_text) verse_text = verse_text.replace(u'', u'')\ .replace(u'', u'').replace(u'', u'')\ .replace(u'', u'').replace(u'', u'')\ - .replace(u'', u'') + .replace(u'', u'').replace(u'', u'') verse_text = self.spaces_regex.sub(u' ', verse_text) self.create_verse(db_book.id, chapter, verse, verse_text) Receiver.send_message(u'process_events')