diff --git a/openlp/core/ui/generaltab.py b/openlp/core/ui/generaltab.py
index 49497a10e..7fe7beaca 100644
--- a/openlp/core/ui/generaltab.py
+++ b/openlp/core/ui/generaltab.py
@@ -93,14 +93,14 @@ class GeneralTab(SettingsTab):
self.monitor_layout.addWidget(self.custom_width_label, 3, 3)
self.custom_width_value_edit = QtGui.QSpinBox(self.monitor_group_box)
self.custom_width_value_edit.setObjectName(u'custom_width_value_edit')
- self.custom_width_value_edit.setMaximum(9999)
+ self.custom_width_value_edit.setRange(1, 9999)
self.monitor_layout.addWidget(self.custom_width_value_edit, 4, 3)
self.custom_height_label = QtGui.QLabel(self.monitor_group_box)
self.custom_height_label.setObjectName(u'custom_height_label')
self.monitor_layout.addWidget(self.custom_height_label, 3, 4)
self.custom_height_value_edit = QtGui.QSpinBox(self.monitor_group_box)
self.custom_height_value_edit.setObjectName(u'custom_height_value_edit')
- self.custom_height_value_edit.setMaximum(9999)
+ self.custom_height_value_edit.setRange(1, 9999)
self.monitor_layout.addWidget(self.custom_height_value_edit, 4, 4)
self.display_on_monitor_check = QtGui.QCheckBox(self.monitor_group_box)
self.display_on_monitor_check.setObjectName(u'monitor_combo_box')
diff --git a/openlp/core/ui/themeform.py b/openlp/core/ui/themeform.py
index 68d8cc216..007932f6e 100644
--- a/openlp/core/ui/themeform.py
+++ b/openlp/core/ui/themeform.py
@@ -38,7 +38,7 @@ from openlp.core.lib import UiStrings, Registry, translate
from openlp.core.lib.theme import BackgroundType, BackgroundGradientType
from openlp.core.lib.ui import critical_error_message_box
from openlp.core.ui import ThemeLayoutForm
-from openlp.core.utils import get_images_filter
+from openlp.core.utils import get_images_filter, is_not_image_file
from themewizard import Ui_ThemeWizard
log = logging.getLogger(__name__)
@@ -178,7 +178,7 @@ class ThemeForm(QtGui.QWizard, Ui_ThemeWizard):
"""
background_image = BackgroundType.to_string(BackgroundType.Image)
if self.page(self.currentId()) == self.backgroundPage and \
- self.theme.background_type == background_image and not self.imageFileEdit.text():
+ self.theme.background_type == background_image and is_not_image_file(self.imageFileEdit.text()):
QtGui.QMessageBox.critical(self, translate('OpenLP.ThemeWizard', 'Background Image Empty'),
translate('OpenLP.ThemeWizard', 'You have not selected a '
'background image. Please select one before continuing.'))
diff --git a/openlp/core/utils/__init__.py b/openlp/core/utils/__init__.py
index 59dd08b27..0a4df48f8 100644
--- a/openlp/core/utils/__init__.py
+++ b/openlp/core/utils/__init__.py
@@ -246,6 +246,23 @@ def get_images_filter():
return IMAGES_FILTER
+def is_not_image_file(file_name):
+ """
+ Validate that the file is not an image file.
+
+ ``file_name``
+ File name to be checked.
+ """
+ if not file_name:
+ return True
+ else:
+ formats = [unicode(fmt).lower() for fmt in QtGui.QImageReader.supportedImageFormats()]
+ file_part, file_extension = os.path.splitext(unicode(file_name))
+ if file_extension[1:].lower() in formats and os.path.exists(file_name):
+ return False
+ return True
+
+
def split_filename(path):
"""
Return a list of the parts in a given path.
diff --git a/openlp/plugins/remotes/html/live.css b/openlp/plugins/remotes/html/main.css
similarity index 100%
rename from openlp/plugins/remotes/html/live.css
rename to openlp/plugins/remotes/html/main.css
diff --git a/openlp/plugins/remotes/html/live.html b/openlp/plugins/remotes/html/main.html
similarity index 95%
rename from openlp/plugins/remotes/html/live.html
rename to openlp/plugins/remotes/html/main.html
index f9a2c874c..3fbd42447 100644
--- a/openlp/plugins/remotes/html/live.html
+++ b/openlp/plugins/remotes/html/main.html
@@ -30,10 +30,10 @@
${live_title}
-
+
-
+
diff --git a/openlp/plugins/remotes/html/live.js b/openlp/plugins/remotes/html/main.js
similarity index 98%
rename from openlp/plugins/remotes/html/live.js
rename to openlp/plugins/remotes/html/main.js
index d55072c16..4f4f36351 100644
--- a/openlp/plugins/remotes/html/live.js
+++ b/openlp/plugins/remotes/html/main.js
@@ -26,7 +26,7 @@
window.OpenLP = {
loadSlide: function (event) {
$.getJSON(
- "/live/image",
+ "/main/image",
function (data, status) {
var img = document.getElementById('image');
img.src = data.results.slide_image;
@@ -36,7 +36,7 @@ window.OpenLP = {
},
pollServer: function () {
$.getJSON(
- "/live/poll",
+ "/main/poll",
function (data, status) {
if (OpenLP.slideCount != data.results.slide_count) {
OpenLP.slideCount = data.results.slide_count;
diff --git a/openlp/plugins/remotes/lib/httpserver.py b/openlp/plugins/remotes/lib/httpserver.py
index 671a85517..48a6a4d79 100644
--- a/openlp/plugins/remotes/lib/httpserver.py
+++ b/openlp/plugins/remotes/lib/httpserver.py
@@ -177,11 +177,11 @@ class HttpServer(object):
self.root = self.Public()
self.root.files = self.Files()
self.root.stage = self.Stage()
- self.root.live = self.Live()
+ self.root.main = self.Main()
self.root.router = self.router
self.root.files.router = self.router
self.root.stage.router = self.router
- self.root.live.router = self.router
+ self.root.main.router = self.router
cherrypy.tree.mount(self.root, '/', config=self.define_config())
# Turn off the flood of access messages cause by poll
cherrypy.log.access_log.propagate = False
@@ -218,7 +218,7 @@ class HttpServer(object):
u'/stage': {u'tools.staticdir.on': True,
u'tools.staticdir.dir': self.router.html_dir,
u'tools.basic_auth.on': False},
- u'/live': {u'tools.staticdir.on': True,
+ u'/main': {u'tools.staticdir.on': True,
u'tools.staticdir.dir': self.router.html_dir,
u'tools.basic_auth.on': False}}
return directory_config
@@ -253,9 +253,9 @@ class HttpServer(object):
url = urlparse.urlparse(cherrypy.url())
return self.router.process_http_request(url.path, *args)
- class Live(object):
+ class Main(object):
"""
- Live view is read only so security is not relevant and would reduce it's usability
+ Main view is read only so security is not relevant and would reduce it's usability
"""
@cherrypy.expose
def default(self, *args, **kwargs):
@@ -281,12 +281,12 @@ class HttpRouter(object):
self.routes = [
(u'^/$', self.serve_file),
(u'^/(stage)$', self.serve_file),
- (u'^/(live)$', self.serve_file),
+ (u'^/(main)$', self.serve_file),
(r'^/files/(.*)$', self.serve_file),
(r'^/api/poll$', self.poll),
(r'^/stage/poll$', self.poll),
- (r'^/live/poll$', self.live_poll),
- (r'^/live/image$', self.live_image),
+ (r'^/main/poll$', self.main_poll),
+ (r'^/main/image$', self.main_image),
(r'^/api/controller/(live|preview)/(.*)$', self.controller),
(r'^/stage/controller/(live|preview)/(.*)$', self.controller),
(r'^/api/service/(.*)$', self.service),
@@ -378,7 +378,7 @@ class HttpRouter(object):
'slides': translate('RemotePlugin.Mobile', 'Slides')
}
- def serve_file(self, filename=None):
+ def serve_file(self, file_name=None):
"""
Send a file to the socket. For now, just a subset of file types and must be top level inside the html folder.
If subfolders requested return 404, easier for security for the present.
@@ -386,17 +386,17 @@ class HttpRouter(object):
Ultimately for i18n, this could first look for xx/file.html before falling back to file.html.
where xx is the language, e.g. 'en'
"""
- log.debug(u'serve file request %s' % filename)
- if not filename:
- filename = u'index.html'
- elif filename == u'stage':
- filename = u'stage.html'
- elif filename == u'live':
- filename = u'live.html'
- path = os.path.normpath(os.path.join(self.html_dir, filename))
+ log.debug(u'serve file request %s' % file_name)
+ if not file_name:
+ file_name = u'index.html'
+ elif file_name == u'stage':
+ file_name = u'stage.html'
+ elif file_name == u'main':
+ file_name = u'main.html'
+ path = os.path.normpath(os.path.join(self.html_dir, file_name))
if not path.startswith(self.html_dir):
return self._http_not_found()
- ext = os.path.splitext(filename)[1]
+ ext = os.path.splitext(file_name)[1]
html = None
if ext == u'.html':
mimetype = u'text/html'
@@ -447,7 +447,7 @@ class HttpRouter(object):
cherrypy.response.headers['Content-Type'] = u'application/json'
return json.dumps({u'results': result}).encode()
- def live_poll(self):
+ def main_poll(self):
"""
Poll OpenLP to determine the current slide count.
"""
@@ -457,7 +457,7 @@ class HttpRouter(object):
cherrypy.response.headers['Content-Type'] = u'application/json'
return json.dumps({u'results': result}).encode()
- def live_image(self):
+ def main_image(self):
"""
Return the latest display image as a byte stream.
"""
diff --git a/scripts/check_dependencies.py b/scripts/check_dependencies.py
index bd7786b01..40377bb5b 100755
--- a/scripts/check_dependencies.py
+++ b/scripts/check_dependencies.py
@@ -83,7 +83,6 @@ MODULES = [
'bs4',
'mako',
'cherrypy',
- 'migrate',
'uno',
'icu',
'bs4',
diff --git a/tests/interfaces/openlp_core_utils/__init__.py b/tests/interfaces/openlp_core_utils/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/interfaces/openlp_core_utils/test_utils.py b/tests/interfaces/openlp_core_utils/test_utils.py
new file mode 100644
index 000000000..fe5d33560
--- /dev/null
+++ b/tests/interfaces/openlp_core_utils/test_utils.py
@@ -0,0 +1,52 @@
+"""
+Functional tests to test the AppLocation class and related methods.
+"""
+import os
+from unittest import TestCase
+
+from openlp.core.utils import is_not_image_file
+from tests.utils.constants import TEST_RESOURCES_PATH
+
+
+class TestUtils(TestCase):
+ """
+ A test suite to test out various methods around the Utils functions.
+ """
+ def is_not_image_empty_test(self):
+ """
+ Test the method handles an empty string
+ """
+ # Given and empty string
+ file_name = ""
+
+ # WHEN testing for it
+ result = is_not_image_file(file_name)
+
+ # THEN the result is false
+ assert result is True, u'The missing file test should return True'
+
+ def is_not_image_with_image_file_test(self):
+ """
+ Test the method handles an image file
+ """
+ # Given and empty string
+ file_name = os.path.join(TEST_RESOURCES_PATH, u'church.jpg')
+
+ # WHEN testing for it
+ result = is_not_image_file(file_name)
+
+ # THEN the result is false
+ assert result is False, u'The file is present so the test should return False'
+
+ def is_not_image_with_none_image_file_test(self):
+ """
+ Test the method handles a non image file
+ """
+ # Given and empty string
+ file_name = os.path.join(TEST_RESOURCES_PATH, u'serviceitem_custom_1.osj')
+
+ # WHEN testing for it
+ result = is_not_image_file(file_name)
+
+ # THEN the result is false
+ assert result is True, u'The file is not an image file so the test should return True'
\ No newline at end of file