forked from openlp/openlp
Head
This commit is contained in:
commit
8f47af1732
@ -27,3 +27,4 @@ openlp.pro
|
||||
tests.kdev4
|
||||
*.nja
|
||||
*.orig
|
||||
__pycache__
|
||||
|
@ -88,9 +88,9 @@ class StartTimeForm(QtGui.QDialog, Ui_StartTimeDialog):
|
||||
"""
|
||||
Split time up into hours minutes and seconds from secongs
|
||||
"""
|
||||
hours = seconds / 3600
|
||||
hours = seconds // 3600
|
||||
seconds -= 3600 * hours
|
||||
minutes = seconds / 60
|
||||
minutes = seconds // 60
|
||||
seconds -= 60 * minutes
|
||||
return hours, minutes, seconds
|
||||
|
||||
|
@ -256,7 +256,7 @@ def is_not_image_file(file_name):
|
||||
if not file_name:
|
||||
return True
|
||||
else:
|
||||
formats = [str(fmt).lower() for fmt in QtGui.QImageReader.supportedImageFormats()]
|
||||
formats = [bytes(fmt).decode().lower() for fmt in QtGui.QImageReader.supportedImageFormats()]
|
||||
file_part, file_extension = os.path.splitext(str(file_name))
|
||||
if file_extension[1:].lower() in formats and os.path.exists(file_name):
|
||||
return False
|
||||
|
@ -48,6 +48,7 @@ __default_settings__ = {
|
||||
'bibles/verse layout style': LayoutStyle.VersePerSlide,
|
||||
'bibles/book name language': LanguageSelection.Bible,
|
||||
'bibles/display brackets': DisplayStyle.NoBrackets,
|
||||
'bibles/is verse number visible': True,
|
||||
'bibles/display new chapter': False,
|
||||
'bibles/second bibles': True,
|
||||
'bibles/advanced bible': '',
|
||||
|
@ -58,6 +58,9 @@ class BiblesTab(SettingsTab):
|
||||
self.verse_display_group_box.setObjectName('verse_display_group_box')
|
||||
self.verse_display_layout = QtGui.QFormLayout(self.verse_display_group_box)
|
||||
self.verse_display_layout.setObjectName('verse_display_layout')
|
||||
self.is_verse_number_visible_check_box = QtGui.QCheckBox(self.verse_display_group_box)
|
||||
self.is_verse_number_visible_check_box.setObjectName('is_verse_number_visible_check_box')
|
||||
self.verse_display_layout.addRow(self.is_verse_number_visible_check_box)
|
||||
self.new_chapters_check_box = QtGui.QCheckBox(self.verse_display_group_box)
|
||||
self.new_chapters_check_box.setObjectName('new_chapters_check_box')
|
||||
self.verse_display_layout.addRow(self.new_chapters_check_box)
|
||||
@ -134,6 +137,7 @@ class BiblesTab(SettingsTab):
|
||||
self.left_layout.addStretch()
|
||||
self.right_layout.addStretch()
|
||||
# Signals and slots
|
||||
self.is_verse_number_visible_check_box.stateChanged.connect(self.on_is_verse_number_visible_check_box_changed)
|
||||
self.new_chapters_check_box.stateChanged.connect(self.on_new_chapters_check_box_changed)
|
||||
self.display_style_combo_box.activated.connect(self.on_display_style_combo_box_changed)
|
||||
self.bible_theme_combo_box.activated.connect(self.on_bible_theme_combo_box_changed)
|
||||
@ -156,6 +160,7 @@ class BiblesTab(SettingsTab):
|
||||
|
||||
def retranslateUi(self):
|
||||
self.verse_display_group_box.setTitle(translate('BiblesPlugin.BiblesTab', 'Verse Display'))
|
||||
self.is_verse_number_visible_check_box.setText(translate('BiblesPlugin.BiblesTab', 'Show verse numbers'))
|
||||
self.new_chapters_check_box.setText(translate('BiblesPlugin.BiblesTab', 'Only show new chapter numbers'))
|
||||
self.layout_style_label.setText(UiStrings().LayoutStyle)
|
||||
self.display_style_label.setText(UiStrings().DisplayStyle)
|
||||
@ -208,6 +213,13 @@ class BiblesTab(SettingsTab):
|
||||
def on_language_selection_combo_box_changed(self):
|
||||
self.language_selection = self.language_selection_combo_box.currentIndex()
|
||||
|
||||
def on_is_verse_number_visible_check_box_changed(self, check_state):
|
||||
"""
|
||||
Event handler for the 'verse number visible' check box
|
||||
"""
|
||||
self.is_verse_number_visible = (check_state == QtCore.Qt.Checked)
|
||||
self.check_is_verse_number_visible()
|
||||
|
||||
def on_new_chapters_check_box_changed(self, check_state):
|
||||
self.show_new_chapters = False
|
||||
# We have a set value convert to True/False.
|
||||
@ -299,11 +311,14 @@ class BiblesTab(SettingsTab):
|
||||
def load(self):
|
||||
settings = Settings()
|
||||
settings.beginGroup(self.settings_section)
|
||||
self.is_verse_number_visible = settings.value('is verse number visible')
|
||||
self.show_new_chapters = settings.value('display new chapter')
|
||||
self.display_style = settings.value('display brackets')
|
||||
self.layout_style = settings.value('verse layout style')
|
||||
self.bible_theme = settings.value('bible theme')
|
||||
self.second_bibles = settings.value('second bibles')
|
||||
self.is_verse_number_visible_check_box.setChecked(self.is_verse_number_visible)
|
||||
self.check_is_verse_number_visible()
|
||||
self.new_chapters_check_box.setChecked(self.show_new_chapters)
|
||||
self.display_style_combo_box.setCurrentIndex(self.display_style)
|
||||
self.layout_style_combo_box.setCurrentIndex(self.layout_style)
|
||||
@ -351,6 +366,7 @@ class BiblesTab(SettingsTab):
|
||||
def save(self):
|
||||
settings = Settings()
|
||||
settings.beginGroup(self.settings_section)
|
||||
settings.setValue('is verse number visible', self.is_verse_number_visible)
|
||||
settings.setValue('display new chapter', self.show_new_chapters)
|
||||
settings.setValue('display brackets', self.display_style)
|
||||
settings.setValue('verse layout style', self.layout_style)
|
||||
@ -405,3 +421,12 @@ class BiblesTab(SettingsTab):
|
||||
color.setAlpha(128)
|
||||
palette.setColor(QtGui.QPalette.Active, QtGui.QPalette.Text, color)
|
||||
return palette
|
||||
|
||||
def check_is_verse_number_visible(self):
|
||||
"""
|
||||
Enables / Disables verse settings dependent on is_verse_number_visible
|
||||
"""
|
||||
self.new_chapters_check_box.setEnabled(self.is_verse_number_visible)
|
||||
self.display_style_label.setEnabled(self.is_verse_number_visible)
|
||||
self.display_style_combo_box.setEnabled(self.is_verse_number_visible)
|
||||
|
||||
|
@ -717,7 +717,7 @@ def get_soup_for_bible_ref(reference_url, header=None, pre_parse_regex=None, pre
|
||||
return None
|
||||
page_source = page.read()
|
||||
if pre_parse_regex and pre_parse_substitute is not None:
|
||||
page_source = re.sub(pre_parse_regex, pre_parse_substitute, page_source)
|
||||
page_source = re.sub(pre_parse_regex, pre_parse_substitute, page_source.decode())
|
||||
soup = None
|
||||
try:
|
||||
soup = BeautifulSoup(page_source)
|
||||
|
@ -803,20 +803,20 @@ class BibleMediaItem(MediaManagerItem):
|
||||
verses.add(book, chapter, verse, version, copyright, permissions)
|
||||
verse_text = self.formatVerse(old_chapter, chapter, verse)
|
||||
if second_bible:
|
||||
bible_text = '%s %s\n\n%s %s' % (verse_text, text, verse_text, second_text)
|
||||
bible_text = '%s%s\n\n%s %s' % (verse_text, text, verse_text, second_text)
|
||||
raw_slides.append(bible_text.rstrip())
|
||||
bible_text = ''
|
||||
# If we are 'Verse Per Slide' then create a new slide.
|
||||
elif self.settings.layout_style == LayoutStyle.VersePerSlide:
|
||||
bible_text = '%s %s' % (verse_text, text)
|
||||
bible_text = '%s%s' % (verse_text, text)
|
||||
raw_slides.append(bible_text.rstrip())
|
||||
bible_text = ''
|
||||
# If we are 'Verse Per Line' then force a new line.
|
||||
elif self.settings.layout_style == LayoutStyle.VersePerLine:
|
||||
bible_text = '%s%s %s\n' % (bible_text, verse_text, text)
|
||||
bible_text = '%s%s%s\n' % (bible_text, verse_text, text)
|
||||
# We have to be 'Continuous'.
|
||||
else:
|
||||
bible_text = '%s %s %s\n' % (bible_text, verse_text, text)
|
||||
bible_text = '%s %s%s\n' % (bible_text, verse_text, text)
|
||||
bible_text = bible_text.strip(' ')
|
||||
if not old_item:
|
||||
start_item = bitem
|
||||
@ -943,17 +943,19 @@ class BibleMediaItem(MediaManagerItem):
|
||||
The verse number (int).
|
||||
"""
|
||||
verse_separator = get_reference_separator('sep_v_display')
|
||||
if not self.settings.is_verse_number_visible:
|
||||
return ''
|
||||
if not self.settings.show_new_chapters or old_chapter != chapter:
|
||||
verse_text = str(chapter) + verse_separator + str(verse)
|
||||
else:
|
||||
verse_text = str(verse)
|
||||
if self.settings.display_style == DisplayStyle.Round:
|
||||
return '{su}(%s){/su}' % verse_text
|
||||
return '{su}(%s){/su} ' % verse_text
|
||||
if self.settings.display_style == DisplayStyle.Curly:
|
||||
return '{su}{%s}{/su}' % verse_text
|
||||
return '{su}{%s}{/su} ' % verse_text
|
||||
if self.settings.display_style == DisplayStyle.Square:
|
||||
return '{su}[%s]{/su}' % verse_text
|
||||
return '{su}%s{/su}' % verse_text
|
||||
return '{su}[%s]{/su} ' % verse_text
|
||||
return '{su}%s{/su} ' % verse_text
|
||||
|
||||
def search(self, string, showError):
|
||||
"""
|
||||
|
@ -198,21 +198,7 @@ class RemoteTab(SettingsTab):
|
||||
"""
|
||||
Update the display based on the data input on the screen
|
||||
"""
|
||||
ip_address = 'localhost'
|
||||
if self.address_edit.text() == ZERO_URL:
|
||||
interfaces = QtNetwork.QNetworkInterface.allInterfaces()
|
||||
for interface in interfaces:
|
||||
if not interface.isValid():
|
||||
continue
|
||||
if not (interface.flags() & (QtNetwork.QNetworkInterface.IsUp | QtNetwork.QNetworkInterface.IsRunning)):
|
||||
continue
|
||||
for address in interface.addressEntries():
|
||||
ip = address.ip()
|
||||
if ip.protocol() == 0 and ip != QtNetwork.QHostAddress.LocalHost:
|
||||
ip_address = ip
|
||||
break
|
||||
else:
|
||||
ip_address = self.address_edit.text()
|
||||
ip_address = self.get_ip_address(self.address_edit.text())
|
||||
http_url = 'http://%s:%s/' % (ip_address, self.port_spin_box.value())
|
||||
https_url = 'https://%s:%s/' % (ip_address, self.https_port_spin_box.value())
|
||||
self.remote_url.setText('<a href="%s">%s</a>' % (http_url, http_url))
|
||||
@ -226,6 +212,25 @@ class RemoteTab(SettingsTab):
|
||||
self.live_url.setText('<a href="%s">%s</a>' % (http_url_temp, http_url_temp))
|
||||
self.live_https_url.setText('<a href="%s">%s</a>' % (https_url_temp, https_url_temp))
|
||||
|
||||
def get_ip_address(self, ip_address):
|
||||
"""
|
||||
returns the IP address in dependency of the passed address
|
||||
ip_address == 0.0.0.0: return the IP address of the first valid interface
|
||||
else: return ip_address
|
||||
"""
|
||||
if ip_address == ZERO_URL:
|
||||
interfaces = QtNetwork.QNetworkInterface.allInterfaces()
|
||||
for interface in interfaces:
|
||||
if not interface.isValid():
|
||||
continue
|
||||
if not (interface.flags() & (QtNetwork.QNetworkInterface.IsUp | QtNetwork.QNetworkInterface.IsRunning)):
|
||||
continue
|
||||
for address in interface.addressEntries():
|
||||
ip = address.ip()
|
||||
if ip.protocol() == QtNetwork.QAbstractSocket.IPv4Protocol and ip != QtNetwork.QHostAddress.LocalHost:
|
||||
return ip.toString()
|
||||
return ip_address
|
||||
|
||||
def load(self):
|
||||
"""
|
||||
Load the configuration and update the server configuration if necessary
|
||||
|
@ -46,7 +46,13 @@ log = logging.getLogger(__name__)
|
||||
|
||||
WHITESPACE = re.compile(r'[\W_]+', re.UNICODE)
|
||||
APOSTROPHE = re.compile('[\'`’ʻ′]', re.UNICODE)
|
||||
PATTERN = re.compile(r"\\([a-z]{1,32})(-?\d{1,10})?[ ]?|\\'([0-9a-f]{2})|\\([^a-z])|([{}])|[\r\n]+|(.)", re.I)
|
||||
# PATTERN will look for the next occurence of one of these symbols:
|
||||
# \controlword - optionally preceded by \*, optionally followed by a number
|
||||
# \'## - where ## is a pair of hex digits, representing a single character
|
||||
# \# - where # is a single non-alpha character, representing a special symbol
|
||||
# { or } - marking the beginning/end of a group
|
||||
# a run of characters without any \ { } or end-of-line
|
||||
PATTERN = re.compile(r"(\\\*)?\\([a-z]{1,32})(-?\d{1,10})?[ ]?|\\'([0-9a-f]{2})|\\([^a-z*])|([{}])|[\r\n]+|([^\\{}\r\n]+)", re.I)
|
||||
# RTF control words which specify a "destination" to be ignored.
|
||||
DESTINATIONS = frozenset((
|
||||
'aftncn', 'aftnsep', 'aftnsepc', 'annotation', 'atnauthor',
|
||||
@ -57,8 +63,8 @@ DESTINATIONS = frozenset((
|
||||
'datafield', 'datastore', 'defchp', 'defpap', 'do', 'doccomm',
|
||||
'docvar', 'dptxbxtext', 'ebcend', 'ebcstart', 'factoidname',
|
||||
'falt', 'fchars', 'ffdeftext', 'ffentrymcr', 'ffexitmcr',
|
||||
'ffformat', 'ffhelptext', 'ffl', 'ffname', 'ffstattext', 'field',
|
||||
'file', 'filetbl', 'fldinst', 'fldrslt', 'fldtype', 'fname',
|
||||
'ffformat', 'ffhelptext', 'ffl', 'ffname', 'ffstattext',
|
||||
'file', 'filetbl', 'fldinst', 'fldtype', 'fname',
|
||||
'fontemb', 'fontfile', 'footer', 'footerf', 'footerl', 'footerr',
|
||||
'footnote', 'formfield', 'ftncn', 'ftnsep', 'ftnsepc', 'g',
|
||||
'generator', 'gridtbl', 'header', 'headerf', 'headerl',
|
||||
@ -106,6 +112,11 @@ DESTINATIONS = frozenset((
|
||||
'xmlclose', 'xmlname', 'xmlnstbl', 'xmlopen'))
|
||||
# Translation of some special characters.
|
||||
SPECIAL_CHARS = {
|
||||
'\n': '\n',
|
||||
'\r': '\n',
|
||||
'~': '\u00A0',
|
||||
'-': '\u00AD',
|
||||
'_': '\u2011',
|
||||
'par': '\n',
|
||||
'sect': '\n\n',
|
||||
# Required page and column break.
|
||||
@ -132,16 +143,19 @@ SPECIAL_CHARS = {
|
||||
'zwj': '\u200D',
|
||||
'zwnj': '\u200C'}
|
||||
CHARSET_MAPPING = {
|
||||
'fcharset0': 'cp1252',
|
||||
'fcharset161': 'cp1253',
|
||||
'fcharset162': 'cp1254',
|
||||
'fcharset163': 'cp1258',
|
||||
'fcharset177': 'cp1255',
|
||||
'fcharset178': 'cp1256',
|
||||
'fcharset186': 'cp1257',
|
||||
'fcharset204': 'cp1251',
|
||||
'fcharset222': 'cp874',
|
||||
'fcharset238': 'cp1250'}
|
||||
'0': 'cp1252',
|
||||
'128': 'cp932',
|
||||
'129': 'cp949',
|
||||
'134': 'cp936',
|
||||
'161': 'cp1253',
|
||||
'162': 'cp1254',
|
||||
'163': 'cp1258',
|
||||
'177': 'cp1255',
|
||||
'178': 'cp1256',
|
||||
'186': 'cp1257',
|
||||
'204': 'cp1251',
|
||||
'222': 'cp874',
|
||||
'238': 'cp1250'}
|
||||
|
||||
|
||||
class VerseType(object):
|
||||
@ -351,7 +365,7 @@ def retrieve_windows_encoding(recommendation=None):
|
||||
if recommendation == encodings[index][0]:
|
||||
recommended_index = index
|
||||
break
|
||||
if recommended_index > 0:
|
||||
if recommended_index > -1:
|
||||
choice = QtGui.QInputDialog.getItem(None,
|
||||
translate('SongsPlugin', 'Character Encoding'),
|
||||
translate('SongsPlugin', 'The codepage setting is responsible\n'
|
||||
@ -365,7 +379,7 @@ def retrieve_windows_encoding(recommendation=None):
|
||||
[pair[1] for pair in encodings], 0, False)
|
||||
if not choice[1]:
|
||||
return None
|
||||
return filter(lambda item: item[1] == choice[0], encodings)[0][0]
|
||||
return next(filter(lambda item: item[1] == choice[0], encodings))[0]
|
||||
|
||||
|
||||
def clean_string(string):
|
||||
@ -521,43 +535,59 @@ def strip_rtf(text, default_encoding=None):
|
||||
curskip = 0
|
||||
# Output buffer.
|
||||
out = []
|
||||
# Encoded buffer.
|
||||
ebytes = bytearray()
|
||||
for match in PATTERN.finditer(text):
|
||||
word, arg, hex, char, brace, tchar = match.groups()
|
||||
iinu, word, arg, hex, char, brace, tchar = match.groups()
|
||||
# \x (non-alpha character)
|
||||
if char:
|
||||
if char in '\\{}':
|
||||
tchar = char
|
||||
else:
|
||||
word = char
|
||||
# Flush encoded buffer to output buffer
|
||||
if ebytes and not hex and not tchar:
|
||||
failed = False
|
||||
while True:
|
||||
try:
|
||||
encoding, default_encoding = get_encoding(font, font_table, default_encoding, failed=failed)
|
||||
if not encoding:
|
||||
return None
|
||||
dbytes = ebytes.decode(encoding)
|
||||
# Code 5C is a peculiar case with Windows Codepage 932
|
||||
if encoding == 'cp932' and '\\' in dbytes:
|
||||
dbytes = dbytes.replace('\\', '\u00A5')
|
||||
out.append(dbytes)
|
||||
ebytes.clear()
|
||||
except UnicodeDecodeError:
|
||||
failed = True
|
||||
else:
|
||||
break
|
||||
# {}
|
||||
if brace:
|
||||
curskip = 0
|
||||
if brace == '{':
|
||||
# Push state
|
||||
stack.append((ucskip, ignorable, font))
|
||||
elif brace == '}':
|
||||
elif brace == '}' and len(stack) > 0:
|
||||
# Pop state
|
||||
ucskip, ignorable, font = stack.pop()
|
||||
# \x (not a letter)
|
||||
elif char:
|
||||
curskip = 0
|
||||
if char == '~' and not ignorable:
|
||||
out.append('\xA0')
|
||||
elif char in '{}\\' and not ignorable:
|
||||
out.append(char)
|
||||
elif char == '-' and not ignorable:
|
||||
out.append('\u00AD')
|
||||
elif char == '_' and not ignorable:
|
||||
out.append('\u2011')
|
||||
elif char == '*':
|
||||
ignorable = True
|
||||
# \command
|
||||
elif word:
|
||||
curskip = 0
|
||||
if word in DESTINATIONS:
|
||||
ignorable = True
|
||||
elif word in SPECIAL_CHARS:
|
||||
out.append(SPECIAL_CHARS[word])
|
||||
if not ignorable:
|
||||
out.append(SPECIAL_CHARS[word])
|
||||
elif word == 'uc':
|
||||
ucskip = int(arg)
|
||||
elif word == ' ':
|
||||
elif word == 'u':
|
||||
c = int(arg)
|
||||
if c < 0:
|
||||
c += 0x10000
|
||||
out.append(chr(c))
|
||||
if not ignorable:
|
||||
out.append(chr(c))
|
||||
curskip = ucskip
|
||||
elif word == 'fonttbl':
|
||||
ignorable = True
|
||||
@ -565,31 +595,24 @@ def strip_rtf(text, default_encoding=None):
|
||||
font = arg
|
||||
elif word == 'ansicpg':
|
||||
font_table[font] = 'cp' + arg
|
||||
elif word == 'fcharset' and font not in font_table and word + arg in CHARSET_MAPPING:
|
||||
# \ansicpg overrides \fcharset, if present.
|
||||
font_table[font] = CHARSET_MAPPING[word + arg]
|
||||
elif word == 'fcharset' and font not in font_table and arg in CHARSET_MAPPING:
|
||||
font_table[font] = CHARSET_MAPPING[arg]
|
||||
elif word == 'fldrslt':
|
||||
pass
|
||||
# \* 'Ignore if not understood' marker
|
||||
elif iinu:
|
||||
ignorable = True
|
||||
# \'xx
|
||||
elif hex:
|
||||
if curskip > 0:
|
||||
curskip -= 1
|
||||
elif not ignorable:
|
||||
charcode = int(hex, 16)
|
||||
failed = False
|
||||
while True:
|
||||
try:
|
||||
encoding, default_encoding = get_encoding(font, font_table, default_encoding, failed=failed)
|
||||
if not encoding:
|
||||
return None
|
||||
out.append(chr(charcode).decode(encoding))
|
||||
except UnicodeDecodeError:
|
||||
failed = True
|
||||
else:
|
||||
break
|
||||
ebytes.append(int(hex, 16))
|
||||
elif tchar:
|
||||
if curskip > 0:
|
||||
curskip -= 1
|
||||
elif not ignorable:
|
||||
out.append(tchar)
|
||||
ebytes += tchar.encode()
|
||||
text = ''.join(out)
|
||||
return text, default_encoding
|
||||
|
||||
|
@ -122,7 +122,7 @@ class EasyWorshipSongImport(SongImport):
|
||||
db_file.seek(120)
|
||||
field_info = db_file.read(num_fields * 2)
|
||||
db_file.seek(4 + (num_fields * 4) + 261, os.SEEK_CUR)
|
||||
field_names = db_file.read(header_size - db_file.tell()).split('\0', num_fields)
|
||||
field_names = db_file.read(header_size - db_file.tell()).split(b'\0', num_fields)
|
||||
field_names.pop()
|
||||
field_descs = []
|
||||
for i, field_name in enumerate(field_names):
|
||||
@ -132,12 +132,12 @@ class EasyWorshipSongImport(SongImport):
|
||||
# Pick out the field description indexes we will need
|
||||
try:
|
||||
success = True
|
||||
fi_title = self.findField('Title')
|
||||
fi_author = self.findField('Author')
|
||||
fi_copy = self.findField('Copyright')
|
||||
fi_admin = self.findField('Administrator')
|
||||
fi_words = self.findField('Words')
|
||||
fi_ccli = self.findField('Song Number')
|
||||
fi_title = self.findField(b'Title')
|
||||
fi_author = self.findField(b'Author')
|
||||
fi_copy = self.findField(b'Copyright')
|
||||
fi_admin = self.findField(b'Administrator')
|
||||
fi_words = self.findField(b'Words')
|
||||
fi_ccli = self.findField(b'Song Number')
|
||||
except IndexError:
|
||||
# This is the wrong table
|
||||
success = False
|
||||
@ -150,7 +150,7 @@ class EasyWorshipSongImport(SongImport):
|
||||
cur_block_pos = header_size + ((cur_block - 1) * 1024 * block_size)
|
||||
db_file.seek(cur_block_pos)
|
||||
cur_block, rec_count = struct.unpack('<h2xh', db_file.read(6))
|
||||
rec_count = (rec_count + record_size) / record_size
|
||||
rec_count = (rec_count + record_size) // record_size
|
||||
block_list.append((cur_block_pos, rec_count))
|
||||
total_count += rec_count
|
||||
self.import_wizard.progress_bar.setMaximum(total_count)
|
||||
@ -164,7 +164,7 @@ class EasyWorshipSongImport(SongImport):
|
||||
raw_record = db_file.read(record_size)
|
||||
self.fields = self.recordStruct.unpack(raw_record)
|
||||
self.setDefaults()
|
||||
self.title = self.getField(fi_title)
|
||||
self.title = self.getField(fi_title).decode()
|
||||
# Get remaining fields.
|
||||
copy = self.getField(fi_copy)
|
||||
admin = self.getField(fi_admin)
|
||||
@ -173,25 +173,26 @@ class EasyWorshipSongImport(SongImport):
|
||||
words = self.getField(fi_words)
|
||||
# Set the SongImport object members.
|
||||
if copy:
|
||||
self.copyright = copy
|
||||
self.copyright = copy.decode()
|
||||
if admin:
|
||||
if copy:
|
||||
self.copyright += ', '
|
||||
self.copyright += translate('SongsPlugin.EasyWorshipSongImport', 'Administered by %s') % admin
|
||||
self.copyright += translate('SongsPlugin.EasyWorshipSongImport',
|
||||
'Administered by %s') % admin.decode()
|
||||
if ccli:
|
||||
self.ccliNumber = ccli
|
||||
self.ccliNumber = ccli.decode()
|
||||
if authors:
|
||||
# Split up the authors
|
||||
author_list = authors.split('/')
|
||||
author_list = authors.split(b'/')
|
||||
if len(author_list) < 2:
|
||||
author_list = authors.split(';')
|
||||
author_list = authors.split(b';')
|
||||
if len(author_list) < 2:
|
||||
author_list = authors.split(',')
|
||||
author_list = authors.split(b',')
|
||||
for author_name in author_list:
|
||||
self.addAuthor(author_name.strip())
|
||||
self.addAuthor(author_name.decode().strip())
|
||||
if words:
|
||||
# Format the lyrics
|
||||
result = strip_rtf(words, self.encoding)
|
||||
result = strip_rtf(words.decode(), self.encoding)
|
||||
if result is None:
|
||||
return
|
||||
words, self.encoding = result
|
||||
@ -267,14 +268,14 @@ class EasyWorshipSongImport(SongImport):
|
||||
field = self.fields[field_desc_index]
|
||||
field_desc = self.fieldDescs[field_desc_index]
|
||||
# Return None in case of 'blank' entries
|
||||
if isinstance(field, str):
|
||||
if not field.rstrip('\0'):
|
||||
if isinstance(field, bytes):
|
||||
if not field.rstrip(b'\0'):
|
||||
return None
|
||||
elif field == 0:
|
||||
return None
|
||||
# Format the field depending on the field type
|
||||
if field_desc.field_type == FieldType.String:
|
||||
return field.rstrip('\0')
|
||||
return field.rstrip(b'\0')
|
||||
elif field_desc.field_type == FieldType.Int16:
|
||||
return field ^ 0x8000
|
||||
elif field_desc.field_type == FieldType.Int32:
|
||||
@ -291,12 +292,12 @@ class EasyWorshipSongImport(SongImport):
|
||||
self.memoFile.seek(8, os.SEEK_CUR)
|
||||
elif memo_block_type == 3:
|
||||
if sub_block > 63:
|
||||
return ''
|
||||
return b''
|
||||
self.memoFile.seek(11 + (5 * sub_block), os.SEEK_CUR)
|
||||
sub_block_start, = struct.unpack('B', self.memoFile.read(1))
|
||||
self.memoFile.seek(block_start + (sub_block_start * 16))
|
||||
else:
|
||||
return ''
|
||||
return b''
|
||||
return self.memoFile.read(blob_size)
|
||||
else:
|
||||
return 0
|
||||
|
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
|
||||
|
||||
@ -50,7 +50,7 @@ IS_WIN = sys.platform.startswith('win')
|
||||
|
||||
|
||||
VERS = {
|
||||
'Python': '2.6',
|
||||
'Python': '3.0',
|
||||
'PyQt4': '4.6',
|
||||
'Qt4': '4.6',
|
||||
'sqlalchemy': '0.5',
|
||||
@ -64,6 +64,7 @@ WIN32_MODULES = [
|
||||
'win32ui',
|
||||
'pywintypes',
|
||||
'pyodbc',
|
||||
'icu',
|
||||
]
|
||||
|
||||
MODULES = [
|
||||
@ -77,6 +78,7 @@ MODULES = [
|
||||
'PyQt4.QtWebKit',
|
||||
'PyQt4.phonon',
|
||||
'sqlalchemy',
|
||||
'alembic',
|
||||
'sqlite3',
|
||||
'lxml',
|
||||
'chardet',
|
||||
@ -84,8 +86,6 @@ MODULES = [
|
||||
'bs4',
|
||||
'mako',
|
||||
'uno',
|
||||
'icu',
|
||||
'bs4',
|
||||
]
|
||||
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
|
||||
|
||||
@ -102,7 +102,7 @@ class CommandStack(object):
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def next(self):
|
||||
def __next__(self):
|
||||
if self.current_index == len(self.data):
|
||||
raise StopIteration
|
||||
else:
|
||||
@ -145,9 +145,9 @@ def print_quiet(text, linefeed=True):
|
||||
global quiet_mode
|
||||
if not quiet_mode:
|
||||
if linefeed:
|
||||
print text
|
||||
print(text)
|
||||
else:
|
||||
print text,
|
||||
print(text, end=' ')
|
||||
|
||||
def print_verbose(text):
|
||||
"""
|
||||
|
2
setup.py
2
setup.py
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
|
||||
|
||||
|
@ -187,7 +187,7 @@ class TestLib(TestCase):
|
||||
"""
|
||||
Test the get_text_file_string() method when a read error happens
|
||||
"""
|
||||
with patch('openlp.core.lib.os.path.isfile') as mocked_isfile, patch('builtins.open') as mocked_open:
|
||||
with patch('openlp.core.lib.os.path.isfile') as mocked_isfile, patch('openlp.core.lib.open', create=True) as mocked_open:
|
||||
# GIVEN: A mocked-out open() which raises an exception and isfile returns True
|
||||
filename = 'testfile.txt'
|
||||
mocked_isfile.return_value = True
|
||||
@ -252,7 +252,7 @@ class TestLib(TestCase):
|
||||
# GIVEN: A set of mocked-out Qt classes
|
||||
mocked_byte_array = MagicMock()
|
||||
MockedQtCore.QByteArray.return_value = mocked_byte_array
|
||||
mocked_byte_array.toBase64.return_value = 'base64mock'
|
||||
mocked_byte_array.toBase64.return_value = QtCore.QByteArray('base64mock')
|
||||
mocked_buffer = MagicMock()
|
||||
MockedQtCore.QBuffer.return_value = mocked_buffer
|
||||
MockedQtCore.QIODevice.WriteOnly = 'writeonly'
|
||||
|
@ -0,0 +1,116 @@
|
||||
"""
|
||||
This module contains tests for the versereferencelist submodule of the Bibles plugin.
|
||||
"""
|
||||
from unittest import TestCase
|
||||
from openlp.plugins.bibles.lib.versereferencelist import VerseReferenceList
|
||||
|
||||
class TestVerseReferenceList(TestCase):
|
||||
def setUp(self):
|
||||
"""
|
||||
Initializes all we need
|
||||
"""
|
||||
|
||||
def add_first_verse_test(self):
|
||||
"""
|
||||
Test the addition of a verse to the empty list
|
||||
"""
|
||||
# GIVEN: an empty list
|
||||
reference_list = VerseReferenceList()
|
||||
book = 'testBook'
|
||||
chapter = 1
|
||||
verse = 1
|
||||
version = 'testVersion'
|
||||
copyright = 'testCopyright'
|
||||
permission = 'testPermision'
|
||||
|
||||
# WHEN: We add it to the verse list
|
||||
reference_list.add(book, chapter, verse, version, copyright, permission)
|
||||
|
||||
# THEN: The entries should be in the first entry of the list
|
||||
self.assertEqual(reference_list.current_index, 0, 'The current index should be 0')
|
||||
self.assertEqual(reference_list.verse_list[0]['book'], book, 'The book in first entry should be %s' % book)
|
||||
self.assertEqual(reference_list.verse_list[0]['chapter'], chapter, 'The chapter in first entry should be %u' % chapter)
|
||||
self.assertEqual(reference_list.verse_list[0]['start'], verse, 'The start in first entry should be %u' % verse)
|
||||
self.assertEqual(reference_list.verse_list[0]['version'], version, 'The version in first entry should be %s' % version)
|
||||
self.assertEqual(reference_list.verse_list[0]['end'], verse, 'The end in first entry should be %u' % verse)
|
||||
|
||||
def add_next_verse_test(self):
|
||||
"""
|
||||
Test the addition of the following verse
|
||||
"""
|
||||
# GIVEN: 1 line in the list of verses
|
||||
book = 'testBook'
|
||||
chapter = 1
|
||||
verse = 1
|
||||
next_verse = 2
|
||||
version = 'testVersion'
|
||||
copyright = 'testCopyright'
|
||||
permission = 'testPermision'
|
||||
reference_list = VerseReferenceList()
|
||||
reference_list.add(book, chapter, verse, version, copyright, permission)
|
||||
|
||||
# WHEN: We add the following verse to the verse list
|
||||
reference_list.add(book, chapter, next_verse, version, copyright, permission)
|
||||
|
||||
# THEN: The current index should be 0 and the end pointer of the entry should be '2'
|
||||
self.assertEqual(reference_list.current_index, 0, 'The current index should be 0')
|
||||
self.assertEqual(reference_list.verse_list[0]['end'], next_verse, 'The end in first entry should be %u' % next_verse)
|
||||
|
||||
def add_another_verse_test(self):
|
||||
"""
|
||||
Test the addition of a verse in another book
|
||||
"""
|
||||
# GIVEN: 1 line in the list of verses
|
||||
book = 'testBook'
|
||||
chapter = 1
|
||||
verse = 1
|
||||
next_verse = 2
|
||||
another_book = 'testBook2'
|
||||
another_chapter = 2
|
||||
another_verse = 5
|
||||
version = 'testVersion'
|
||||
copyright = 'testCopyright'
|
||||
permission = 'testPermision'
|
||||
reference_list = VerseReferenceList()
|
||||
reference_list.add(book, chapter, verse, version, copyright, permission)
|
||||
|
||||
# WHEN: We add a verse of another book to the verse list
|
||||
reference_list.add(another_book, another_chapter, another_verse, version, copyright, permission)
|
||||
|
||||
# THEN: the current index should be 1
|
||||
self.assertEqual(reference_list.current_index, 1, 'The current index should be 1')
|
||||
|
||||
def add_version_test(self):
|
||||
"""
|
||||
Test the addition of a version to the list
|
||||
"""
|
||||
# GIVEN: version, copyright and permission
|
||||
reference_list = VerseReferenceList()
|
||||
version = 'testVersion'
|
||||
copyright = 'testCopyright'
|
||||
permission = 'testPermision'
|
||||
|
||||
# WHEN: a not existing version will be added
|
||||
reference_list.add_version(version, copyright, permission)
|
||||
|
||||
# THEN: the data will be appended to the list
|
||||
self.assertEqual(len(reference_list.version_list), 1, 'The version data should be appended')
|
||||
self.assertEqual(reference_list.version_list[0], {'version': version, 'copyright': copyright, 'permission': permission},
|
||||
'The version data should be appended')
|
||||
|
||||
def add_existing_version_test(self):
|
||||
"""
|
||||
Test the addition of an existing version to the list
|
||||
"""
|
||||
# GIVEN: version, copyright and permission, added to the version list
|
||||
reference_list = VerseReferenceList()
|
||||
version = 'testVersion'
|
||||
copyright = 'testCopyright'
|
||||
permission = 'testPermision'
|
||||
reference_list.add_version(version, copyright, permission)
|
||||
|
||||
# WHEN: an existing version will be added
|
||||
reference_list.add_version(version, copyright, permission)
|
||||
|
||||
# THEN: the data will not be appended to the list
|
||||
self.assertEqual(len(reference_list.version_list), 1, 'The version data should not be appended')
|
@ -2,6 +2,7 @@
|
||||
This module contains tests for the lib submodule of the Remotes plugin.
|
||||
"""
|
||||
import os
|
||||
import re
|
||||
|
||||
from unittest import TestCase
|
||||
from tempfile import mkstemp
|
||||
@ -52,6 +53,27 @@ class TestRemoteTab(TestCase):
|
||||
del self.form
|
||||
os.unlink(self.ini_file)
|
||||
|
||||
def get_ip_address_default_test(self):
|
||||
"""
|
||||
Test the get_ip_address function with ZERO_URL
|
||||
"""
|
||||
# WHEN: the default ip address is given
|
||||
ip_address = self.form.get_ip_address(ZERO_URL)
|
||||
# THEN: the default ip address will be returned
|
||||
self.assertTrue(re.match('\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}', ip_address), 'The return value should be a valid ip address')
|
||||
|
||||
def get_ip_address_with_ip_test(self):
|
||||
"""
|
||||
Test the get_ip_address function with given ip address
|
||||
"""
|
||||
# GIVEN: A mocked location
|
||||
# GIVEN: An ip address
|
||||
given_ip = '192.168.1.1'
|
||||
# WHEN: the default ip address is given
|
||||
ip_address = self.form.get_ip_address(given_ip)
|
||||
# THEN: the default ip address will be returned
|
||||
self.assertEqual(ip_address, given_ip, 'The return value should be %s' % given_ip)
|
||||
|
||||
def set_basic_urls_test(self):
|
||||
"""
|
||||
Test the set_urls function with standard defaults
|
||||
|
@ -74,18 +74,18 @@ TEST_FIELD_DESCS = [TestFieldDesc('Title', FieldType.String, 50),
|
||||
TestFieldDesc('Default Background', FieldType.Logical, 1), TestFieldDesc('Words', FieldType.Memo, 250),
|
||||
TestFieldDesc('Words', FieldType.Memo, 250), TestFieldDesc('BK Bitmap', FieldType.Blob, 10),
|
||||
TestFieldDesc('Last Modified', FieldType.Timestamp, 10)]
|
||||
TEST_FIELDS = ['A Heart Like Thine\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0', 32868, 2147483750,
|
||||
129, '{\\rtf1\\ansi\\deff0\\deftab254{\\fonttbl{\\f0\\fnil\\fcharset0 Arial;}{\\f1\\fnil\\fcharset0 Verdana;}}'
|
||||
'{\\colortbl\\red0\\green0\\blue0;\\red255\\green0\\blue0;\\red0\\green128\\blue0;\\red0\\green0\\blue255;'
|
||||
'\\red255\\green255\\blue0;\\red255\\green0\\blue255;\\red128\\g<EFBFBD><EFBFBD>\7\0f\r\0\0\1\0',
|
||||
'{\\rtf1\\ansi\\deff0\\deftab254{\\fonttbl{\\f0\\fnil\\fcharset0 Arial;}{\\f1\\fnil\\fcharset0 Verdana;}}'
|
||||
'{\\colortbl\\red0\\green0\\blue0;\\red255\\green0\\blue0;\\red0\\green128\\blue0;\\red0\\green0\\blue255;\\red255'
|
||||
'\\green255\\blue0;\\red255\\green0\\blue255;\\red128\\g><3E>\6\0<EFBFBD>\6\0\0\1\0', '\0\0\0\0\0\0\0\0\0\0', 0]
|
||||
TEST_FIELDS = [b'A Heart Like Thine\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0', 32868, 2147483750,
|
||||
129, b'{\\rtf1\\ansi\\deff0\\deftab254{\\fonttbl{\\f0\\fnil\\fcharset0 Arial;}{\\f1\\fnil\\fcharset0 Verdana;}}'
|
||||
b'{\\colortbl\\red0\\green0\\blue0;\\red255\\green0\\blue0;\\red0\\green128\\blue0;\\red0\\green0\\blue255;'
|
||||
b'\\red255\\green255\\blue0;\\red255\\green0\\blue255;\\red128\\g\xBF\xBD\7\0f\r\0\0\1\0',
|
||||
b'{\\rtf1\\ansi\\deff0\\deftab254{\\fonttbl{\\f0\\fnil\\fcharset0 Arial;}{\\f1\\fnil\\fcharset0 Verdana;}}'
|
||||
b'{\\colortbl\\red0\\green0\\blue0;\\red255\\green0\\blue0;\\red0\\green128\\blue0;\\red0\\green0\\blue255;\\red255'
|
||||
b'\\green255\\blue0;\\red255\\green0\\blue255;\\red128\\g\6\0\xEF\xBF\xBD\6\0\0\1\0', b'\0\0\0\0\0\0\0\0\0\0', 0]
|
||||
GET_MEMO_FIELD_TEST_RESULTS = [
|
||||
(4, '\2', {'return': '\2','read': (1, 3430), 'seek': (507136, (8, os.SEEK_CUR))}),
|
||||
(4, '\3', {'return': '', 'read': (1, ), 'seek': (507136, )}),
|
||||
(5, '\3', {'return': '\3', 'read': (1, 1725), 'seek': (3220111360, (41, os.SEEK_CUR), 3220111408)}),
|
||||
(5, '\4', {'return': '', 'read': (), 'seek': ()})]
|
||||
(4, b'\2', {'return': b'\2','read': (1, 3430), 'seek': (507136, (8, os.SEEK_CUR))}),
|
||||
(4, b'\3', {'return': b'', 'read': (1, ), 'seek': (507136, )}),
|
||||
(5, b'\3', {'return': b'\3', 'read': (1, 1725), 'seek': (3220111360, (41, os.SEEK_CUR), 3220111408)}),
|
||||
(5, b'\4', {'return': b'', 'read': (), 'seek': ()})]
|
||||
|
||||
class TestEasyWorshipSongImport(TestCase):
|
||||
"""
|
||||
@ -189,7 +189,7 @@ class TestEasyWorshipSongImport(TestCase):
|
||||
importer.encoding = TEST_DATA_ENCODING
|
||||
importer.fields = TEST_FIELDS
|
||||
importer.fieldDescs = TEST_FIELD_DESCS
|
||||
field_results = [(0, 'A Heart Like Thine'), (1, 100), (2, 102), (3, True), (6, None), (7, None)]
|
||||
field_results = [(0, b'A Heart Like Thine'), (1, 100), (2, 102), (3, True), (6, None), (7, None)]
|
||||
|
||||
# WHEN: Called with test data
|
||||
for field_index, result in field_results:
|
||||
@ -276,7 +276,7 @@ class TestEasyWorshipSongImport(TestCase):
|
||||
# GIVEN: A mocked out SongImport class, a mocked out "manager"
|
||||
with patch('openlp.plugins.songs.lib.ewimport.SongImport'), \
|
||||
patch('openlp.plugins.songs.lib.ewimport.os.path') as mocked_os_path, \
|
||||
patch('__builtin__.open') as mocked_open, \
|
||||
patch('builtins.open') as mocked_open, \
|
||||
patch('openlp.plugins.songs.lib.ewimport.struct') as mocked_struct:
|
||||
mocked_manager = MagicMock()
|
||||
importer = EasyWorshipSongImport(mocked_manager)
|
||||
@ -303,7 +303,7 @@ class TestEasyWorshipSongImport(TestCase):
|
||||
# GIVEN: A mocked out SongImport class, a mocked out "manager"
|
||||
with patch('openlp.plugins.songs.lib.ewimport.SongImport'), \
|
||||
patch('openlp.plugins.songs.lib.ewimport.os.path') as mocked_os_path, \
|
||||
patch('__builtin__.open'), patch('openlp.plugins.songs.lib.ewimport.struct') as mocked_struct, \
|
||||
patch('builtins.open'), patch('openlp.plugins.songs.lib.ewimport.struct') as mocked_struct, \
|
||||
patch('openlp.plugins.songs.lib.ewimport.retrieve_windows_encoding') as mocked_retrieve_windows_encoding:
|
||||
mocked_manager = MagicMock()
|
||||
importer = EasyWorshipSongImport(mocked_manager)
|
||||
@ -354,7 +354,6 @@ class TestEasyWorshipSongImport(TestCase):
|
||||
# called.
|
||||
self.assertIsNone(importer.doImport(), 'doImport should return None when it has completed')
|
||||
for song_data in SONG_TEST_DATA:
|
||||
print mocked_title.mocked_calls()
|
||||
title = song_data['title']
|
||||
author_calls = song_data['authors']
|
||||
song_copyright = song_data['copyright']
|
||||
|
@ -6,7 +6,7 @@ from unittest import TestCase
|
||||
|
||||
from mock import patch, MagicMock
|
||||
|
||||
from openlp.plugins.songs.lib import VerseType, clean_string, clean_title
|
||||
from openlp.plugins.songs.lib import VerseType, clean_string, clean_title, strip_rtf
|
||||
from openlp.plugins.songs.lib.songcompare import songs_probably_equal, _remove_typos, _op_length
|
||||
|
||||
|
||||
@ -215,6 +215,38 @@ class TestLib(TestCase):
|
||||
# THEN: The maximum length should be returned.
|
||||
assert result == 10, 'The length should be 10.'
|
||||
|
||||
def strip_rtf_charsets_test(self):
|
||||
"""
|
||||
Test that the strip_rtf() method properly decodes the supported charsets.
|
||||
"""
|
||||
test_charset_table = [
|
||||
('0', 'weor\\\'F0-myndum \\\'FEah\\par ', 'weorð-myndum þah\n'),
|
||||
('128', '\\\'83C\\\'83G\\\'83X\\\'A5\\\'83L\\\'83\\\'8A\\\'83X\\\'83g\\\'A1 '
|
||||
'\\\\ \\\'95\\\\ \\\'8E\\} \\\'8E\\{ \\\'A1\\par ', 'イエス・キリスト。 ¥ 表 枝 施 。\n'),
|
||||
('129', '\\\'BF\\\'B9\\\'BC\\\'F6 \\\'B1\\\'D7\\\'B8\\\'AE\\\'BD\\\'BA\\\'B5\\\'B5\\par ', '예수 그리스도\n'),
|
||||
('134', '\\\'D2\\\'AE\\\'F6\\\'D5\\\'BB\\\'F9\\\'B6\\\'BD\\\'CA\\\'C7\\\'D6\\\'F7\\par ', '耶稣基督是主\n'),
|
||||
('161', '\\\'D7\\\'F1\\\'E9\\\'F3\\\'F4\\\'FC\\\'F2\\par ', 'Χριστός\n'),
|
||||
('162', 'Hazreti \\\'DDsa\\par ', 'Hazreti İsa\n'),
|
||||
('163', 'ph\\\'FD\\\'F5ng\\par ', 'phương\n'),
|
||||
('177', '\\\'E1\\\'F8\\\'E0\\\'F9\\\'E9\\\'FA\\par ', 'בראשית\n'),
|
||||
('178', '\\\'ED\\\'D3\\\'E6\\\'DA \\\'C7\\\'E1\\\'E3\\\'D3\\\'ED\\\'CD\\par ', 'يسوع المسيح\n'),
|
||||
('186', 'J\\\'EBzus Kristus yra Vie\\\'F0pats\\par ', 'Jėzus Kristus yra Viešpats\n'),
|
||||
('204', '\\\'D0\\\'EE\\\'F1\\\'F1\\\'E8\\\'FF\\par ', 'Россия\n'),
|
||||
('222', '\\\'A4\\\'C3\\\'D4\\\'CA\\\'B5\\\'EC\\par ', 'คริสต์\n'),
|
||||
('238', 'Z\\\'E1v\\\'ECre\\\'E8n\\\'E1 zkou\\\'9Aka\\par ', 'Závěrečná zkouška\n')
|
||||
]
|
||||
|
||||
# GIVEN: For each character set and input
|
||||
for charset, input, exp_result in test_charset_table:
|
||||
|
||||
# WHEN: We call strip_rtf on the input RTF
|
||||
result, result_enc = strip_rtf(
|
||||
'{\\rtf1 \\ansi \\ansicpg1252 {\\fonttbl \\f0 \\fswiss \\fcharset%s Helvetica;}' \
|
||||
'{\\colortbl ;\\red0 \\green0 \\blue0 ;}\\pard \\f0 %s}' % (charset, input))
|
||||
|
||||
# THEN: The stripped text matches thed expected result
|
||||
assert result == exp_result, 'The result should be %s' % exp_result
|
||||
|
||||
|
||||
class TestVerseType(TestCase):
|
||||
"""
|
||||
|
@ -43,7 +43,7 @@ class TestBibleHTTP(TestCase):
|
||||
results = handler.get_bible_chapter('NIV', 'John', 3)
|
||||
|
||||
# THEN: We should get back a valid service item
|
||||
assert len(results.verselist) == 36, 'The book of John should not have had any verses added or removed'
|
||||
assert len(results.verse_list) == 36, 'The book of John should not have had any verses added or removed'
|
||||
|
||||
def crosswalk_extract_books_test(self):
|
||||
"""
|
||||
@ -69,5 +69,5 @@ class TestBibleHTTP(TestCase):
|
||||
results = handler.get_bible_chapter('niv', 'john', 3)
|
||||
|
||||
# THEN: We should get back a valid service item
|
||||
assert len(results.verselist) == 36, 'The book of John should not have had any verses added or removed'
|
||||
assert len(results.verse_list) == 36, 'The book of John should not have had any verses added or removed'
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user