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')
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'
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()
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
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)
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()
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()
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}
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')
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
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')
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)