openlp-core team mailing list archive
-
openlp-core team
-
Mailing list archive
-
Message #21037
[Merge] lp:~trb143/openlp/junefixes into lp:openlp
Tim Bentley has proposed merging lp:~trb143/openlp/junefixes into lp:openlp.
Requested reviews:
OpenLP Core (openlp-core)
Related bugs:
Bug #1196926 in OpenLP: "Zero division error when display size set to zero"
https://bugs.launchpad.net/openlp/+bug/1196926
Bug #1197376 in OpenLP: "Typing a path for a theme background causes a key error"
https://bugs.launchpad.net/openlp/+bug/1197376
For more details, see:
https://code.launchpad.net/~trb143/openlp/junefixes/+merge/174598
rename new url from live to main
fix display constraints
fix missing image test
add tests.
--
https://code.launchpad.net/~trb143/openlp/junefixes/+merge/174598
Your team OpenLP Core is requested to review the proposed merge of lp:~trb143/openlp/junefixes into lp:openlp.
=== modified file 'openlp/core/ui/generaltab.py'
--- openlp/core/ui/generaltab.py 2013-03-26 11:35:29 +0000
+++ openlp/core/ui/generaltab.py 2013-07-14 06:16:26 +0000
@@ -93,14 +93,14 @@
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')
=== modified file 'openlp/core/ui/themeform.py'
--- openlp/core/ui/themeform.py 2013-03-07 12:59:35 +0000
+++ openlp/core/ui/themeform.py 2013-07-14 06:16:26 +0000
@@ -38,7 +38,7 @@
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 @@
"""
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.'))
=== modified file 'openlp/core/utils/__init__.py'
--- openlp/core/utils/__init__.py 2013-06-20 18:04:21 +0000
+++ openlp/core/utils/__init__.py 2013-07-14 06:16:26 +0000
@@ -246,6 +246,23 @@
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.
=== renamed file 'openlp/plugins/remotes/html/live.css' => 'openlp/plugins/remotes/html/main.css'
=== renamed file 'openlp/plugins/remotes/html/live.html' => 'openlp/plugins/remotes/html/main.html'
--- openlp/plugins/remotes/html/live.html 2013-06-03 17:19:42 +0000
+++ openlp/plugins/remotes/html/main.html 2013-07-14 06:16:26 +0000
@@ -30,10 +30,10 @@
<head>
<meta charset="utf-8" />
<title>${live_title}</title>
- <link rel="stylesheet" href="/files/live.css" />
+ <link rel="stylesheet" href="/files/main.css" />
<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/live.js"></script>
+ <script type="text/javascript" src="/files/main.js"></script>
</head>
<body>
<img id="image" class="size"/>
=== renamed file 'openlp/plugins/remotes/html/live.js' => 'openlp/plugins/remotes/html/main.js'
--- openlp/plugins/remotes/html/live.js 2013-05-21 17:45:33 +0000
+++ openlp/plugins/remotes/html/main.js 2013-07-14 06:16:26 +0000
@@ -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 @@
},
pollServer: function () {
$.getJSON(
- "/live/poll",
+ "/main/poll",
function (data, status) {
if (OpenLP.slideCount != data.results.slide_count) {
OpenLP.slideCount = data.results.slide_count;
=== modified file 'openlp/plugins/remotes/lib/httpserver.py'
--- openlp/plugins/remotes/lib/httpserver.py 2013-05-25 17:05:44 +0000
+++ openlp/plugins/remotes/lib/httpserver.py 2013-07-14 06:16:26 +0000
@@ -177,11 +177,11 @@
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 @@
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 @@
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 @@
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 @@
'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 @@
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 @@
cherrypy.response.headers['Content-Type'] = u'application/json'
return json.dumps({u'results': result})
- def live_poll(self):
+ def main_poll(self):
"""
Poll OpenLP to determine the current slide count.
"""
@@ -457,7 +457,7 @@
cherrypy.response.headers['Content-Type'] = u'application/json'
return json.dumps({u'results': result})
- def live_image(self):
+ def main_image(self):
"""
Return the latest display image as a byte stream.
"""
=== added directory 'tests/interfaces/openlp_core_utils'
=== added file 'tests/interfaces/openlp_core_utils/__init__.py'
=== added file 'tests/interfaces/openlp_core_utils/test_utils.py'
--- tests/interfaces/openlp_core_utils/test_utils.py 1970-01-01 00:00:00 +0000
+++ tests/interfaces/openlp_core_utils/test_utils.py 2013-07-14 06:16:26 +0000
@@ -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
Follow ups