- Merged trunk on 28.7.16

This commit is contained in:
suutari-olli 2016-07-28 22:57:21 +03:00
commit 0923ca6a40
9 changed files with 201 additions and 60 deletions

View File

@ -474,6 +474,7 @@ class ThemeXML(object):
if element.startswith('shadow') or element.startswith('outline'): if element.startswith('shadow') or element.startswith('outline'):
master = 'font_main' master = 'font_main'
# fix bold font # fix bold font
ret_value = None
if element == 'weight': if element == 'weight':
element = 'bold' element = 'bold'
if value == 'Normal': if value == 'Normal':
@ -482,7 +483,7 @@ class ThemeXML(object):
ret_value = True ret_value = True
if element == 'proportion': if element == 'proportion':
element = 'size' element = 'size'
return False, master, element, ret_value return False, master, element, ret_value if ret_value is not None else value
def _create_attr(self, master, element, value): def _create_attr(self, master, element, value):
""" """

View File

@ -252,7 +252,7 @@ class BGExtract(RegistryProperties):
chapter=chapter, chapter=chapter,
version=version) version=version)
soup = get_soup_for_bible_ref( soup = get_soup_for_bible_ref(
'http://legacy.biblegateway.com/passage/?{url}'.format(url=url_params), 'http://biblegateway.com/passage/?{url}'.format(url=url_params),
pre_parse_regex=r'<meta name.*?/>', pre_parse_substitute='') pre_parse_regex=r'<meta name.*?/>', pre_parse_substitute='')
if not soup: if not soup:
return None return None
@ -281,7 +281,7 @@ class BGExtract(RegistryProperties):
""" """
log.debug('BGExtract.get_books_from_http("{version}")'.format(version=version)) log.debug('BGExtract.get_books_from_http("{version}")'.format(version=version))
url_params = urllib.parse.urlencode({'action': 'getVersionInfo', 'vid': '{version}'.format(version=version)}) url_params = urllib.parse.urlencode({'action': 'getVersionInfo', 'vid': '{version}'.format(version=version)})
reference_url = 'http://legacy.biblegateway.com/versions/?{url}#books'.format(url=url_params) reference_url = 'http://biblegateway.com/versions/?{url}#books'.format(url=url_params)
page = get_web_page(reference_url) page = get_web_page(reference_url)
if not page: if not page:
send_error_message('download') send_error_message('download')
@ -312,7 +312,7 @@ class BGExtract(RegistryProperties):
for book in content: for book in content:
book = book.find('td') book = book.find('td')
if book: if book:
books.append(book.contents[0]) books.append(book.contents[1])
return books return books
def get_bibles_from_http(self): def get_bibles_from_http(self):
@ -322,11 +322,11 @@ class BGExtract(RegistryProperties):
returns a list in the form [(biblename, biblekey, language_code)] returns a list in the form [(biblename, biblekey, language_code)]
""" """
log.debug('BGExtract.get_bibles_from_http') log.debug('BGExtract.get_bibles_from_http')
bible_url = 'https://legacy.biblegateway.com/versions/' bible_url = 'https://biblegateway.com/versions/'
soup = get_soup_for_bible_ref(bible_url) soup = get_soup_for_bible_ref(bible_url)
if not soup: if not soup:
return None return None
bible_select = soup.find('select', {'class': 'translation-dropdown'}) bible_select = soup.find('select', {'class': 'search-translation-select'})
if not bible_select: if not bible_select:
log.debug('No select tags found - did site change?') log.debug('No select tags found - did site change?')
return None return None
@ -532,28 +532,26 @@ class CWExtract(RegistryProperties):
returns a list in the form [(biblename, biblekey, language_code)] returns a list in the form [(biblename, biblekey, language_code)]
""" """
log.debug('CWExtract.get_bibles_from_http') log.debug('CWExtract.get_bibles_from_http')
bible_url = 'http://www.biblestudytools.com/' bible_url = 'http://www.biblestudytools.com/bible-versions/'
soup = get_soup_for_bible_ref(bible_url) soup = get_soup_for_bible_ref(bible_url)
if not soup: if not soup:
return None return None
bible_select = soup.find('select') h4_tags = soup.find_all('h4', {'class': 'small-header'})
if not bible_select: if not h4_tags:
log.debug('No select tags found - did site change?') log.debug('No h4 tags found - did site change?')
return None
option_tags = bible_select.find_all('option', {'class': 'log-translation'})
if not option_tags:
log.debug('No option tags found - did site change?')
return None return None
bibles = [] bibles = []
for ot in option_tags: for h4t in h4_tags:
tag_text = ot.get_text().strip() short_name = None
try: if h4t.span:
tag_value = ot['value'] short_name = h4t.span.get_text().strip().lower()
except KeyError: else:
log.exception('No value attribute found - did site change?') log.error('No span tag found - did site change?')
return None return None
if not tag_value: if not short_name:
continue continue
h4t.span.extract()
tag_text = h4t.get_text().strip()
# The names of non-english bibles has their language in parentheses at the end # The names of non-english bibles has their language in parentheses at the end
if tag_text.endswith(')'): if tag_text.endswith(')'):
language = tag_text[tag_text.rfind('(') + 1:-1] language = tag_text[tag_text.rfind('(') + 1:-1]
@ -561,12 +559,20 @@ class CWExtract(RegistryProperties):
language_code = CROSSWALK_LANGUAGES[language] language_code = CROSSWALK_LANGUAGES[language]
else: else:
language_code = '' language_code = ''
# ... except for the latin vulgate # ... except for those that don't...
elif 'latin' in tag_text.lower(): elif 'latin' in tag_text.lower():
language_code = 'la' language_code = 'la'
elif 'la biblia' in tag_text.lower() or 'nueva' in tag_text.lower():
language_code = 'es'
elif 'chinese' in tag_text.lower():
language_code = 'zh'
elif 'greek' in tag_text.lower():
language_code = 'el'
elif 'nova' in tag_text.lower():
language_code = 'pt'
else: else:
language_code = 'en' language_code = 'en'
bibles.append((tag_text, tag_value, language_code)) bibles.append((tag_text, short_name, language_code))
return bibles return bibles

View File

@ -46,7 +46,7 @@ class EasySlidesImport(SongImport):
def do_import(self): def do_import(self):
log.info('Importing EasySlides XML file {source}'.format(source=self.import_source)) log.info('Importing EasySlides XML file {source}'.format(source=self.import_source))
parser = etree.XMLParser(remove_blank_text=True) parser = etree.XMLParser(remove_blank_text=True, recover=True)
parsed_file = etree.parse(self.import_source, parser) parsed_file = etree.parse(self.import_source, parser)
xml = etree.tostring(parsed_file).decode() xml = etree.tostring(parsed_file).decode()
song_xml = objectify.fromstring(xml) song_xml = objectify.fromstring(xml)

View File

@ -73,6 +73,14 @@ class VideoPsalmImport(SongImport):
processed_content += c processed_content += c
c = next(file_content_it) c = next(file_content_it)
processed_content += '"' + c processed_content += '"' + c
# Remove control characters
elif (c < chr(32)):
processed_content += ' '
# Handle escaped characters
elif c == '\\':
processed_content += c
c = next(file_content_it)
processed_content += c
else: else:
processed_content += c processed_content += c
songbook = json.loads(processed_content.strip()) songbook = json.loads(processed_content.strip())

View File

@ -22,43 +22,82 @@
""" """
Package to test the openlp.core.lib.theme package. Package to test the openlp.core.lib.theme package.
""" """
from tests.functional import MagicMock, patch
from unittest import TestCase from unittest import TestCase
import os
from openlp.core.lib.theme import ThemeXML from openlp.core.lib.theme import ThemeXML
class TestTheme(TestCase): class TestThemeXML(TestCase):
""" """
Test the functions in the Theme module Test the ThemeXML class
""" """
def setUp(self):
"""
Create the UI
"""
pass
def tearDown(self):
"""
Delete all the C++ objects at the end so that we don't have a segfault
"""
pass
def test_new_theme(self): def test_new_theme(self):
""" """
Test the theme creation - basic test Test the ThemeXML constructor
""" """
# GIVEN: A new theme # GIVEN: The ThemeXML class
# WHEN: A theme object is created
# WHEN: A theme is created
default_theme = ThemeXML() default_theme = ThemeXML()
# THEN: We should get some default behaviours # THEN: The default values should be correct
self.assertTrue(default_theme.background_border_color == '#000000', 'The theme should have a black border') self.assertEqual('#000000', default_theme.background_border_color,
self.assertTrue(default_theme.background_type == 'solid', 'The theme should have a solid backgrounds') 'background_border_color should be "#000000"')
self.assertTrue(default_theme.display_vertical_align == 0, self.assertEqual('solid', default_theme.background_type, 'background_type should be "solid"')
'The theme should have a display_vertical_align of 0') self.assertEqual(0, default_theme.display_vertical_align, 'display_vertical_align should be 0')
self.assertTrue(default_theme.font_footer_name == "Arial", self.assertEqual('Arial', default_theme.font_footer_name, 'font_footer_name should be "Arial"')
'The theme should have a font_footer_name of Arial') self.assertFalse(default_theme.font_main_bold, 'font_main_bold should be False')
self.assertTrue(default_theme.font_main_bold is False, 'The theme should have a font_main_bold of false') self.assertEqual(47, len(default_theme.__dict__), 'The theme should have 47 attributes')
self.assertTrue(len(default_theme.__dict__) == 47, 'The theme should have 47 variables')
def test_expand_json(self):
"""
Test the expand_json method
"""
# GIVEN: A ThemeXML object and some JSON to "expand"
theme = ThemeXML()
theme_json = {
'background': {
'border_color': '#000000',
'type': 'solid'
},
'display': {
'vertical_align': 0
},
'font': {
'footer': {
'bold': False
},
'main': {
'name': 'Arial'
}
}
}
# WHEN: ThemeXML.expand_json() is run
theme.expand_json(theme_json)
# THEN: The attributes should be set on the object
self.assertEqual('#000000', theme.background_border_color, 'background_border_color should be "#000000"')
self.assertEqual('solid', theme.background_type, 'background_type should be "solid"')
self.assertEqual(0, theme.display_vertical_align, 'display_vertical_align should be 0')
self.assertFalse(theme.font_footer_bold, 'font_footer_bold should be False')
self.assertEqual('Arial', theme.font_main_name, 'font_main_name should be "Arial"')
def test_extend_image_filename(self):
"""
Test the extend_image_filename method
"""
# GIVEN: A theme object
theme = ThemeXML()
theme.theme_name = 'MyBeautifulTheme '
theme.background_filename = ' video.mp4'
theme.background_type = 'video'
path = os.path.expanduser('~')
# WHEN: ThemeXML.extend_image_filename is run
theme.extend_image_filename(path)
# THEN: The filename of the background should be correct
expected_filename = os.path.join(path, 'MyBeautifulTheme', 'video.mp4')
self.assertEqual(expected_filename, theme.background_filename)
self.assertEqual('MyBeautifulTheme', theme.theme_name)

View File

@ -43,3 +43,5 @@ class TestVideoPsalmFileImport(SongImportTestHelper):
""" """
self.file_import(os.path.join(TEST_PATH, 'videopsalm-as-safe-a-stronghold.json'), self.file_import(os.path.join(TEST_PATH, 'videopsalm-as-safe-a-stronghold.json'),
self.load_external_result_data(os.path.join(TEST_PATH, 'as-safe-a-stronghold.json'))) self.load_external_result_data(os.path.join(TEST_PATH, 'as-safe-a-stronghold.json')))
self.file_import(os.path.join(TEST_PATH, 'videopsalm-as-safe-a-stronghold2.json'),
self.load_external_result_data(os.path.join(TEST_PATH, 'as-safe-a-stronghold2.json')))

View File

@ -50,7 +50,8 @@ class TestBibleHTTP(TestCase):
books = handler.get_books_from_http('NIV') books = handler.get_books_from_http('NIV')
# THEN: We should get back a valid service item # THEN: We should get back a valid service item
assert len(books) == 66, 'The bible should not have had any books added or removed' self.assertEqual(len(books), 66, 'The bible should not have had any books added or removed')
self.assertEqual(books[0], 'Genesis', 'The first bible book should be Genesis')
def test_bible_gateway_extract_books_support_redirect(self): def test_bible_gateway_extract_books_support_redirect(self):
""" """
@ -63,7 +64,7 @@ class TestBibleHTTP(TestCase):
books = handler.get_books_from_http('DN1933') books = handler.get_books_from_http('DN1933')
# THEN: We should get back a valid service item # THEN: We should get back a valid service item
assert len(books) == 66, 'This bible should have 66 books' self.assertEqual(len(books), 66, 'This bible should have 66 books')
def test_bible_gateway_extract_verse(self): def test_bible_gateway_extract_verse(self):
""" """
@ -76,7 +77,8 @@ class TestBibleHTTP(TestCase):
results = handler.get_bible_chapter('NIV', 'John', 3) results = handler.get_bible_chapter('NIV', 'John', 3)
# THEN: We should get back a valid service item # THEN: We should get back a valid service item
assert len(results.verse_list) == 36, 'The book of John should not have had any verses added or removed' self.assertEqual(len(results.verse_list), 36,
'The book of John should not have had any verses added or removed')
def test_bible_gateway_extract_verse_nkjv(self): def test_bible_gateway_extract_verse_nkjv(self):
""" """
@ -89,7 +91,8 @@ class TestBibleHTTP(TestCase):
results = handler.get_bible_chapter('NKJV', 'John', 3) results = handler.get_bible_chapter('NKJV', 'John', 3)
# THEN: We should get back a valid service item # THEN: We should get back a valid service item
assert len(results.verse_list) == 36, 'The book of John should not have had any verses added or removed' self.assertEqual(len(results.verse_list), 36,
'The book of John should not have had any verses added or removed')
def test_crosswalk_extract_books(self): def test_crosswalk_extract_books(self):
""" """
@ -102,7 +105,7 @@ class TestBibleHTTP(TestCase):
books = handler.get_books_from_http('niv') books = handler.get_books_from_http('niv')
# THEN: We should get back a valid service item # THEN: We should get back a valid service item
assert len(books) == 66, 'The bible should not have had any books added or removed' self.assertEqual(len(books), 66, 'The bible should not have had any books added or removed')
def test_crosswalk_extract_verse(self): def test_crosswalk_extract_verse(self):
""" """
@ -115,7 +118,8 @@ class TestBibleHTTP(TestCase):
results = handler.get_bible_chapter('niv', 'john', 3) results = handler.get_bible_chapter('niv', 'john', 3)
# THEN: We should get back a valid service item # THEN: We should get back a valid service item
assert len(results.verse_list) == 36, 'The book of John should not have had any verses added or removed' self.assertEqual(len(results.verse_list), 36,
'The book of John should not have had any verses added or removed')
def test_bibleserver_get_bibles(self): def test_bibleserver_get_bibles(self):
""" """
@ -144,9 +148,8 @@ class TestBibleHTTP(TestCase):
# THEN: The list should not be None, and some known bibles should be there # THEN: The list should not be None, and some known bibles should be there
self.assertIsNotNone(bibles) self.assertIsNotNone(bibles)
self.assertIn(('Holman Christian Standard Bible', 'HCSB', 'en'), bibles) self.assertIn(('Holman Christian Standard Bible (HCSB)', 'HCSB', 'en'), bibles)
@skip("Waiting for Crosswalk to fix their server")
def test_crosswalk_get_bibles(self): def test_crosswalk_get_bibles(self):
""" """
Test getting list of bibles from Crosswalk.com Test getting list of bibles from Crosswalk.com

View File

@ -0,0 +1,35 @@
{
"authors": [
["Martin Luther", "words"],
["Unknown", "music"]
],
"ccli_number": "12345",
"comments": "This is\nthe first comment\nThis is\nthe second comment\nThis is\nthe third comment\n",
"copyright": "Public Domain",
"song_book_name": "SongBook1",
"song_number": 0,
"title": "A Safe Stronghold Our God is Still",
"topics": [
"tema1",
"tema2"
],
"verse_order_list": [],
"verses": [
[
"As safe a stronghold our God is still,\nA trusty shield and weapon;\nHell help us clear from all the ill\nThat hath us now oertaken.\nThe ancient prince of hell\nHath risen with purpose fell;\nStrong mail of craft and power\nHe weareth in this hour;\nOn earth is not His fellow.",
"v"
],
[
"With \"force\" of arms we nothing can,\nFull soon were we down-ridden;\nBut for us fights \\ the proper Man,\nWhom God Himself hath bidden.\nAsk ye: Who is this same?\nChrist Jesus is His name,\nThe Lord Sabaoths Son;\nHe, and no other one,\nShall conquer in the battle.",
"v"
],
[
"And were this world all devils oer,\nAnd watching to devour us,\nWe lay it not to heart so sore;\nNot they can overpower us.\nAnd let the prince of ill\nLook grim as eer he will,\nHe harms us not a whit;\nFor why? his doom is writ;\nA word shall quickly slay him.",
"v"
],
[
"Gods word, for all their craft and force,\nOne moment will not linger,\nBut, spite of hell, shall have its course;\nTis written by His finger.\nAnd though they take our life,\nGoods, honour, children, wife,\nYet is their profit small:\nThese things shall vanish all;\nThe city of God remaineth.",
"v"
]
]
}

View File

@ -0,0 +1,47 @@
{Abbreviation:"SB1",Copyright:"Public domain",Songs:[{ID:3,Composer:"Unknown",Author:"Martin Luther",Copyright:"Public
Domain",Theme:"tema1
tema2",CCLI:"12345",Alias:"A safe stronghold",Memo1:"This is
the first comment
",Memo2:"This is
the second comment
",Memo3:"This is
the third comment
",Reference:"reference",Guid:"jtCkrJdPIUOmECjaQylg/g",Verses:[{
Text:"As safe a stronghold our God is still,
A trusty shield and weapon;
Hell help us clear from all the ill
That hath us now oertaken.
The ancient prince of hell
Hath risen with purpose fell;
Strong mail of craft and power
He weareth in this hour;
On earth is not His fellow."},{ID:2,
Text:"With \"force\" of arms we nothing can,
Full soon were we down-ridden;
But for us fights \\ the proper Man,
Whom God Himself hath bidden.
Ask ye: Who is this same?
Christ Jesus is His name,
The Lord Sabaoths Son;
He, and no other one,
Shall conquer in the battle."},{ID:3,
Text:"And were this world all devils oer,
And watching to devour us,
We lay it not to heart so sore;
Not they can overpower us.
And let the prince of ill
Look grim as eer he will,
He harms us not a whit;
For why? his doom is writ;
A word shall quickly slay him."},{ID:4,
Text:"Gods word, for all their craft and force,
One moment will not linger,
But, spite of hell, shall have its course;
Tis written by His finger.
And though they take our life,
Goods, honour, children, wife,
Yet is their profit small:
These things shall vanish all;
The city of God remaineth."}],AudioFile:"282.mp3",IsAudioFileEnabled:1,
Text:"A Safe Stronghold Our God is Still"}],Guid:"khiHU2blX0Kb41dGdbDLhA",VersionDate:"20121012000000",
Text:"SongBook1"}