This commit is contained in:
Raoul Snyman 2014-10-22 22:47:47 +02:00
commit 3771cb42a8
36 changed files with 545 additions and 17014 deletions

View File

@ -39,11 +39,12 @@ import sys
import logging import logging
from optparse import OptionParser from optparse import OptionParser
from traceback import format_exception from traceback import format_exception
import shutil
import time
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.common import Registry, OpenLPMixin, AppLocation, Settings, UiStrings, check_directory_exists, \ from openlp.core.common import Registry, OpenLPMixin, AppLocation, Settings, UiStrings, check_directory_exists, \
is_macosx, is_win is_macosx, is_win, translate
from openlp.core.lib import ScreenList from openlp.core.lib import ScreenList
from openlp.core.resources import qInitResources from openlp.core.resources import qInitResources
from openlp.core.ui.mainwindow import MainWindow from openlp.core.ui.mainwindow import MainWindow
@ -138,6 +139,8 @@ class OpenLP(OpenLPMixin, QtGui.QApplication):
self.splash.show() self.splash.show()
# make sure Qt really display the splash screen # make sure Qt really display the splash screen
self.processEvents() self.processEvents()
# Check if OpenLP has been upgrade and if a backup of data should be created
self.backup_on_upgrade(has_run_wizard)
# start the main app window # start the main app window
self.main_window = MainWindow() self.main_window = MainWindow()
Registry().execute('bootstrap_initialise') Registry().execute('bootstrap_initialise')
@ -156,7 +159,8 @@ class OpenLP(OpenLPMixin, QtGui.QApplication):
self.main_window.first_time() self.main_window.first_time()
update_check = Settings().value('core/update check') update_check = Settings().value('core/update check')
if update_check: if update_check:
VersionThread(self.main_window).start() version = VersionThread(self.main_window)
version.start()
self.main_window.is_display_blank() self.main_window.is_display_blank()
self.main_window.app_startup() self.main_window.app_startup()
return self.exec_() return self.exec_()
@ -194,6 +198,40 @@ class OpenLP(OpenLPMixin, QtGui.QApplication):
self.set_normal_cursor() self.set_normal_cursor()
self.exception_form.exec_() self.exception_form.exec_()
def backup_on_upgrade(self, has_run_wizard):
"""
Check if OpenLP has been upgraded, and ask if a backup of data should be made
:param has_run_wizard: OpenLP has been run before
"""
data_version = Settings().value('core/application version')
openlp_version = get_application_version()['version']
# New installation, no need to create backup
if not has_run_wizard:
Settings().setValue('core/application version', openlp_version)
# If data_version is different from the current version ask if we should backup the data folder
elif data_version != openlp_version:
if QtGui.QMessageBox.question(None, translate('OpenLP', 'Backup'),
translate('OpenLP', 'OpenLP has been upgraded, '
'do you want to create a backup of OpenLPs data folder?'),
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No,
QtGui.QMessageBox.Yes) == QtGui.QMessageBox.Yes:
# Create copy of data folder
data_folder_path = AppLocation.get_data_path()
timestamp = time.strftime("%Y%m%d-%H%M%S")
data_folder_backup_path = data_folder_path + '-' + timestamp
try:
shutil.copytree(data_folder_path, data_folder_backup_path)
except OSError:
QtGui.QMessageBox.warning(None, translate('OpenLP', 'Backup'),
translate('OpenLP', 'Backup of the data folder failed!'))
return
QtGui.QMessageBox.information(None, translate('OpenLP', 'Backup'),
translate('OpenLP', 'A backup of the data folder has been created at %s')
% data_folder_backup_path)
# Update the version in the settings
Settings().setValue('core/application version', openlp_version)
def process_events(self): def process_events(self):
""" """
Wrapper to make ProcessEvents visible and named correctly Wrapper to make ProcessEvents visible and named correctly

View File

@ -137,6 +137,7 @@ class Settings(QtCore.QSettings):
# circular dependency. # circular dependency.
'core/display on monitor': True, 'core/display on monitor': True,
'core/override position': False, 'core/override position': False,
'core/application version': '0.0',
'images/background color': '#000000', 'images/background color': '#000000',
'media/players': 'webkit', 'media/players': 'webkit',
'media/override player': QtCore.Qt.Unchecked, 'media/override player': QtCore.Qt.Unchecked,

View File

@ -490,7 +490,6 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow, RegistryProperties):
self.header_section = 'SettingsImport' self.header_section = 'SettingsImport'
self.recent_files = [] self.recent_files = []
self.timer_id = 0 self.timer_id = 0
self.timer_version_id = 0
self.new_data_path = None self.new_data_path = None
self.copy_data = False self.copy_data = False
Settings().set_up_default_values() Settings().set_up_default_values()
@ -536,7 +535,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow, RegistryProperties):
self.application.set_busy_cursor() self.application.set_busy_cursor()
# Simple message boxes # Simple message boxes
Registry().register_function('theme_update_global', self.default_theme_changed) Registry().register_function('theme_update_global', self.default_theme_changed)
Registry().register_function('openlp_version_check', self.version_notice) QtCore.QObject.connect(self, QtCore.SIGNAL('openlp_version_check'), self.version_notice)
Registry().register_function('config_screen_changed', self.screen_changed) Registry().register_function('config_screen_changed', self.screen_changed)
Registry().register_function('bootstrap_post_set_up', self.bootstrap_post_set_up) Registry().register_function('bootstrap_post_set_up', self.bootstrap_post_set_up)
# Reset the cursor # Reset the cursor
@ -585,12 +584,15 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow, RegistryProperties):
""" """
Notifies the user that a newer version of OpenLP is available. Notifies the user that a newer version of OpenLP is available.
Triggered by delay thread and cannot display popup. Triggered by delay thread and cannot display popup.
:param version: The Version to be displayed.
""" """
log.debug('version_notice') log.debug('version_notice')
version_text = translate('OpenLP.MainWindow', 'Version %s of OpenLP is now available for download (you are ' version_text = translate('OpenLP.MainWindow', 'Version %s of OpenLP is now available for download (you are '
'currently running version %s). \n\nYou can download the latest version from ' 'currently running version %s). \n\nYou can download the latest version from '
'http://openlp.org/.') 'http://openlp.org/.')
self.version_text = version_text % (version, get_application_version()['full']) QtGui.QMessageBox.question(self, translate('OpenLP.MainWindow', 'OpenLP Version Updated'),
version_text % (version, get_application_version()[u'full']))
def show(self): def show(self):
""" """
@ -604,7 +606,6 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow, RegistryProperties):
self.open_cmd_line_files() self.open_cmd_line_files()
elif Settings().value(self.general_settings_section + '/auto open'): elif Settings().value(self.general_settings_section + '/auto open'):
self.service_manager_contents.load_last_file() self.service_manager_contents.load_last_file()
self.timer_version_id = self.startTimer(1000)
view_mode = Settings().value('%s/view mode' % self.general_settings_section) view_mode = Settings().value('%s/view mode' % self.general_settings_section)
if view_mode == 'default': if view_mode == 'default':
self.mode_default_item.setChecked(True) self.mode_default_item.setChecked(True)
@ -1304,17 +1305,6 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow, RegistryProperties):
self.timer_id = 0 self.timer_id = 0
self.load_progress_bar.hide() self.load_progress_bar.hide()
self.application.process_events() self.application.process_events()
if event.timerId() == self.timer_version_id:
self.timer_version_id = 0
# Has the thread passed some data to be displayed so display it and stop all waiting
if hasattr(self, 'version_text'):
QtGui.QMessageBox.question(self, translate('OpenLP.MainWindow', 'OpenLP Version Updated'),
self.version_text)
else:
# the thread has not confirmed it is running or it has not yet sent any data so lets keep waiting
if not hasattr(self, 'version_update_running') or self.version_update_running:
self.timer_version_id = self.startTimer(1000)
self.application.process_events()
def set_new_data_path(self, new_data_path): def set_new_data_path(self, new_data_path):
""" """

View File

@ -374,7 +374,8 @@ class SlideController(DisplayController, RegistryProperties):
triggers=self._slide_shortcut_activated) for s in shortcuts]) triggers=self._slide_shortcut_activated) for s in shortcuts])
self.shortcut_timer.timeout.connect(self._slide_shortcut_activated) self.shortcut_timer.timeout.connect(self._slide_shortcut_activated)
# Signals # Signals
self.preview_widget.itemSelectionChanged.connect(self.on_slide_selected) self.preview_widget.clicked.connect(self.on_slide_selected)
self.preview_widget.verticalHeader().sectionClicked.connect(self.on_slide_selected)
if self.is_live: if self.is_live:
# Need to use event as called across threads and UI is updated # Need to use event as called across threads and UI is updated
QtCore.QObject.connect(self, QtCore.SIGNAL('slidecontroller_toggle_display'), self.toggle_display) QtCore.QObject.connect(self, QtCore.SIGNAL('slidecontroller_toggle_display'), self.toggle_display)

View File

@ -98,6 +98,16 @@ class VersionThread(QtCore.QThread):
A special Qt thread class to fetch the version of OpenLP from the website. A special Qt thread class to fetch the version of OpenLP from the website.
This is threaded so that it doesn't affect the loading time of OpenLP. This is threaded so that it doesn't affect the loading time of OpenLP.
""" """
def __init__(self, main_window):
"""
Constructor for the thread class.
:param main_window: The main window Object.
"""
log.debug("VersionThread - Initialise")
super(VersionThread, self).__init__(None)
self.main_window = main_window
def run(self): def run(self):
""" """
Run the thread. Run the thread.
@ -106,8 +116,9 @@ class VersionThread(QtCore.QThread):
log.debug('Version thread - run') log.debug('Version thread - run')
app_version = get_application_version() app_version = get_application_version()
version = check_latest_version(app_version) version = check_latest_version(app_version)
log.debug("Versions %s and %s " % (LooseVersion(str(version)), LooseVersion(str(app_version['full']))))
if LooseVersion(str(version)) > LooseVersion(str(app_version['full'])): if LooseVersion(str(version)) > LooseVersion(str(app_version['full'])):
Registry().execute('openlp_version_check', '%s' % version) self.main_window.emit(QtCore.SIGNAL('openlp_version_check'), '%s' % version)
class HTTPRedirectHandlerFixed(urllib.request.HTTPRedirectHandler): class HTTPRedirectHandlerFixed(urllib.request.HTTPRedirectHandler):
@ -228,8 +239,6 @@ def check_latest_version(current_version):
this_test = str(datetime.now().date()) this_test = str(datetime.now().date())
settings.setValue('last version test', this_test) settings.setValue('last version test', this_test)
settings.endGroup() settings.endGroup()
# Tell the main window whether there will ever be data to display
Registry().get('main_window').version_update_running = last_test != this_test
if last_test != this_test: if last_test != this_test:
if current_version['build']: if current_version['build']:
req = urllib.request.Request('http://www.openlp.org/files/nightly_version.txt') req = urllib.request.Request('http://www.openlp.org/files/nightly_version.txt')

View File

@ -38,7 +38,7 @@ from openlp.core.lib import MediaManagerItem, ItemCapabilities, ServiceItemConte
from openlp.core.lib.ui import critical_error_message_box, create_horizontal_adjusting_combo_box from openlp.core.lib.ui import critical_error_message_box, create_horizontal_adjusting_combo_box
from openlp.core.utils import get_locale_key from openlp.core.utils import get_locale_key
from openlp.plugins.presentations.lib import MessageListener from openlp.plugins.presentations.lib import MessageListener
from openlp.plugins.presentations.lib.pdfcontroller import PDF_CONTROLLER_FILETYPES
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -145,7 +145,7 @@ class PresentationMediaItem(MediaManagerItem):
if self.controllers[item].enabled(): if self.controllers[item].enabled():
self.display_type_combo_box.addItem(item) self.display_type_combo_box.addItem(item)
if self.display_type_combo_box.count() > 1: if self.display_type_combo_box.count() > 1:
self.display_type_combo_box.insertItem(0, self.automatic) self.display_type_combo_box.insertItem(0, self.automatic, userData='automatic')
self.display_type_combo_box.setCurrentIndex(0) self.display_type_combo_box.setCurrentIndex(0)
if Settings().value(self.settings_section + '/override app') == QtCore.Qt.Checked: if Settings().value(self.settings_section + '/override app') == QtCore.Qt.Checked:
self.presentation_widget.show() self.presentation_widget.show()
@ -260,11 +260,11 @@ class PresentationMediaItem(MediaManagerItem):
filename = presentation_file filename = presentation_file
if filename is None: if filename is None:
filename = items[0].data(QtCore.Qt.UserRole) filename = items[0].data(QtCore.Qt.UserRole)
file_type = os.path.splitext(filename)[1][1:] file_type = os.path.splitext(filename.lower())[1][1:]
if not self.display_type_combo_box.currentText(): if not self.display_type_combo_box.currentText():
return False return False
service_item.add_capability(ItemCapabilities.CanEditTitle) service_item.add_capability(ItemCapabilities.CanEditTitle)
if (file_type == 'pdf' or file_type == 'xps') and context != ServiceItemContext.Service: if file_type in PDF_CONTROLLER_FILETYPES and context != ServiceItemContext.Service:
service_item.add_capability(ItemCapabilities.CanMaintain) service_item.add_capability(ItemCapabilities.CanMaintain)
service_item.add_capability(ItemCapabilities.CanPreview) service_item.add_capability(ItemCapabilities.CanPreview)
service_item.add_capability(ItemCapabilities.CanLoop) service_item.add_capability(ItemCapabilities.CanLoop)
@ -313,7 +313,7 @@ class PresentationMediaItem(MediaManagerItem):
(path, name) = os.path.split(filename) (path, name) = os.path.split(filename)
service_item.title = name service_item.title = name
if os.path.exists(filename): if os.path.exists(filename):
if service_item.processor == self.automatic: if self.display_type_combo_box.itemData(self.display_type_combo_box.currentIndex()) == 'automatic':
service_item.processor = self.find_controller_by_type(filename) service_item.processor = self.find_controller_by_type(filename)
if not service_item.processor: if not service_item.processor:
return False return False

View File

@ -29,12 +29,14 @@
import logging import logging
import copy import copy
import os
from PyQt4 import QtCore from PyQt4 import QtCore
from openlp.core.common import Registry from openlp.core.common import Registry
from openlp.core.ui import HideMode from openlp.core.ui import HideMode
from openlp.core.lib import ServiceItemContext, ServiceItem from openlp.core.lib import ServiceItemContext, ServiceItem
from openlp.plugins.presentations.lib.pdfcontroller import PDF_CONTROLLER_FILETYPES
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -320,10 +322,11 @@ class MessageListener(object):
file = item.get_frame_path() file = item.get_frame_path()
self.handler = item.processor self.handler = item.processor
# When starting presentation from the servicemanager we convert # When starting presentation from the servicemanager we convert
# PDF/XPS-serviceitems into image-serviceitems. When started from the mediamanager # PDF/XPS/OXPS-serviceitems into image-serviceitems. When started from the mediamanager
# the conversion has already been done at this point. # the conversion has already been done at this point.
if file.endswith('.pdf') or file.endswith('.xps'): file_type = os.path.splitext(file.lower())[1][1:]
log.debug('Converting from pdf/xps to images for serviceitem with file %s', file) if file_type in PDF_CONTROLLER_FILETYPES:
log.debug('Converting from pdf/xps/oxps to images for serviceitem with file %s', file)
# Create a copy of the original item, and then clear the original item so it can be filled with images # Create a copy of the original item, and then clear the original item so it can be filled with images
item_cpy = copy.copy(item) item_cpy = copy.copy(item)
item.__init__(None) item.__init__(None)
@ -338,7 +341,7 @@ class MessageListener(object):
item.image_border = item_cpy.image_border item.image_border = item_cpy.image_border
item.main = item_cpy.main item.main = item_cpy.main
item.theme_data = item_cpy.theme_data item.theme_data = item_cpy.theme_data
# When presenting PDF or XPS, we are using the image presentation code, # When presenting PDF/XPS/OXPS, we are using the image presentation code,
# so handler & processor is set to None, and we skip adding the handler. # so handler & processor is set to None, and we skip adding the handler.
self.handler = None self.handler = None
if self.handler == self.media_item.automatic: if self.handler == self.media_item.automatic:
@ -349,7 +352,7 @@ class MessageListener(object):
controller = self.live_handler controller = self.live_handler
else: else:
controller = self.preview_handler controller = self.preview_handler
# When presenting PDF or XPS, we are using the image presentation code, # When presenting PDF/XPS/OXPS, we are using the image presentation code,
# so handler & processor is set to None, and we skip adding the handler. # so handler & processor is set to None, and we skip adding the handler.
if self.handler is None: if self.handler is None:
self.controller = controller self.controller = controller

View File

@ -34,12 +34,17 @@ import re
from subprocess import check_output, CalledProcessError, STDOUT from subprocess import check_output, CalledProcessError, STDOUT
from openlp.core.utils import AppLocation from openlp.core.utils import AppLocation
from openlp.core.common import Settings, is_win from openlp.core.common import Settings, is_win, trace_error_handler
from openlp.core.lib import ScreenList from openlp.core.lib import ScreenList
from .presentationcontroller import PresentationController, PresentationDocument from .presentationcontroller import PresentationController, PresentationDocument
if is_win():
from subprocess import STARTUPINFO, STARTF_USESHOWWINDOW
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
PDF_CONTROLLER_FILETYPES = ['pdf', 'xps', 'oxps']
class PdfController(PresentationController): class PdfController(PresentationController):
""" """
@ -74,11 +79,19 @@ class PdfController(PresentationController):
runlog = '' runlog = ''
log.debug('testing program_path: %s', program_path) log.debug('testing program_path: %s', program_path)
try: try:
runlog = check_output([program_path, '--help'], stderr=STDOUT) # Setup startupinfo options for check_output to avoid console popping up on windows
if is_win():
startupinfo = STARTUPINFO()
startupinfo.dwFlags |= STARTF_USESHOWWINDOW
else:
startupinfo = None
runlog = check_output([program_path, '--help'], stderr=STDOUT, startupinfo=startupinfo)
except CalledProcessError as e: except CalledProcessError as e:
runlog = e.output runlog = e.output
except Exception: except Exception:
trace_error_handler(log)
runlog = '' runlog = ''
log.debug('check_output returned: %s' % runlog)
# Analyse the output to see it the program is mudraw, ghostscript or neither # Analyse the output to see it the program is mudraw, ghostscript or neither
for line in runlog.splitlines(): for line in runlog.splitlines():
decoded_line = line.decode() decoded_line = line.decode()
@ -148,7 +161,7 @@ class PdfController(PresentationController):
if os.path.isfile(os.path.join(application_path, 'mudraw')): if os.path.isfile(os.path.join(application_path, 'mudraw')):
self.mudrawbin = os.path.join(application_path, 'mudraw') self.mudrawbin = os.path.join(application_path, 'mudraw')
if self.mudrawbin: if self.mudrawbin:
self.also_supports = ['xps'] self.also_supports = ['xps', 'oxps']
return True return True
elif self.gsbin: elif self.gsbin:
return True return True
@ -182,6 +195,12 @@ class PdfDocument(PresentationDocument):
self.hidden = False self.hidden = False
self.image_files = [] self.image_files = []
self.num_pages = -1 self.num_pages = -1
# Setup startupinfo options for check_output to avoid console popping up on windows
if is_win():
self.startupinfo = STARTUPINFO()
self.startupinfo.dwFlags |= STARTF_USESHOWWINDOW
else:
self.startupinfo = None
def gs_get_resolution(self, size): def gs_get_resolution(self, size):
""" """
@ -199,7 +218,8 @@ class PdfDocument(PresentationDocument):
runlog = [] runlog = []
try: try:
runlog = check_output([self.controller.gsbin, '-dNOPAUSE', '-dNODISPLAY', '-dBATCH', runlog = check_output([self.controller.gsbin, '-dNOPAUSE', '-dNODISPLAY', '-dBATCH',
'-sFile=' + self.file_path, gs_resolution_script]) '-sFile=' + self.file_path, gs_resolution_script],
startupinfo=self.startupinfo)
except CalledProcessError as e: except CalledProcessError as e:
log.debug(' '.join(e.cmd)) log.debug(' '.join(e.cmd))
log.debug(e.output) log.debug(e.output)
@ -248,13 +268,14 @@ class PdfDocument(PresentationDocument):
os.makedirs(self.get_temp_folder()) os.makedirs(self.get_temp_folder())
if self.controller.mudrawbin: if self.controller.mudrawbin:
runlog = check_output([self.controller.mudrawbin, '-w', str(size.right()), '-h', str(size.bottom()), runlog = check_output([self.controller.mudrawbin, '-w', str(size.right()), '-h', str(size.bottom()),
'-o', os.path.join(self.get_temp_folder(), 'mainslide%03d.png'), self.file_path]) '-o', os.path.join(self.get_temp_folder(), 'mainslide%03d.png'), self.file_path],
startupinfo=self.startupinfo)
elif self.controller.gsbin: elif self.controller.gsbin:
resolution = self.gs_get_resolution(size) resolution = self.gs_get_resolution(size)
runlog = check_output([self.controller.gsbin, '-dSAFER', '-dNOPAUSE', '-dBATCH', '-sDEVICE=png16m', runlog = check_output([self.controller.gsbin, '-dSAFER', '-dNOPAUSE', '-dBATCH', '-sDEVICE=png16m',
'-r' + str(resolution), '-dTextAlphaBits=4', '-dGraphicsAlphaBits=4', '-r' + str(resolution), '-dTextAlphaBits=4', '-dGraphicsAlphaBits=4',
'-sOutputFile=' + os.path.join(self.get_temp_folder(), 'mainslide%03d.png'), '-sOutputFile=' + os.path.join(self.get_temp_folder(), 'mainslide%03d.png'),
self.file_path]) self.file_path], startupinfo=self.startupinfo)
created_files = sorted(os.listdir(self.get_temp_folder())) created_files = sorted(os.listdir(self.get_temp_folder()))
for fn in created_files: for fn in created_files:
if os.path.isfile(os.path.join(self.get_temp_folder(), fn)): if os.path.isfile(os.path.join(self.get_temp_folder(), fn)):

View File

@ -31,12 +31,12 @@
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width, minimum-scale=1, maximum-scale=1" /> <meta name="viewport" content="width=device-width, minimum-scale=1, maximum-scale=1" />
<title>${app_title}</title> <title>${app_title}</title>
<link rel="stylesheet" href="/files/jquery.mobile.css" /> <link rel="stylesheet" href="/files/jquery.mobile.min.css" />
<link rel="stylesheet" href="/files/openlp.css" /> <link rel="stylesheet" href="/files/openlp.css" />
<link rel="shortcut icon" type="image/x-icon" href="/files/images/favicon.ico"> <link rel="shortcut icon" type="image/x-icon" href="/files/images/favicon.ico">
<script type="text/javascript" src="/files/jquery.js"></script> <script type="text/javascript" src="/files/jquery.min.js"></script>
<script type="text/javascript" src="/files/openlp.js"></script> <script type="text/javascript" src="/files/openlp.js"></script>
<script type="text/javascript" src="/files/jquery.mobile.js"></script> <script type="text/javascript" src="/files/jquery.mobile.min.js"></script>
<script type="text/javascript"> <script type="text/javascript">
translationStrings = { translationStrings = {
"go_live": "${go_live}", "go_live": "${go_live}",

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -32,7 +32,7 @@
<title>${live_title}</title> <title>${live_title}</title>
<link rel="stylesheet" href="/files/main.css" /> <link rel="stylesheet" href="/files/main.css" />
<link rel="shortcut icon" type="image/x-icon" href="/files/images/favicon.ico"> <link rel="shortcut icon" type="image/x-icon" href="/files/images/favicon.ico">
<script type="text/javascript" src="/files/jquery.js"></script> <script type="text/javascript" src="/files/jquery.min.js"></script>
<script type="text/javascript" src="/files/main.js"></script> <script type="text/javascript" src="/files/main.js"></script>
</head> </head>
<body> <body>

View File

@ -32,7 +32,7 @@
background-image: url(images/ui-icon-unblank.png); background-image: url(images/ui-icon-unblank.png);
} }
/* Overwrite style from jquery-mobile.css */ /* Overwrite style from jquery-mobile.min.css */
.ui-li .ui-btn-text a.ui-link-inherit{ .ui-li .ui-btn-text a.ui-link-inherit{
white-space: normal; white-space: normal;
} }

View File

@ -32,7 +32,7 @@
<title>${stage_title}</title> <title>${stage_title}</title>
<link rel="stylesheet" href="/files/stage.css" /> <link rel="stylesheet" href="/files/stage.css" />
<link rel="shortcut icon" type="image/x-icon" href="/files/images/favicon.ico"> <link rel="shortcut icon" type="image/x-icon" href="/files/images/favicon.ico">
<script type="text/javascript" src="/files/jquery.js"></script> <script type="text/javascript" src="/files/jquery.min.js"></script>
<script type="text/javascript" src="/files/stage.js"></script> <script type="text/javascript" src="/files/stage.js"></script>
</head> </head>
<body> <body>

View File

@ -239,6 +239,7 @@ class OpenLyrics(object):
def __init__(self, manager): def __init__(self, manager):
self.manager = manager self.manager = manager
FormattingTags.load_tags()
def song_to_xml(self, song): def song_to_xml(self, song):
""" """
@ -582,18 +583,20 @@ class OpenLyrics(object):
# Some tags have only start html e.g. {br} # Some tags have only start html e.g. {br}
'end html': tag.close.text if hasattr(tag, 'close') else '', 'end html': tag.close.text if hasattr(tag, 'close') else '',
'protected': False, 'protected': False,
}
# Add 'temporary' key in case the formatting tag should not be saved otherwise it is supposed that # Add 'temporary' key in case the formatting tag should not be saved otherwise it is supposed that
# formatting tag is permanent. # formatting tag is permanent.
if temporary: 'temporary': temporary
openlp_tag['temporary'] = temporary }
found_tags.append(openlp_tag) found_tags.append(openlp_tag)
existing_tag_ids = [tag['start tag'] for tag in FormattingTags.get_html_tags()] existing_tag_ids = [tag['start tag'] for tag in FormattingTags.get_html_tags()]
new_tags = [tag for tag in found_tags if tag['start tag'] not in existing_tag_ids] new_tags = [tag for tag in found_tags if tag['start tag'] not in existing_tag_ids]
# Do not save an empty list. # Do not save an empty list.
if new_tags: if new_tags:
FormattingTags.add_html_tags(new_tags) FormattingTags.add_html_tags(new_tags)
FormattingTags.save_html_tags() if not temporary:
custom_tags = [tag for tag in FormattingTags.get_html_tags()
if not tag['protected'] and not tag['temporary']]
FormattingTags.save_html_tags(custom_tags)
def _process_lines_mixed_content(self, element, newlines=True): def _process_lines_mixed_content(self, element, newlines=True):
""" """

View File

@ -106,7 +106,7 @@ class JenkinsTrigger(object):
def print_output(self): def print_output(self):
""" """
Print the status information of the build tirggered. Print the status information of the build triggered.
""" """
print('Add this to your merge proposal:') print('Add this to your merge proposal:')
print('--------------------------------') print('--------------------------------')

View File

@ -0,0 +1,70 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2014 Raoul Snyman #
# Portions copyright (c) 2008-2014 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, #
# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. #
# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, #
# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, #
# Frode Woldsund, Martin Zibricky, Patrick Zimmermann #
# --------------------------------------------------------------------------- #
# This program is free software; you can redistribute it and/or modify it #
# under the terms of the GNU General Public License as published by the Free #
# Software Foundation; version 2 of the License. #
# #
# This program is distributed in the hope that it will be useful, but WITHOUT #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
# more details. #
# #
# You should have received a copy of the GNU General Public License along #
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
"""
Package to test the openlp.core.utils.actions package.
"""
from unittest import TestCase
from openlp.core.common.settings import Settings
from openlp.core.utils import VersionThread, get_application_version
from tests.functional import MagicMock, patch
from tests.helpers.testmixin import TestMixin
class TestInitFunctions(TestMixin, TestCase):
def setUp(self):
"""
Create an instance and a few example actions.
"""
self.build_settings()
def tearDown(self):
"""
Clean up
"""
self.destroy_settings()
def version_thread_triggered_test(self):
"""
Test the version thread call does not trigger UI
:return:
"""
# GIVEN: a equal version setup and the data is not today.
mocked_main_window = MagicMock()
Settings().setValue('core/last version test', '1950-04-01')
# WHEN: We check to see if the version is different .
with patch('PyQt4.QtCore.QThread'),\
patch('openlp.core.utils.get_application_version') as mocked_get_application_version:
mocked_get_application_version.return_value = \
{'version': '1.0.0', 'build': '', 'full': '2.0.4'}
version_thread = VersionThread(mocked_main_window)
version_thread.run()
# THEN: If the version has changed the main window is notified
self.assertTrue(mocked_main_window.emit.called, 'The main windows should have been notified')

View File

@ -71,7 +71,7 @@ class TestMediaItem(TestCase, TestMixin):
pdf_controller = MagicMock() pdf_controller = MagicMock()
pdf_controller.enabled.return_value = True pdf_controller.enabled.return_value = True
pdf_controller.supports = ['pdf'] pdf_controller.supports = ['pdf']
pdf_controller.also_supports = ['xps'] pdf_controller.also_supports = ['xps', 'oxps']
# Mock the controllers. # Mock the controllers.
self.media_item.controllers = { self.media_item.controllers = {
'Impress': impress_controller, 'Impress': impress_controller,
@ -90,3 +90,4 @@ class TestMediaItem(TestCase, TestMixin):
self.assertIn('*.ppt', self.media_item.on_new_file_masks, 'The file mask should contain the ppt extension') self.assertIn('*.ppt', self.media_item.on_new_file_masks, 'The file mask should contain the ppt extension')
self.assertIn('*.pdf', self.media_item.on_new_file_masks, 'The file mask should contain the pdf extension') self.assertIn('*.pdf', self.media_item.on_new_file_masks, 'The file mask should contain the pdf extension')
self.assertIn('*.xps', self.media_item.on_new_file_masks, 'The file mask should contain the xps extension') self.assertIn('*.xps', self.media_item.on_new_file_masks, 'The file mask should contain the xps extension')
self.assertIn('*.oxps', self.media_item.on_new_file_masks, 'The file mask should contain the oxps extension')

View File

@ -33,7 +33,7 @@ classes and related methods.
from unittest import TestCase from unittest import TestCase
import os import os
from openlp.plugins.presentations.lib.presentationcontroller import PresentationController, PresentationDocument from openlp.plugins.presentations.lib.presentationcontroller import PresentationController, PresentationDocument
from tests.functional import MagicMock, patch, mock_open from tests.functional import MagicMock, mock_open, patch
FOLDER_TO_PATCH = 'openlp.plugins.presentations.lib.presentationcontroller.PresentationDocument.get_thumbnail_folder' FOLDER_TO_PATCH = 'openlp.plugins.presentations.lib.presentationcontroller.PresentationDocument.get_thumbnail_folder'
@ -42,6 +42,19 @@ class TestPresentationController(TestCase):
""" """
Test the PresentationController. Test the PresentationController.
""" """
# TODO: Items left to test
# PresentationController
# __init__
# enabled
# is_available
# check_available
# start_process
# kill
# add_document
# remove_doc
# close_presentation
# _get_plugin_manager
def setUp(self): def setUp(self):
mocked_plugin = MagicMock() mocked_plugin = MagicMock()
mocked_plugin.settings_section = 'presentations' mocked_plugin.settings_section = 'presentations'
@ -164,3 +177,124 @@ class TestPresentationController(TestCase):
# THEN: it should return two empty lists # THEN: it should return two empty lists
self.assertIs(type(result_titles), list, 'result_titles should be a list') self.assertIs(type(result_titles), list, 'result_titles should be a list')
class TestPresentationDocument(TestCase):
"""
Test the PresentationDocument Class
"""
# TODO: Items left to test
# PresentationDocument
# __init__
# presentation_deleted
# get_thumbnail_folder
# get_temp_folder
# check_thumbnails
# close_presentation
# is_active
# is_loaded
# blank_screen
# unblank_screen
# is_blank
# stop_presentation
# start_presentation
# get_slide_number
# get_slide_count
# goto_slide
# next_step
# previous_step
# convert_thumbnail
# get_thumbnail_path
# poll_slidenumber
# get_slide_text
# get_slide_notes
def setUp(self):
"""
Set up the patches and mocks need for all tests.
"""
self.check_directory_exists_patcher = \
patch('openlp.plugins.presentations.lib.presentationcontroller.check_directory_exists')
self.get_thumbnail_folder_patcher = \
patch('openlp.plugins.presentations.lib.presentationcontroller.PresentationDocument.get_thumbnail_folder')
self.os_patcher = patch('openlp.plugins.presentations.lib.presentationcontroller.os')
self._setup_patcher = \
patch('openlp.plugins.presentations.lib.presentationcontroller.PresentationDocument._setup')
self.mock_check_directory_exists = self.check_directory_exists_patcher.start()
self.mock_get_thumbnail_folder = self.get_thumbnail_folder_patcher.start()
self.mock_os = self.os_patcher.start()
self.mock_setup = self._setup_patcher.start()
self.mock_controller = MagicMock()
self.mock_get_thumbnail_folder.return_value = 'returned/path/'
def tearDown(self):
"""
Stop the patches
"""
self.check_directory_exists_patcher.stop()
self.get_thumbnail_folder_patcher.stop()
self.os_patcher.stop()
self._setup_patcher.stop()
def initialise_presentation_document_test(self):
"""
Test the PresentationDocument __init__ method when initialising the PresentationDocument Class
"""
# GIVEN: A mocked setup method and mocked controller
self.mock_setup.reset()
# WHEN: Creating an instance of PresentationDocument
PresentationDocument(self.mock_controller, 'Name')
# THEN: PresentationDocument._setup should have been called with the argument 'Name'
self.mock_setup.assert_called_once_with('Name')
def presentation_document_setup_test(self):
"""
Test the PresentationDocument _setup method when initialising the PresentationDocument Class
"""
self._setup_patcher.stop()
# GIVEN: A mocked controller, patched check_directory_exists and get_thumbnail_folder methods
# WHEN: Creating an instance of PresentationDocument
PresentationDocument(self.mock_controller, 'Name')
# THEN: check_directory_exists should have been called with 'returned/path/'
self.mock_check_directory_exists.assert_called_once_with('returned/path/')
self._setup_patcher.start()
def load_presentation_test(self):
"""
Test the PresentationDocument.load_presentation method.
"""
# GIVEN: An instance of PresentationDocument
instance = PresentationDocument(self.mock_controller, 'Name')
# WHEN: Calling load_presentation()
result = instance.load_presentation()
# THEN: load_presentation should return false
self.assertFalse(result, "PresentationDocument.load_presentation should return false.")
def get_file_name_test(self):
"""
Test the PresentationDocument.get_file_name method.
"""
# GIVEN: A mocked os.path.split which returns a list, an instance of PresentationDocument and
# arbitary file_path.
self.mock_os.path.split.return_value = ['directory', 'file.ext']
instance = PresentationDocument(self.mock_controller, 'Name')
instance.file_path = 'filepath'
# WHEN: Calling get_file_name
result = instance.get_file_name()
# THEN: get_file_name should return 'file.ext'
self.assertEqual(result, 'file.ext')

View File

@ -132,6 +132,7 @@ class TestRouter(TestCase, TestMixin):
Test the main poll logic Test the main poll logic
""" """
# GIVEN: a defined router with two slides # GIVEN: a defined router with two slides
Registry.create()
Registry().register('live_controller', MagicMock) Registry().register('live_controller', MagicMock)
router = HttpRouter() router = HttpRouter()
router.send_response = MagicMock() router.send_response = MagicMock()

View File

@ -35,6 +35,7 @@ from unittest import TestCase
from tests.functional import MagicMock, patch from tests.functional import MagicMock, patch
from openlp.core.common import Registry
from openlp.plugins.songs.lib.importers.easyworship import EasyWorshipSongImport, FieldDescEntry, FieldType from openlp.plugins.songs.lib.importers.easyworship import EasyWorshipSongImport, FieldDescEntry, FieldType
TEST_PATH = os.path.abspath( TEST_PATH = os.path.abspath(
@ -153,6 +154,11 @@ class TestEasyWorshipSongImport(TestCase):
""" """
Test the functions in the :mod:`ewimport` module. Test the functions in the :mod:`ewimport` module.
""" """
def setUp(self):
"""
Create the registry
"""
Registry.create()
def create_field_desc_entry_test(self): def create_field_desc_entry_test(self):
""" """

View File

@ -31,11 +31,17 @@ This module contains tests for the OpenLyrics song importer.
""" """
import os import os
import json
from unittest import TestCase from unittest import TestCase
from lxml import etree, objectify
from tests.functional import MagicMock, patch from tests.functional import MagicMock, patch
from tests.helpers.testmixin import TestMixin
from openlp.plugins.songs.lib.importers.openlyrics import OpenLyricsImport from openlp.plugins.songs.lib.importers.openlyrics import OpenLyricsImport
from openlp.plugins.songs.lib.importers.songimport import SongImport from openlp.plugins.songs.lib.importers.songimport import SongImport
from openlp.plugins.songs.lib.openlyricsxml import OpenLyrics
from openlp.core.common import Registry, Settings
TEST_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), TEST_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__),
'..', '..', '..', 'resources', 'openlyricssongs')) '..', '..', '..', 'resources', 'openlyricssongs'))
@ -59,11 +65,33 @@ SONG_TEST_DATA = {
} }
} }
start_tags = [{"protected": False, "desc": "z", "start tag": "{z}", "end html": "</strong>", "temporary": False,
"end tag": "{/z}", "start html": "strong>"}]
result_tags = [{"temporary": False, "protected": False, "desc": "z", "start tag": "{z}", "start html": "strong>",
"end html": "</strong>", "end tag": "{/z}"},
{"temporary": False, "end tag": "{/c}", "desc": "c", "start tag": "{c}",
"start html": "<span class=\"chord\" style=\"display:none\"><strong>", "end html": "</strong></span>",
"protected": False}]
class TestOpenLyricsImport(TestCase):
class TestOpenLyricsImport(TestCase, TestMixin):
""" """
Test the functions in the :mod:`openlyricsimport` module. Test the functions in the :mod:`openlyricsimport` module.
""" """
def setUp(self):
"""
Create the registry
"""
self.setup_application()
Registry.create()
self.build_settings()
def tearDown(self):
"""
Cleanup
"""
self.destroy_settings()
def create_importer_test(self): def create_importer_test(self):
""" """
Test creating an instance of the OpenLyrics file importer Test creating an instance of the OpenLyrics file importer
@ -97,3 +125,24 @@ class TestOpenLyricsImport(TestCase):
# THEN: The xml_to_song() method should have been called # THEN: The xml_to_song() method should have been called
self.assertTrue(importer.open_lyrics.xml_to_song.called) self.assertTrue(importer.open_lyrics.xml_to_song.called)
def process_formatting_tags_test(self):
"""
Test that _process_formatting_tags works
"""
# GIVEN: A OpenLyric XML with formatting tags and a mocked out manager
mocked_manager = MagicMock()
Settings().setValue('formattingTags/html_tags', json.dumps(start_tags))
ol = OpenLyrics(mocked_manager)
parser = etree.XMLParser(remove_blank_text=True)
parsed_file = etree.parse(open(os.path.join(TEST_PATH, 'duchu-tags.xml'), 'rb'), parser)
xml = etree.tostring(parsed_file).decode()
song_xml = objectify.fromstring(xml)
# WHEN: processing the formatting tags
ol._process_formatting_tags(song_xml, False)
# THEN: New tags should have been saved
self.assertListEqual(json.loads(json.dumps(result_tags)),
json.loads(str(Settings().value('formattingTags/html_tags'))),
'The formatting tags should contain both the old and the new')

View File

@ -35,6 +35,7 @@ from unittest import TestCase
from tests.helpers.songfileimport import SongImportTestHelper from tests.helpers.songfileimport import SongImportTestHelper
from openlp.plugins.songs.lib.importers.opensong import OpenSongImport from openlp.plugins.songs.lib.importers.opensong import OpenSongImport
from openlp.core.common import Registry
from tests.functional import patch, MagicMock from tests.functional import patch, MagicMock
TEST_PATH = os.path.abspath( TEST_PATH = os.path.abspath(
@ -64,6 +65,12 @@ class TestOpenSongImport(TestCase):
""" """
Test the functions in the :mod:`opensongimport` module. Test the functions in the :mod:`opensongimport` module.
""" """
def setUp(self):
"""
Create the registry
"""
Registry.create()
def create_importer_test(self): def create_importer_test(self):
""" """
Test creating an instance of the OpenSong file importer Test creating an instance of the OpenSong file importer

View File

@ -34,6 +34,7 @@ ProPresenter song files into the current installation database.
import os import os
from tests.helpers.songfileimport import SongImportTestHelper from tests.helpers.songfileimport import SongImportTestHelper
from openlp.core.common import Registry
TEST_PATH = os.path.abspath( TEST_PATH = os.path.abspath(
os.path.join(os.path.dirname(__file__), '..', '..', '..', 'resources', 'powerpraisesongs')) os.path.join(os.path.dirname(__file__), '..', '..', '..', 'resources', 'powerpraisesongs'))

View File

@ -38,12 +38,12 @@ TEST_PATH = os.path.abspath(
os.path.join(os.path.dirname(__file__), '..', '..', '..', 'resources', 'presentationmanagersongs')) os.path.join(os.path.dirname(__file__), '..', '..', '..', 'resources', 'presentationmanagersongs'))
class TestSongShowPlusFileImport(SongImportTestHelper): class TestPresentationManagerFileImport(SongImportTestHelper):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.importer_class_name = 'PresentationManagerImport' self.importer_class_name = 'PresentationManagerImport'
self.importer_module_name = 'presentationmanager' self.importer_module_name = 'presentationmanager'
super(TestSongShowPlusFileImport, self).__init__(*args, **kwargs) super(TestPresentationManagerFileImport, self).__init__(*args, **kwargs)
def test_song_import(self): def test_song_import(self):
""" """
@ -51,3 +51,5 @@ class TestSongShowPlusFileImport(SongImportTestHelper):
""" """
self.file_import([os.path.join(TEST_PATH, 'Great Is Thy Faithfulness.sng')], self.file_import([os.path.join(TEST_PATH, 'Great Is Thy Faithfulness.sng')],
self.load_external_result_data(os.path.join(TEST_PATH, 'Great Is Thy Faithfulness.json'))) self.load_external_result_data(os.path.join(TEST_PATH, 'Great Is Thy Faithfulness.json')))
self.file_import([os.path.join(TEST_PATH, 'Agnus Dei.sng')],
self.load_external_result_data(os.path.join(TEST_PATH, 'Agnus Dei.json')))

View File

@ -36,6 +36,7 @@ from unittest import TestCase
from tests.functional import MagicMock, patch from tests.functional import MagicMock, patch
from openlp.plugins.songs.lib.importers.songbeamer import SongBeamerImport from openlp.plugins.songs.lib.importers.songbeamer import SongBeamerImport
from openlp.plugins.songs.lib import VerseType from openlp.plugins.songs.lib import VerseType
from openlp.core.common import Registry
TEST_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), TEST_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__),
'..', '..', '..', 'resources', 'songbeamersongs')) '..', '..', '..', 'resources', 'songbeamersongs'))
@ -59,6 +60,12 @@ class TestSongBeamerImport(TestCase):
""" """
Test the functions in the :mod:`songbeamerimport` module. Test the functions in the :mod:`songbeamerimport` module.
""" """
def setUp(self):
"""
Create the registry
"""
Registry.create()
def create_importer_test(self): def create_importer_test(self):
""" """
Test creating an instance of the SongBeamer file importer Test creating an instance of the SongBeamer file importer

View File

@ -35,12 +35,19 @@ from unittest import TestCase
from tests.functional import MagicMock, patch from tests.functional import MagicMock, patch
from openlp.plugins.songs.lib.importers.zionworx import ZionWorxImport from openlp.plugins.songs.lib.importers.zionworx import ZionWorxImport
from openlp.plugins.songs.lib.importers.songimport import SongImport from openlp.plugins.songs.lib.importers.songimport import SongImport
from openlp.core.common import Registry
class TestZionWorxImport(TestCase): class TestZionWorxImport(TestCase):
""" """
Test the functions in the :mod:`zionworximport` module. Test the functions in the :mod:`zionworximport` module.
""" """
def setUp(self):
"""
Create the registry
"""
Registry.create()
def create_importer_test(self): def create_importer_test(self):
""" """
Test creating an instance of the ZionWorx file importer Test creating an instance of the ZionWorx file importer

View File

@ -33,9 +33,10 @@ import os
from unittest import TestCase from unittest import TestCase
from unittest.mock import MagicMock, patch from unittest.mock import MagicMock, patch
from PyQt4 import QtCore from PyQt4 import QtCore, QtGui
from openlp.core import OpenLP from openlp.core import OpenLP
from openlp.core.common import Settings
from tests.helpers.testmixin import TestMixin from tests.helpers.testmixin import TestMixin
@ -44,11 +45,13 @@ TEST_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'resou
class TestInit(TestCase, TestMixin): class TestInit(TestCase, TestMixin):
def setUp(self): def setUp(self):
self.build_settings()
with patch('openlp.core.common.OpenLPMixin.__init__') as constructor: with patch('openlp.core.common.OpenLPMixin.__init__') as constructor:
constructor.return_value = None constructor.return_value = None
self.openlp = OpenLP(list()) self.openlp = OpenLP(list())
def tearDown(self): def tearDown(self):
self.destroy_settings()
del self.openlp del self.openlp
def event_test(self): def event_test(self):
@ -68,3 +71,51 @@ class TestInit(TestCase, TestMixin):
self.assertTrue(result, "The method should have returned True.") self.assertTrue(result, "The method should have returned True.")
mocked_file_method.assert_called_once_with() mocked_file_method.assert_called_once_with()
self.assertEqual(self.openlp.args[0], file_path, "The path should be in args.") self.assertEqual(self.openlp.args[0], file_path, "The path should be in args.")
def backup_on_upgrade_first_install_test(self):
"""
Test that we don't try to backup on a new install
"""
# GIVEN: Mocked data version and OpenLP version which are the same
old_install = False
MOCKED_VERSION = {
'full': '2.2.0-bzr000',
'version': '2.2.0',
'build': 'bzr000'
}
Settings().setValue('core/application version', '2.2.0')
with patch('openlp.core.get_application_version') as mocked_get_application_version,\
patch('openlp.core.QtGui.QMessageBox.question') as mocked_question:
mocked_get_application_version.return_value = MOCKED_VERSION
mocked_question.return_value = QtGui.QMessageBox.No
# WHEN: We check if a backup should be created
self.openlp.backup_on_upgrade(old_install)
# THEN: It should not ask if we want to create a backup
self.assertEqual(Settings().value('core/application version'), '2.2.0', 'Version should be the same!')
self.assertEqual(mocked_question.call_count, 0, 'No question should have been asked!')
def backup_on_upgrade_test(self):
"""
Test that we try to backup on a new install
"""
# GIVEN: Mocked data version and OpenLP version which are different
old_install = True
MOCKED_VERSION = {
'full': '2.2.0-bzr000',
'version': '2.2.0',
'build': 'bzr000'
}
Settings().setValue('core/application version', '2.0.5')
with patch('openlp.core.get_application_version') as mocked_get_application_version,\
patch('openlp.core.QtGui.QMessageBox.question') as mocked_question:
mocked_get_application_version.return_value = MOCKED_VERSION
mocked_question.return_value = QtGui.QMessageBox.No
# WHEN: We check if a backup should be created
self.openlp.backup_on_upgrade(old_install)
# THEN: It should ask if we want to create a backup
self.assertEqual(Settings().value('core/application version'), '2.2.0', 'Version should be upgraded!')
self.assertEqual(mocked_question.call_count, 1, 'A question should have been asked!')

View File

@ -34,6 +34,8 @@ import json
import logging import logging
from unittest import TestCase from unittest import TestCase
from openlp.plugins.songs.lib.importers.opensong import OpenSongImport
from openlp.core.common import Registry
from tests.functional import patch, MagicMock, call from tests.functional import patch, MagicMock, call
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -53,6 +55,7 @@ class SongImportTestHelper(TestCase):
""" """
Patch and set up the mocks required. Patch and set up the mocks required.
""" """
Registry.create()
self.add_copyright_patcher = patch('openlp.plugins.songs.lib.importers.%s.%s.add_copyright' % self.add_copyright_patcher = patch('openlp.plugins.songs.lib.importers.%s.%s.add_copyright' %
(self.importer_module_name, self.importer_class_name)) (self.importer_module_name, self.importer_class_name))
self.add_verse_patcher = patch('openlp.plugins.songs.lib.importers.%s.%s.add_verse' % self.add_verse_patcher = patch('openlp.plugins.songs.lib.importers.%s.%s.add_verse' %

View File

@ -0,0 +1,27 @@
<?xml version='1.0' encoding='utf-8'?>
<song xmlns="http://openlyrics.info/namespace/2009/song" version="0.8" createdIn="OpenLP 2.0.4" modifiedIn="OpenLP 2.0.4" modifiedDate="2014-06-27T09:55:49">
<properties>
<titles>
<title>Duchu svätý volám príď &lt;akordy&gt;</title>
</titles>
<authors>
<author>Author Unknown</author>
</authors>
</properties>
<format>
<tags application="OpenLP">
<tag name="c">
<open>&lt;span class="chord" style="display:none"&gt;&lt;strong&gt;</open>
<close>&lt;/strong&gt;&lt;/span&gt;</close>
</tag>
</tags>
</format>
<lyrics>
<verse name="v1">
<lines><tag name="c">[D]</tag>Duchu svätý volám príď, <tag name="c">[Ami]</tag>oheň mojej duši daj,<br/><tag name="c">[G]</tag>Oheň môjmu telu daj, <tag name="c">[D]</tag>rozpáľ ma.</lines>
</verse>
<verse name="c1">
<lines>Všemoh<tag name="c">[Ami]</tag>úci <tag name="c">[G]</tag>Boh tu s nami <tag name="c">[D]</tag>je,<br/>neko<tag name="c">[Ami]</tag>nečne <tag name="c">[G]</tag>milostivý <tag name="c">[D]</tag>je,<br/>Uka<tag name="c">[Ami]</tag>zuje <tag name="c">[G]</tag>dobrotivú <tag name="c">[D]</tag>tvár voči <tag name="c">[Ami]</tag>t<tag name="c">[G]</tag>ým,<br/>ktorí milovať ho <tag name="c">[D]</tag>chcú.</lines>
</verse>
</lyrics>
</song>

View File

@ -0,0 +1,14 @@
{
"title": "Agnus Dei",
"verse_order_list": ["v1", "v2"],
"verses": [
[
"Alleluia Alleluluia \nfor the Lord almighty reigns \nAlleluia Alleluluia \nHoly holy are you Lord God Almighty \nWorthy is the lamb \nWorthy is the lamb \nHoly holy are you Lord God Almighty",
"v1"
],
[
"Worthy is the lamb \nWorthy is the lamb \nYou are holy holy \nAre you lamb \nWorthy is the lamb \nYou are holy holy \nYou are holy holy",
"v2"
]
]
}

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<song xmlns="creativelifestyles/song">
<attributes>
<title>Agnus Dei</title>
<author></author>
<copyright></copyright>
<ccli_number></ccli_number>
<comments></comments>
</attributes>
<verses>
<verse id="Verse 1">
Alleluia Alleluluia
for the Lord almighty reigns
Alleluia Alleluluia
Holy holy are you Lord God Almighty
Worthy is the lamb
Worthy is the lamb
Holy holy are you Lord God Almighty
</verse>
<verse id="Verse 2">
Worthy is the lamb
Worthy is the lamb
You are holy holy
Are you lamb
Worthy is the lamb
You are holy holy
You are holy holy
</verse>
</verses>
</song>