← Back to team overview

openlp-core team mailing list archive

[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