Esempio n. 1
0
    def test_image_to_byte_base_64(self):
        """
        Test the image_to_byte() function
        """
        with patch('openlp.core.lib.QtCore') as MockedQtCore:
            # GIVEN: A set of mocked-out Qt classes
            mocked_byte_array = MagicMock()
            MockedQtCore.QByteArray.return_value = mocked_byte_array
            mocked_byte_array.toBase64.return_value = QtCore.QByteArray(b'base64mock')
            mocked_buffer = MagicMock()
            MockedQtCore.QBuffer.return_value = mocked_buffer
            MockedQtCore.QIODevice.WriteOnly = 'writeonly'
            mocked_image = MagicMock()

            # WHEN: We convert an image to a byte array
            result = image_to_byte(mocked_image)

            # THEN: We should receive a value of 'base64mock'
            MockedQtCore.QByteArray.assert_called_with()
            MockedQtCore.QBuffer.assert_called_with(mocked_byte_array)
            mocked_buffer.open.assert_called_with('writeonly')
            mocked_image.save.assert_called_with(mocked_buffer, "PNG")
            mocked_byte_array.toBase64.assert_called_with()
            self.assertEqual('base64mock', result, 'The result should be the return value of the mocked out '
                                                   'base64 method')
Esempio n. 2
0
    def test_image_to_byte_base_64(self):
        """
        Test the image_to_byte() function
        """
        with patch('openlp.core.lib.QtCore') as MockedQtCore:
            # GIVEN: A set of mocked-out Qt classes
            mocked_byte_array = MagicMock()
            MockedQtCore.QByteArray.return_value = mocked_byte_array
            mocked_byte_array.toBase64.return_value = QtCore.QByteArray(
                b'base64mock')
            mocked_buffer = MagicMock()
            MockedQtCore.QBuffer.return_value = mocked_buffer
            MockedQtCore.QIODevice.WriteOnly = 'writeonly'
            mocked_image = MagicMock()

            # WHEN: We convert an image to a byte array
            result = image_to_byte(mocked_image)

            # THEN: We should receive a value of 'base64mock'
            MockedQtCore.QByteArray.assert_called_with()
            MockedQtCore.QBuffer.assert_called_with(mocked_byte_array)
            mocked_buffer.open.assert_called_with('writeonly')
            mocked_image.save.assert_called_with(mocked_buffer, "PNG")
            mocked_byte_array.toBase64.assert_called_with()
            assert 'base64mock' == result, 'The result should be the return value of the mocked out base64 method'
Esempio n. 3
0
 def setup(self):
     """
     Set up and build the output screen
     """
     self.log_debug('Start MainDisplay setup (live = %s)' % self.is_live)
     self.screen = self.screens.current
     self.setVisible(False)
     Display.setup(self)
     if self.is_live:
         # Build the initial frame.
         background_color = QtGui.QColor()
         background_color.setNamedColor(Settings().value('advanced/default color'))
         if not background_color.isValid():
             background_color = QtCore.Qt.white
         image_file = Settings().value('advanced/default image')
         splash_image = QtGui.QImage(image_file)
         self.initial_fame = QtGui.QImage(
             self.screen['size'].width(),
             self.screen['size'].height(),
             QtGui.QImage.Format_ARGB32_Premultiplied)
         painter_image = QtGui.QPainter()
         painter_image.begin(self.initial_fame)
         painter_image.fillRect(self.initial_fame.rect(), background_color)
         painter_image.drawImage(
             (self.screen['size'].width() - splash_image.width()) // 2,
             (self.screen['size'].height() - splash_image.height()) // 2,
             splash_image)
         service_item = ServiceItem()
         service_item.bg_image_bytes = image_to_byte(self.initial_fame)
         self.web_view.setHtml(build_html(service_item, self.screen, self.is_live, None,
                               plugins=self.plugin_manager.plugins))
         self._hide_mouse()
Esempio n. 4
0
 def serve_thumbnail(self, controller_name=None, dimensions=None, file_name=None):
     """
     Serve an image file. If not found return 404.
     """
     log.debug('serve thumbnail %s/thumbnails%s/%s' % (controller_name, dimensions, file_name))
     supported_controllers = ['presentations', 'images']
     # -1 means use the default dimension in ImageManager
     width = -1
     height = -1
     if dimensions:
         match = re.search('(\d+)x(\d+)', dimensions)
         if match:
             # let's make sure that the dimensions are within reason
             width = sorted([10, int(match.group(1)), 1000])[1]
             height = sorted([10, int(match.group(2)), 1000])[1]
     content = ''
     content_type = None
     if controller_name and file_name:
         if controller_name in supported_controllers:
             full_path = urllib.parse.unquote(file_name)
             if '..' not in full_path:  # no hacking please
                 full_path = os.path.normpath(os.path.join(AppLocation.get_section_data_path(controller_name),
                                                           'thumbnails/' + full_path))
                 if os.path.exists(full_path):
                     path, just_file_name = os.path.split(full_path)
                     self.image_manager.add_image(full_path, just_file_name, None, width, height)
                     ext, content_type = self.get_content_type(full_path)
                     image = self.image_manager.get_image(full_path, just_file_name, width, height)
                     content = image_to_byte(image, False)
     if len(content) == 0:
         return self.do_not_found()
     self.send_response(200)
     self.send_header('Content-type', content_type)
     self.end_headers()
     return content
Esempio n. 5
0
 def setup(self):
     """
     Set up and build the output screen
     """
     self.log_debug('Start MainDisplay setup (live = %s)' % self.is_live)
     self.screen = self.screens.current
     self.setVisible(False)
     Display.setup(self)
     if self.is_live:
         # Build the initial frame.
         background_color = QtGui.QColor()
         background_color.setNamedColor(Settings().value('advanced/default color'))
         if not background_color.isValid():
             background_color = QtCore.Qt.white
         image_file = Settings().value('advanced/default image')
         splash_image = QtGui.QImage(image_file)
         self.initial_fame = QtGui.QImage(
             self.screen['size'].width(),
             self.screen['size'].height(),
             QtGui.QImage.Format_ARGB32_Premultiplied)
         painter_image = QtGui.QPainter()
         painter_image.begin(self.initial_fame)
         painter_image.fillRect(self.initial_fame.rect(), background_color)
         painter_image.drawImage(
             (self.screen['size'].width() - splash_image.width()) // 2,
             (self.screen['size'].height() - splash_image.height()) // 2,
             splash_image)
         service_item = ServiceItem()
         service_item.bg_image_bytes = image_to_byte(self.initial_fame)
         self.web_view.setHtml(build_html(service_item, self.screen, self.is_live, None,
                               plugins=self.plugin_manager.plugins))
         self._hide_mouse()
Esempio n. 6
0
 def _process_cache(self):
     """
     Actually does the work.
     """
     log.debug('_processCache')
     image = self._conversion_queue.get()[2]
     # Generate the QImage for the image.
     if image.image is None:
         # Let's see if the image was requested with specific dimensions
         width = self.width if image.width == -1 else image.width
         height = self.height if image.height == -1 else image.height
         image.image = resize_image(
             image.path, width, height, image.background,
             Settings().value('advanced/ignore aspect ratio'))
         # Set the priority to Lowest and stop here as we need to process more important images first.
         if image.priority == Priority.Normal:
             self._conversion_queue.modify_priority(image, Priority.Lowest)
             return
         # For image with high priority we set the priority to Low, as the byte stream might be needed earlier the
         # byte stream of image with Normal priority. We stop here as we need to process more important images first.
         elif image.priority == Priority.High:
             self._conversion_queue.modify_priority(image, Priority.Low)
             return
     # Generate the byte stream for the image.
     if image.image_bytes is None:
         image.image_bytes = image_to_byte(image.image)
Esempio n. 7
0
 def main_image(self):
     """
     Return the latest display image as a byte stream.
     """
     result = {
         'slide_image': 'data:image/png;base64,' + str(image_to_byte(self.live_controller.slide_image))
     }
     self.do_json_header()
     return json.dumps({'results': result}).encode()
Esempio n. 8
0
 def main_image(self):
     """
     Return the latest display image as a byte stream.
     """
     result = {
         'slide_image': 'data:image/png;base64,' + str(image_to_byte(self.live_controller.slide_image))
     }
     cherrypy.response.headers['Content-Type'] = 'application/json'
     return json.dumps({'results': result}).encode()
Esempio n. 9
0
def main_image(request):
    """
    Return the latest display image as a byte stream.
    :param request: base path of the URL. Not used but passed by caller
    :return:
    """
    live_controller = Registry().get('live_controller')
    result = {
        'slide_image': 'data:image/png;base64,' + str(image_to_byte(live_controller.slide_image))
    }
    return {'results': result}
Esempio n. 10
0
 def main_image(self):
     """
     Return the latest display image as a byte stream.
     """
     result = {
         'slide_image':
         'data:image/png;base64,' +
         str(image_to_byte(self.live_controller.slide_image))
     }
     self.do_json_header()
     return json.dumps({'results': result}).encode()
Esempio n. 11
0
 def _add_preview_item(self, body, item, index):
     """
     Add a preview item
     """
     div = self._add_element('div', class_id='item', parent=body)
     # Add the title of the service item.
     item_title = self._add_element('h2', parent=div, class_id='itemTitle')
     img = image_to_byte(item.icon.pixmap(20, 20).toImage())
     self._add_element('img', parent=item_title, attribute=('src', 'data:image/png;base64, ' + img))
     self._add_element('span', ' ' + html.escape(item.get_display_title()), item_title)
     if self.slide_text_check_box.isChecked():
         # Add the text of the service item.
         if item.is_text():
             verse_def = None
             verse_html = None
             for slide in item.print_slides:
                 if not verse_def or verse_def != slide['verse'] or verse_html == slide['text']:
                     text_div = self._add_element('div', parent=div, class_id='itemText')
                 elif 'chordspacing' not in slide['text']:
                     self._add_element('br', parent=text_div)
                 self._add_element('span', slide['text'], text_div)
                 verse_def = slide['verse']
                 verse_html = slide['text']
             # Break the page before the div element.
             if index != 0 and self.page_break_after_text.isChecked():
                 div.set('class', 'item newPage')
         # Add the image names of the service item.
         elif item.is_image():
             ol = self._add_element('ol', parent=div, class_id='imageList')
             for slide in range(len(item.get_frames())):
                 self._add_element('li', item.get_frame_title(slide), ol)
         # add footer
         footer_html = item.footer_html
         footer_html = footer_html.partition('<br>')[2]
         if footer_html:
             footer_html = html.escape(footer_html.replace('<br>', '\n'))
             self._add_element('div', footer_html.replace('\n', '<br>'), parent=div, class_id='itemFooter')
     # Add service items' notes.
     if self.notes_check_box.isChecked():
         if item.notes:
             p = self._add_element('div', class_id='itemNotes', parent=div)
             self._add_element('span', translate('OpenLP.ServiceManager', 'Notes: '), p, class_id='itemNotesTitle')
             self._add_element('span', html.escape(item.notes).replace('\n', '<br>'), p, class_id='itemNotesText')
     # Add play length of media files.
     if item.is_media() and self.meta_data_check_box.isChecked():
         tme = item.media_length
         if item.end_time > 0:
             tme = item.end_time - item.start_time
         title = self._add_element('div', class_id='media', parent=div)
         self._add_element(
             'span', translate('OpenLP.ServiceManager', 'Playing time: '), title, class_id='mediaTitle')
         self._add_element('span', str(datetime.timedelta(seconds=tme)), title, class_id='mediaText')
Esempio n. 12
0
    def serve_thumbnail(self,
                        controller_name=None,
                        dimensions=None,
                        file_name=None):
        """
        Serve an image file. If not found return 404.

        :param file_name: file name to be served
        :param dimensions: image size
        :param controller_name: controller to be called
        """
        log.debug('serve thumbnail %s/thumbnails%s/%s' %
                  (controller_name, dimensions, file_name))
        supported_controllers = ['presentations', 'images']
        # -1 means use the default dimension in ImageManager
        width = -1
        height = -1
        if dimensions:
            match = re.search('(\d+)x(\d+)', dimensions)
            if match:
                # let's make sure that the dimensions are within reason
                width = sorted([10, int(match.group(1)), 1000])[1]
                height = sorted([10, int(match.group(2)), 1000])[1]
        content = ''
        content_type = None
        if controller_name and file_name:
            if controller_name in supported_controllers:
                full_path = urllib.parse.unquote(file_name)
                if '..' not in full_path:  # no hacking please
                    full_path = os.path.normpath(
                        os.path.join(
                            AppLocation.get_section_data_path(controller_name),
                            'thumbnails/' + full_path))
                    if os.path.exists(full_path):
                        path, just_file_name = os.path.split(full_path)
                        self.image_manager.add_image(full_path, just_file_name,
                                                     None, width, height)
                        ext, content_type = self.get_content_type(full_path)
                        image = self.image_manager.get_image(
                            full_path, just_file_name, width, height)
                        content = image_to_byte(image, False)
        if len(content) == 0:
            return self.do_not_found()
        self.send_response(200)
        self.send_header('Content-type', content_type)
        self.end_headers()
        return content
Esempio n. 13
0
def display_thumbnails(request,
                       controller_name,
                       log,
                       dimensions,
                       file_name,
                       slide=None):
    """
    Handles requests for adding a song to the service

    Return an image to a web page based on a URL
    :param request: Request object
    :param controller_name: which controller is requesting the image
    :param log: the logger object
    :param dimensions: the image size eg 88x88
    :param str file_name: the file name of the image
    :param slide: the individual image name
    :return:
    """
    log.debug('serve thumbnail {cname}/thumbnails{dim}/{fname}/{slide}'.format(
        cname=controller_name, dim=dimensions, fname=file_name, slide=slide))
    # -1 means use the default dimension in ImageManager
    width = -1
    height = -1
    image = None
    if dimensions:
        match = re.search(r'(\d+)x(\d+)', dimensions)
        if match:
            # let's make sure that the dimensions are within reason
            width = sorted([10, int(match.group(1)), 1000])[1]
            height = sorted([10, int(match.group(2)), 1000])[1]
    if controller_name and file_name:
        file_name = urllib.parse.unquote(file_name)
        if '..' not in file_name:  # no hacking please
            full_path = AppLocation.get_section_data_path(
                controller_name) / 'thumbnails' / file_name
            if slide:
                full_path = full_path / slide
            if full_path.exists():
                Registry().get('image_manager').add_image(
                    full_path, full_path.name, None, width, height)
                image = Registry().get('image_manager').get_image(
                    full_path, full_path.name, width, height)
    return Response(body=image_to_byte(image, False),
                    status=200,
                    content_type='image/png',
                    charset='utf8')
Esempio n. 14
0
 def _process_cache(self):
     """
     Actually does the work.
     """
     log.debug('_processCache')
     image = self._conversion_queue.get()[2]
     # Generate the QImage for the image.
     if image.image is None:
         image.image = resize_image(image.path, self.width, self.height, image.background)
         # Set the priority to Lowest and stop here as we need to process more important images first.
         if image.priority == Priority.Normal:
             self._conversion_queue.modify_priority(image, Priority.Lowest)
             return
         # For image with high priority we set the priority to Low, as the byte stream might be needed earlier the
         # byte stream of image with Normal priority. We stop here as we need to process more important images first.
         elif image.priority == Priority.High:
             self._conversion_queue.modify_priority(image, Priority.Low)
             return
     # Generate the byte stream for the image.
     if image.image_bytes is None:
         image.image_bytes = image_to_byte(image.image)