further work on parse_reference and other things

This commit is contained in:
M2j 2010-12-16 21:00:01 +01:00
parent 6e834900e6
commit f119a4afa5
10 changed files with 155 additions and 198 deletions

View File

@ -79,6 +79,12 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
QtGui.QWizard.__init__(self, parent)
self.setupUi(self)
self.registerFields()
if not BibleFormat.get_availability(BibleFormat.OpenLP1):
self.openlp1Page.setVisible(False)
self.openlp1LocationLabel.setVisible(False)
self.openlp1LocationEdit.setVisible(False)
self.openlp1FileButton.setVisible(False)
self.openlp1DisabledLabel.setVisible(True)
self.finishButton = self.button(QtGui.QWizard.FinishButton)
self.cancelButton = self.button(QtGui.QWizard.CancelButton)
self.manager = manager
@ -104,9 +110,6 @@ class BibleImportForm(QtGui.QWizard, Ui_BibleImportWizard):
QtCore.QObject.connect(self.openlp1FileButton,
QtCore.SIGNAL(u'clicked()'),
self.onOpenlp1FileButtonClicked)
QtCore.QObject.connect(self.cancelButton,
QtCore.SIGNAL(u'clicked(bool)'),
self.onCancelButtonClicked)
QtCore.QObject.connect(self,
QtCore.SIGNAL(u'currentIdChanged(int)'),
self.onCurrentIdChanged)

View File

@ -280,6 +280,11 @@ class Ui_BibleImportWizard(object):
self.openlp1LocationLayout.addWidget(self.openlp1FileButton)
self.openlp1Layout.setLayout(1, QtGui.QFormLayout.FieldRole,
self.openlp1LocationLayout)
self.openlp1DisabledLabel = QtGui.QLabel(self.openlp1Page)
self.openlp1DisabledLabel.setObjectName(u'openlp1DisabledLabel')
self.openlp1DisabledLabel.setVisible(False)
self.openlp1DisabledLabel.setWordWrap(True)
self.openlp1Layout.addWidget(self.openlp1DisabledLabel)
self.formatWidget.addWidget(self.openlp1Page)
self.selectPageLayout.addWidget(self.formatWidget)
bibleImportWizard.addPage(self.selectPage)
@ -420,3 +425,8 @@ class Ui_BibleImportWizard(object):
self.importProgressLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'Ready.'))
self.importProgressBar.setFormat(u'%p%')
self.openlp1DisabledLabel.setText(
translate('BiblesPlugin.ImportWizardForm', 'The openlp.org 1.x '
'importer has been disabled due to a missing Python module. If '
'you want to use this importer, you will need to install the '
'"python-sqlite" module.'))

View File

@ -32,24 +32,56 @@ import re
log = logging.getLogger(__name__)
BIBLE_SEPARATORS = {u'sep_v': r'\s*,\s*', u'sep_r': r'\s*-\s*', u'sep_l': r'\.'}
# English:
BIBLE_SEPARATORS = {u'sep_v': r'\s*:\s*', u'sep_r': r'\s*-\s*', u'sep_l': r','}
# German:
#BIBLE_SEPARATORS = {u'sep_v': r'\s*,\s*', u'sep_r': r'\s*-\s*', u'sep_l': r'\.'}
# RegEx for a verse span: (<chapter>:)?<verse>(-(<chapter>:)?<verse>?)?
BIBLE_RANGE_REGEX = str(r'(?:(?P<from_chapter>[0-9]+)%(sep_v)s)?'
r'(?P<from_verse>[0-9]+)(?:%(sep_r)s(?:(?:(?P<to_chapter>[0-9]+)%(sep_v)s)?'
r'(?P<to_verse>[0-9]+))?)?' % BIBLE_SEPARATORS)
r'(?P<from_verse>[0-9]+)(?P<range_to>%(sep_r)s(?:(?:(?P<to_chapter>[0-9]+)'
r'%(sep_v)s)?(?P<to_verse>[0-9]+))?)?' % BIBLE_SEPARATORS)
BIBLE_RANGE = re.compile(r'^\s*' + BIBLE_RANGE_REGEX + r'\s*$', re.UNICODE)
BIBLE_REFERENCE_NG = re.compile(str(r'^\s*?(?P<book>[\d]*[^\d]+)\s*?'
r'(?P<ranges>(?:' + BIBLE_RANGE_REGEX + r'(?:%(sep_l)s|(?=\s*\n)))+)\s*$') %
BIBLE_RANGE_SPLIT = re.compile(BIBLE_SEPARATORS[u'sep_l'])
# RegEx for a reference <book>(<range>(,|(?=$)))+
BIBLE_REFERENCE = re.compile(str(r'^\s*(?!\s)(?P<book>[\d]*[^\d]+)(?<!\s)\s*'
r'(?P<ranges>(?:' + BIBLE_RANGE_REGEX + r'(?:%(sep_l)s|(?=\s*$)))+)\s*$') %
BIBLE_SEPARATORS, re.UNICODE)
def parse_reference_ng(reference):
def parse_reference(reference):
"""
This is the next generation über-awesome function that takes a person's
typed in string and converts it to a reference list, a list of references to
be queried from the Bible database files.
#####
This is a user manual like description, how the references are working.
- Each reference starts with the book name. A chapter name is manditory.
``John 3`` refers to Gospel of John chapter 3
- A reference range can be given after a range seperator.
``John 3-5`` refers to John chapters 3 to 5
- Single verses can be addressed after a verse seperator
``John 3:16`` refers to John chapter 3 verse 16
``John 3:16-4:3`` refers to John chapter 3 verse 16 to chapter 4 verse 3
- After a verse reference all further single values are treat as verse in
the last selected chapter.
``John 3:16-18`` refers to John chapter 3 verses 16 to 18
- After a list separator it is possible to refer to additional verses. They
are build analog to the first ones. This way it is possible to define each
number of verse references. It is not possible to refer to verses in
additional books.
``John 3:16,18`` refers to John chapter 3 verses 16 and 18
``John 3:16-18,20`` refers to John chapter 3 verses 16 to 18 to 20
``John 3:16-18,4:1`` refers to John chapter 3 verses 16 to 18 and
chapter 3 verse 1
- If there is a range separator without further verse declaration the last
refered chapter is addressed until the end.
#####
The ``BIBLE_RANGE`` regular expression produces match groups for verse range
declarations:
@ -58,23 +90,23 @@ def parse_reference_ng(reference):
a verse separator.
2. ``(?P<from_verse>[0-9]+)``
The verse reference ``from_verse`` is manditory
``(?:%(sep_r)s(?:`` ... ``)?)?``
A range declaration is optional. It starts with a range seperator and
contains a optional chapter and verse declaration
3. ``(?:(?P<to_chapter>[0-9]+)%(sep_v)s)?``
3. ``(?P<range_to>%(sep_r)s(?:`` ... ``)?)?``
A ``range_to`` declaration is optional. It starts with a range seperator
and contains a optional chapter and verse declaration
4. ``(?:(?P<to_chapter>[0-9]+)%(sep_v)s)?``
The ``to_chapter`` reference with seperator is equivalent to group 1.
4. ``(?P<to_verse>[0-9]+)?)?``
5. ``(?P<to_verse>[0-9]+)?)?``
The ``to_verse`` reference is equivalent to group 2.
The ``BIBLE_REFERENCE`` regular expression produces matched groups for the
whole reference string:
1. ``\s*?(?P<book>[\d]*[^\d]+)\s*?``
1. ``^\s*(?!\s)(?P<book>[\d]*[^\d]+)(?<!\s)\s*``
The ``book`` group starts with the first non-whitespace character. There
are optional leading digits followed by non-digits. The group ends
before the whitspace in front of the next digit.
2. ``(?P<ranges>(?:`` + BIBLE_RANGE_REGEX +
``(?:%(sep_l)s|(?=\s*\\n)))+)\s*$``
``(?:%(sep_l)s|(?=\s*$)))+)\s*$``
The sechon group contains all ``ranges``. This can be multiple
declarations of a BIBLE_RANGE separated by a list separator.
@ -93,181 +125,67 @@ def parse_reference_ng(reference):
"""
log.debug('parse_reference("%s")', reference)
if u'<split>' in reference:
return
ref_list = []
match = BIBLE_REFERENCE_NG.match(reference)
if match:
log.debug(u'Matched reference %s' % reference)
book = match.group(u'book')
ranges = match.group(u'ranges').split(r'\s*\.\s*')
chapter = 0
for this_range in ranges:
range_match = BIBLE_RANGE.match(this_range)
from_chapter = int(u'0' + range_match.group('from_chapter'))
from_verse = int(u'0' + range_match.group('from_verse'))
to_chapter = int(u'0' + range_match.group('to_chapter'))
to_verse = int(u'0' + range_match.group('to_verse'))
# First reference has to be a chapter
if not unified_ref_list:
if not from_chapter:
from_chapter = from_verse
from_verse = 1
# Fill missing chapter references with the last chapter
if from_chapter:
chapter = from_chapter
else:
from_chapter = chapter
if not from_verse:
from_verse = 1
if to_chapter:
if to_chapter > from_chapter:
ref_list.append((book, from_chapter, from_verse, -1))
for i in range(from_chapter + 1, to_chapter -1):
ref_list.append((book, i, 1, -1))
ref_list.append((book, to_chapter, 1, to_verse))
else:
if to_verse < from_verse:
to_verse = from_verse
ref_list.append((book, from_chapter, from_verse, to_verse))
else:
if to_verse < from_verse:
to_verse = from_verse
ref_list.append((book, from_chapter, from_verse, to_verse))
else:
log.debug(u'Invalid reference: %s' % reference)
return None
return ref_list
BIBLE_REFERENCE = re.compile(
r'^([\w ]+?) *([0-9]+)' # Initial book and chapter
r'(?: *[:|v|V] *([0-9]+))?' # Verse for first chapter
r'(?: *- *([0-9]+|end$))?' # Range for verses or chapters
r'(?:(?:,([0-9]+))?' # Second chapter
r' *[,|:|v|V] *([0-9]+|end$)' # More range for verses or chapters
r'(?: *- *([0-9]+|end$))?)?$', # End of second verse range
re.UNICODE)
def check_end(match_group):
"""
Check if a regular expression match group contains the text u'end' or
should be converted to an int.
``match_group``
The match group to check.
"""
if match_group == u'end':
return -1
else:
return int(match_group)
def parse_reference(reference):
"""
This is the über-awesome function that takes a person's typed in string
and converts it to a reference list, a list of references to be queried
from the Bible database files.
The ``BIBLE_REFERENCE`` constant regular expression produces the following
match groups:
0. (match string)
This is a special group consisting of the whole string that matched.
1. ``[\w ]+``
The book the reference is from.
2. ``[0-9]+``
The first (or only) chapter in the reference.
3. ``None`` or ``[0-9]+``
``None``, or the only verse, or the first verse in a verse range or,
the start verse in a chapter range.
4. ``None`` or ``[0-9]+`` or ``end``
``None``, or the end verse of the first verse range, or the end chapter
of a chapter range.
5. ``None`` or ``[0-9]+``
``None``, or the second chapter in multiple (non-ranged) chapters.
6. ``None`` or ``[0-9]+`` or ``end``
``None``, the start of the second verse range. or the end of a chapter
range.
7. ``None`` or ``[0-9]+`` or ``end``
``None``, or the end of the second verse range.
The reference list is a list of tuples, with each tuple structured like
this::
(book, chapter, start_verse, end_verse)
``reference``
The bible reference to parse.
Returns None or a reference list.
"""
reference = reference.strip()
log.debug('parse_reference("%s")', reference)
unified_ref_list = []
match = BIBLE_REFERENCE.match(reference)
if match:
log.debug(u'Matched reference %s' % reference)
book = match.group(1)
chapter = int(match.group(2))
if match.group(7):
# Two verse ranges
vr1_start = int(match.group(3))
vr1_end = int(match.group(4))
unified_ref_list.append((book, chapter, vr1_start, vr1_end))
vr2_start = int(match.group(6))
vr2_end = check_end(match.group(7))
if match.group(5):
# One verse range per chapter
chapter2 = int(match.group(5))
unified_ref_list.append((book, chapter2, vr2_start, vr2_end))
book = match.group(u'book')
ranges = BIBLE_RANGE_SPLIT.split(match.group(u'ranges'))
ref_list = []
chapter = 0
for this_range in ranges:
range_match = BIBLE_RANGE.match(this_range)
from_chapter = range_match.group('from_chapter')
from_verse = range_match.group('from_verse')
has_range = range_match.group('range_to')
to_chapter = range_match.group('to_chapter')
to_verse = range_match.group('to_verse')
if from_chapter:
from_chapter = int(from_chapter)
if from_verse:
from_verse = int(from_verse)
if to_chapter:
to_chapter = int(to_chapter)
if to_verse:
to_verse = int(to_verse)
# Fill chapters with reasonable values.
if from_chapter:
chapter = from_chapter
elif chapter:
from_chapter = chapter
else:
unified_ref_list.append((book, chapter, vr2_start, vr2_end))
elif match.group(6):
# Chapter range with verses
if match.group(3):
vr1_start = int(match.group(3))
else:
vr1_start = 1
if match.group(2) == match.group(4):
vr1_end = int(match.group(6))
unified_ref_list.append((book, chapter, vr1_start, vr1_end))
else:
vr1_end = -1
unified_ref_list.append((book, chapter, vr1_start, vr1_end))
vr2_end = check_end(match.group(6))
if int(match.group(4)) > chapter:
for i in range(chapter + 1, int(match.group(4)) + 1):
if i == int(match.group(4)):
unified_ref_list.append((book, i, 1, vr2_end))
else:
unified_ref_list.append((book, i, 1, -1))
elif match.group(4):
# Chapter range or chapter and verse range
if match.group(3):
vr1_start = int(match.group(3))
vr1_end = check_end(match.group(4))
if vr1_end == -1 or vr1_end > vr1_start:
unified_ref_list.append((book, chapter, vr1_start, vr1_end))
from_chapter = from_verse
from_verse = None
if to_chapter:
if to_chapter < from_chapter:
continue
else:
log.debug(u'Ambiguous reference: %s' % reference)
return None
elif match.group(4) != u'end':
for i in range(chapter, int(match.group(4)) + 1):
unified_ref_list.append((book, i, 1, -1))
chapter = to_chapter
elif to_verse:
if chapter:
to_chapter = chapter
else:
to_chapter = to_verse
# Append references to the list
if has_range:
if not from_verse:
from_verse = 1
if not to_verse:
to_verse = -1
if to_chapter > from_chapter:
ref_list.append((book, from_chapter, from_verse, -1))
for i in range(int(from_chapter) + 1, int(to_chapter) - 1):
ref_list.append((book, i, 1, -1))
ref_list.append((book, to_chapter, 1, to_verse))
elif to_verse >= from_verse:
ref_list.append((book, from_chapter, from_verse, to_verse))
elif from_verse:
ref_list.append((book, from_chapter, from_verse, from_verse))
else:
log.debug(u'Unsupported reference: %s' % reference)
return None
elif match.group(3):
# Single chapter and verse
verse = int(match.group(3))
unified_ref_list.append((book, chapter, verse, verse))
else:
# Single chapter
unified_ref_list.append((book, chapter, -1, -1))
ref_list.append((book, from_chapter, 1, -1))
return ref_list
else:
log.debug(u'Invalid reference: %s' % reference)
return None
return unified_ref_list
class SearchResults(object):

View File

@ -261,8 +261,8 @@ class BSExtract(object):
``chapter``
Chapter number
"""
print(bookname)
log.debug(u'get_bible_chapter %s,%s,%s', version, bookname, chapter)
'''
bookindex = self._get_book_index(bookname)
if chapter < 10:
chapter_string = u'00' + unicode(chapter)
@ -272,6 +272,10 @@ class BSExtract(object):
chapter_string = unicode(chapter)
chapter_url = u'http://m.bibleserver.com/text/%s/%s%s000' % \
(version, bookindex, chapter_string)
'''
chapter_url = u'http://m.bibleserver.com/#/%s/%s%s' % \
(version, bookname, chapter)
log.debug(u'URL: %s', chapter_url)
page = None
try:
@ -299,6 +303,7 @@ class BSExtract(object):
versenumber = int(verse_number.sub(r'\1', verse[u'class']))
verses[versenumber] = verse.contents[1].rstrip(u'\n')
return SearchResults(bookname, chapter, verses)
'''
def _get_book_index(self, bookname):
print bookname
bookmap = {u'Gen': u'01', u'Exod': u'02', u'Lev': u'03',
@ -319,6 +324,7 @@ class BSExtract(object):
u'1Pet': u'60', u'2Pet': u'61', u'1John': u'62', u'2John':u'63',
u'3John': u'64', u'Jude': u'65', u'Rev': u'66'}
return bookmap[bookname]
'''
class CWExtract(object):
@ -431,7 +437,7 @@ class HTTPBible(BibleDB):
Run the import. This method overrides the parent class method. Returns
``True`` on success, ``False`` on failure.
"""
self.wizard.ImportProgressBar.setMaximum(2)
self.wizard.importProgressBar.setMaximum(2)
self.wizard.incrementProgressBar('Registering bible...')
self.create_meta(u'download source', self.download_source)
self.create_meta(u'download name', self.download_name)

View File

@ -35,9 +35,14 @@ from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta
from csvbible import CSVBible
from http import HTTPBible
from openlp1 import OpenLP1Bible
from opensong import OpenSongBible
from osis import OSISBible
# Imports that might fail.
try:
from openlp1 import OpenLP1Bible
has_openlp1 = True
except ImportError:
has_openlp1 = False
log = logging.getLogger(__name__)
@ -57,6 +62,7 @@ class BibleFormat(object):
plus a few helper functions to facilitate generic handling of Bible types
for importing.
"""
_format_availability = {}
Unknown = -1
OSIS = 0
CSV = 1
@ -98,6 +104,14 @@ class BibleFormat(object):
BibleFormat.OpenLP1
]
@staticmethod
def set_availability(format, available):
BibleFormat._format_availability[format] = available
@staticmethod
def get_availability(format):
return BibleFormat._format_availability.get(format, True)
class BibleManager(object):
"""
@ -339,3 +353,8 @@ class BibleManager(object):
"""
for bible in self.db_cache:
self.db_cache[bible].finalise()
BibleFormat.set_availability(BibleFormat.OpenLP1, has_openlp1)
__all__ = [u'BibleFormat']

View File

@ -750,21 +750,21 @@ class BibleMediaItem(MediaManagerItem):
second_copyright, second_permissions)
if footer not in raw_footer:
raw_footer.append(footer)
bible_text = u'%s %s\n\n%s %s' % (verse_text, text, verse_text,
bible_text = u'%s\u00a0%s\n\n%s\u00a0%s' % (verse_text, text, verse_text,
second_text)
raw_slides.append(bible_text)
bible_text = u''
# If we are 'Verse Per Slide' then create a new slide.
elif self.parent.settings_tab.layout_style == 0:
bible_text = u'%s %s' % (verse_text, text)
bible_text = u'%s\u00a0%s' % (verse_text, text)
raw_slides.append(bible_text)
bible_text = u''
# If we are 'Verse Per Line' then force a new line.
elif self.parent.settings_tab.layout_style == 1:
bible_text = u'%s %s %s\n' % (bible_text, verse_text, text)
bible_text = u'%s %s\u00a0%s\n' % (bible_text, verse_text, text)
# We have to be 'Continuous'.
else:
bible_text = u'%s %s %s\n' % (bible_text, verse_text, text)
bible_text = u'%s %s\u00a0%s\n' % (bible_text, verse_text, text)
if first_item:
start_item = item
first_item = False

1
openlp/plugins/bibles/lib/openlp1.py Executable file → Normal file
View File

@ -62,6 +62,7 @@ class OpenLP1Bible(BibleDB):
# Create all books.
cursor.execute(u'SELECT id, testament_id, name, abbreviation FROM book')
books = cursor.fetchall()
self.wizard.importProgressBar.setMaximum(len(books) + 1)
for book in books:
if self.stop_import_flag:
connection.close()

View File

@ -134,9 +134,9 @@ class OSISBible(BibleDB):
testament)
if last_chapter == 0:
if book == u'Gen':
self.wizard.ImportProgressBar.setMaximum(1188)
self.wizard.importProgressBar.setMaximum(1188)
else:
self.wizard.ImportProgressBar.setMaximum(260)
self.wizard.importProgressBar.setMaximum(260)
if last_chapter != chapter:
if last_chapter != 0:
self.session.commit()

View File

@ -48,12 +48,12 @@ Hungarian Károli,KAR
Icelandic Bible,ICELAND
La Nuova Diodati,LND
La Parola è Vita,LM
Jacalteco, Oriental,JAC
Jacalteco - Oriental,JAC
Kekchi,KEK
Korean Bible,KOREAN
Maori Bible,MAORI
Macedonian New Testament,MNT
Mam, Central,MVC
Mam - Central,MVC
Mam de Todos Santos Chuchumatán,MVJ
Reimer 2001,REIMER
Náhuatl de Guerrero,NGU
@ -62,7 +62,7 @@ Det Norsk Bibelselskap 1930,DNB1930
Levande Bibeln,LB
O Livro,OL
João Ferreira de Almeida Atualizada,AA
Quiché, Centro Occidental,QUT
Quiché - Centro Occidental,QUT
Romanian,RMNN
Romanian,TLCR
Russian Synodal Version,RUSV
@ -77,4 +77,4 @@ Ukrainian Bible,UKR
Uspanteco,USP
1934 Vietnamese Bible,VIET
Chinese Union Version (Simplified),CUVS
Chinese Union Version (Traditional),CUV
Chinese Union Version (Traditional),CUV

Can't render this file because it has a wrong number of fields in line 51.

View File

@ -1,5 +1,5 @@
عربي, ARA
Bible, překlad 21. století, B21
Bible překlad 21. století, B21
Bible du Semeur, BDS
Българската Библия, BLG
Český ekumenický překlad, CEP
@ -8,7 +8,7 @@ Hrvatski, CRO
Version La Biblia al Dia, CST
中文和合本(简体), CUVS
Bibelen på hverdagsdansk, DK
Rev. Elberfelder, ELB
Revidierte Elberfelder, ELB
Einheitsübersetzung, EU
Gute Nachricht Bibel, GNB
Hoffnung für alle, HFA
@ -20,7 +20,7 @@ King James Version, KJV
Luther 1984, LUT
Septuaginta, LXX
Neue Genfer Übersetzung, NGÜ
New Int. Readers Version, NIRV
New International Readers Version, NIRV
New International Version, NIV
Neues Leben, NL
En Levende Bok, NOR

1 عربي, ARA عربي ARA
2 Bible, překlad 21. století, B21 Bible – překlad 21. století B21
3 Bible du Semeur, BDS Bible du Semeur BDS
4 Българската Библия, BLG Българската Библия BLG
5 Český ekumenický překlad, CEP Český ekumenický překlad CEP
8 Version La Biblia al Dia, CST Version La Biblia al Dia CST
9 中文和合本(简体), CUVS 中文和合本(简体) CUVS
10 Bibelen på hverdagsdansk, DK Bibelen på hverdagsdansk DK
11 Rev. Elberfelder, ELB Revidierte Elberfelder ELB
12 Einheitsübersetzung, EU Einheitsübersetzung EU
13 Gute Nachricht Bibel, GNB Gute Nachricht Bibel GNB
14 Hoffnung für alle, HFA Hoffnung für alle HFA
20 Luther 1984, LUT Luther 1984 LUT
21 Septuaginta, LXX Septuaginta LXX
22 Neue Genfer Übersetzung, NGÜ Neue Genfer Übersetzung NGÜ
23 New Int. Readers Version, NIRV New International Readers Version NIRV
24 New International Version, NIV New International Version NIV
25 Neues Leben, NL Neues Leben NL
26 En Levende Bok, NOR En Levende Bok NOR