Ejemplo n.º 1
0
    def render(self, provides_own_theme_data=False):
        """
        The render method is what generates the frames for the screen and obtains the display information from the
        renderer. At this point all slides are built for the given display size.

        :param provides_own_theme_data: This switch disables the usage of the item's theme. However, this is
            disabled by default. If this is used, it has to be taken care, that
            the renderer knows the correct theme data. However, this is needed
            for the theme manager.
        """
        log.debug('Render called')
        self._display_frames = []
        self.bg_image_bytes = None
        if not provides_own_theme_data:
            self.renderer.set_item_theme(self.theme)
            self.theme_data, self.main, self.footer = self.renderer.pre_render()
        if self.service_item_type == ServiceItemType.Text:
            log.debug('Formatting slides: %s' % self.title)
            # Save rendered pages to this dict. In the case that a slide is used twice we can use the pages saved to
            # the dict instead of rendering them again.

            if self.get_plugin_name() == 'songs':
                if not self.extra_data_dict:
                    self.extra_data_dict = {}
                    if not self.xml_version.startswith('<?xml') and not self.xml_version.startswith('<song'):
                        # This is an old style song, without XML.
                        verses = self.xml_version.split('\n\n')
                        for count, verse in enumerate(verses):
                            self.extra_data_dict['v' + str(count)] = str(verse).split('\n')

                    elif self.xml_version.startswith('<?xml'):
                        # New style song, output as XML.
                        song_xml_split = re.split('(<verse[\w"= ]*>)', self.xml_version)
                        current_section = ''

                        for song_part in song_xml_split:
                            if song_part.startswith("<verse name"):
                                current_section = song_part.replace('<verse name="', '').replace('">', '')
                            elif song_part.startswith("<lines"):
                                # New line needed between <lines> sections
                                song_part = song_part.replace('</lines><line', '</lines><br/><line')
                                # Split out <lines>, </lines>, </verse>, </lyrics> and </song> tags
                                song_part = ''.join(re.split('<lines[\w"= ]*>', song_part))
                                song_part = song_part.replace('</lines>','').replace('</verse>', '')
                                song_part = song_part.replace('</lyrics>','').replace('</song>', '')
                                # Convert to list
                                self.extra_data_dict[current_section] = song_part.split('<br/>')

                previous_pages = {}

                # Get key and transpose amount, if used in this song
                if "<key>" in self.xml_version:
                    current_key = self.xml_version[(self.xml_version.index('<key>') + 5):(self.xml_version.index('<key>')+7)]
                    if current_key[1] == '<':
                        current_key = current_key[0]
                else:
                    current_key = ''

                if "<transposition>" in self.xml_version:
                    current_transpose = self.xml_version[(self.xml_version.index('<transposition>') + 15):(self.xml_version.index('<transposition>')+18)]
                    # Possible options: 1,...,9, 10, 11, -1, ... -9, -10, -11
                    if current_transpose[1] == '<':
                        current_transpose = int(current_transpose[0])
                    elif current_transpose[2] == '<':
                        current_transpose = int(current_transpose[0:2])
                else:
                    current_transpose = 0

                # Calculate resultant key for musician oriented view
                if current_key != '':
                    resultant_key = Chords.transpose_chord(current_key, current_key, current_transpose)
                else:
                    resultant_key = ''

                for slide in self._raw_frames:
                    verse_tag = slide['verseTag']
                    if verse_tag in previous_pages and previous_pages[verse_tag][0] == slide['raw_slide']:
                        pages = previous_pages[verse_tag][1]
                    else:
                        pages = self.renderer.format_slide(slide['raw_slide'], self)
                        previous_pages[verse_tag] = (slide['raw_slide'], pages)

                    xml_lines = self.extra_data_dict[verse_tag.lower()]
                    xml_line_lower, xml_line_upper = 0, 0

                    subpage_count = 0
                    for page in pages:
                        subpage_count += 1
                        page_lines = page.split('<br>')

                        # Given the current page_lines, calculate the corresponding xml_lines
                        xml_segment = ''
                        xml_line_lower = xml_line_upper

                        for line in page_lines:
                            while (xml_line_upper < len(xml_lines)) and not (''.join(re.split('<chord[\w\+#"=// ]* />', xml_lines[xml_line_upper])).strip() == line.strip()):
                                xml_line_upper += 1

                        xml_line_upper += 1
                        page_xml = xml_lines[xml_line_lower: xml_line_upper]

                        # Exclude any [br] or [---] elements from the XML list
                        page_xml_short = []
                        for item in page_xml:
                            if item != '[br]' and item != '[---]':
								# split item by chord tags, then transpose each chord tag
                                if current_transpose != 0:
                                    item_sections = re.split('(<chord[\w\+#"=// ]* />)', item)
                                    transposed_item = ''

                                    for item_section in item_sections:
                                        if item_section.startswith('<chord name'):
                                            transposed_item = transposed_item + Chords.transpose_chord_tag(item_section, current_key, current_transpose)
                                        else:
                                            transposed_item = transposed_item + item_section
                                    page_xml_short.append(transposed_item)
                                else:
                                    page_xml_short.append(item)

                        page = page.replace('<br>', '{br}')
                        html_data = expand_tags(html.escape(page.rstrip()))
                        self._display_frames.append({
                            'title': clean_tags(page),
                            'text': clean_tags(page.rstrip()),
                            'html': html_data.replace('&amp;nbsp;', '&nbsp;'),
                            'verseTag': verse_tag,
                            'verseSubpage': subpage_count,
                            'extraInfo': '<br>'.join(page_xml_short),
                            'playedKey': resultant_key
                        })

                        # Deal with any [br] tag in XML before processing next page
                        # TODO: Check if we need to also do this for [---] tags
                        if xml_line_upper < len(xml_lines) and xml_lines[xml_line_upper].strip() == '[br]':
                            xml_line_upper += 1

            else:
                previous_pages = {}
                for slide in self._raw_frames:
                    verse_tag = slide['verseTag']
                    if verse_tag in previous_pages and previous_pages[verse_tag][0] == slide['raw_slide']:
                        pages = previous_pages[verse_tag][1]
                    else:
                        pages = self.renderer.format_slide(slide['raw_slide'], self)
                        previous_pages[verse_tag] = (slide['raw_slide'], pages)

                    for page in pages:
                        page = page.replace('<br>', '{br}')
                        html_data = expand_tags(html.escape(page.rstrip()))
                        self._display_frames.append({
                            'title': clean_tags(page),
                            'text': clean_tags(page.rstrip()),
                            'html': html_data.replace('&amp;nbsp;', '&nbsp;'),
                            'verseTag': verse_tag,
                        })

        elif self.service_item_type == ServiceItemType.Image or self.service_item_type == ServiceItemType.Command:
            pass
        else:
            log.error('Invalid value renderer: %s' % self.service_item_type)
        self.title = clean_tags(self.title)
        # The footer should never be None, but to be compatible with a few
        # nightly builds between 1.9.4 and 1.9.5, we have to correct this to
        # avoid tracebacks.
        if self.raw_footer is None:
            self.raw_footer = []
        self.foot_text = '<br>'.join([_f for _f in self.raw_footer if _f])
Ejemplo n.º 2
0
    def process_chord_view(self, args):
        # Pre-condition: args is of the form update=n&capo=m, either one is optional
        # Also capo must be an integer m, 0<=m<=11
        update_id = "unset"
        capo = 0

        for update_option in args.split("&"):
            option_parts = update_option.split("=")
            if (option_parts[0] == "update"):
                update_id = option_parts[1]
            elif (option_parts[0] == "capo"):
                if (option_parts[1].isdigit() and int(option_parts[1]) >=0 and int(option_parts[1]) <= 11):
                    capo = int(option_parts[1])

        current_item = self.live_controller.service_item
        if current_item and current_item.get_plugin_name() == 'songs':
            if update_id == str(self.service_manager.last_update_count):
                json_data = {'status': 'current'}
            else:
                if (self.service_manager.stored_update_id == self.service_manager.last_update_count) and (capo == 0):
                    json_data = self.service_manager.stored_chord_json_data
                else:
                    current_frames = current_item.get_frames()
                    current_slide = str(current_frames[self.live_controller.selected_row]['extraInfo'])
                    if (self.live_controller.selected_row+1) != len(current_frames):
                        next_slide = str(current_frames[self.live_controller.selected_row+1]['extraInfo'])
                    else:
                        next_slide = ''

                    if (capo > 0) and (current_frames[0]['playedKey'] != ''): # Song has a key specified and a non-zero capo
                        musician_key = 'Capo ' + str(capo) + ' (' + Chords.transpose_chord(current_frames[0]['playedKey'], current_frames[0]['playedKey'], -capo) + ')'
                        current_slide_sections = re.split('(<chord[\w\+#"=// ]* />)', current_slide)
                        transposed_current_slide = ''

                        next_slide_sections = re.split('(<chord[\w\+#"=// ]* />)', next_slide)
                        transposed_next_slide = ''

                        for current_slide_section in current_slide_sections:
                            if current_slide_section.startswith('<chord name'):
                                transposed_current_slide = transposed_current_slide + Chords.transpose_chord_tag(current_slide_section, current_frames[0]['playedKey'], -capo)
                            else:
                                transposed_current_slide = transposed_current_slide + current_slide_section

                        for next_slide_section in next_slide_sections:
                            if next_slide_section.startswith('<chord name'):
                                transposed_next_slide = transposed_next_slide + Chords.transpose_chord_tag(next_slide_section, current_frames[0]['playedKey'], -capo)
                            else:
                                transposed_next_slide = transposed_next_slide + next_slide_section

                        current_slide = transposed_current_slide
                        next_slide = transposed_next_slide
                    else:
                        musician_key = current_frames[0]['playedKey']

                    song_order = []
                    for item, frame in enumerate(current_frames):
                        if item == self.live_controller.selected_row:
                            if frame['verseSubpage'] == 1: # First page of a verse/chorus
                                song_order.append("(" + frame['verseTag'] + ")")
                            else: # Not first page of verse/chorus, so verseTag already in list
                                song_order[-1] = "(" + frame['verseTag'] + ")"
                        else:
                            if frame['verseSubpage'] == 1:
                                song_order.append(frame['verseTag'])

                    json_data = {'status': 'update',
                                 'update_id': str(self.service_manager.last_update_count),
                                 'current_slide': current_slide.replace("\"", "'"),
                                 'next_slide': next_slide.replace("\"", "'"),
                                 'song_order': ' '.join(song_order),
                                 'played_key': musician_key}

                    if capo == 0:
                        self.service_manager.stored_update_id = self.service_manager.last_update_count
                        self.service_manager.stored_chord_json_data = json_data

        else:
            json_data = {'status': 'inactive'}

        self.do_json_header()
        return json.dumps(json_data).encode()
Ejemplo n.º 3
0
    def process_chord_view(self, args):
        # Pre-condition: args is of the form update=n&capo=m, either one is optional
        # Also capo must be an integer m, 0<=m<=11
        update_id = "unset"
        capo = 0

        for update_option in args.split("&"):
            option_parts = update_option.split("=")
            if (option_parts[0] == "update"):
                update_id = option_parts[1]
            elif (option_parts[0] == "capo"):
                if (option_parts[1].isdigit() and int(option_parts[1]) >= 0
                        and int(option_parts[1]) <= 11):
                    capo = int(option_parts[1])

        current_item = self.live_controller.service_item
        if current_item and current_item.get_plugin_name() == 'songs':
            if update_id == str(self.service_manager.last_update_count):
                json_data = {'status': 'current'}
            else:
                if (self.service_manager.stored_update_id
                        == self.service_manager.last_update_count) and (capo
                                                                        == 0):
                    json_data = self.service_manager.stored_chord_json_data
                else:
                    current_frames = current_item.get_frames()
                    current_slide = str(current_frames[
                        self.live_controller.selected_row]['extraInfo'])
                    if (self.live_controller.selected_row +
                            1) != len(current_frames):
                        next_slide = str(
                            current_frames[self.live_controller.selected_row +
                                           1]['extraInfo'])
                    else:
                        next_slide = ''

                    if (capo > 0) and (
                            current_frames[0]['playedKey'] != ''
                    ):  # Song has a key specified and a non-zero capo
                        musician_key = 'Capo ' + str(
                            capo) + ' (' + Chords.transpose_chord(
                                current_frames[0]['playedKey'],
                                current_frames[0]['playedKey'], -capo) + ')'
                        current_slide_sections = re.split(
                            '(<chord[\w\+#"=// ]* />)', current_slide)
                        transposed_current_slide = ''

                        next_slide_sections = re.split(
                            '(<chord[\w\+#"=// ]* />)', next_slide)
                        transposed_next_slide = ''

                        for current_slide_section in current_slide_sections:
                            if current_slide_section.startswith('<chord name'):
                                transposed_current_slide = transposed_current_slide + Chords.transpose_chord_tag(
                                    current_slide_section,
                                    current_frames[0]['playedKey'], -capo)
                            else:
                                transposed_current_slide = transposed_current_slide + current_slide_section

                        for next_slide_section in next_slide_sections:
                            if next_slide_section.startswith('<chord name'):
                                transposed_next_slide = transposed_next_slide + Chords.transpose_chord_tag(
                                    next_slide_section,
                                    current_frames[0]['playedKey'], -capo)
                            else:
                                transposed_next_slide = transposed_next_slide + next_slide_section

                        current_slide = transposed_current_slide
                        next_slide = transposed_next_slide
                    else:
                        musician_key = current_frames[0]['playedKey']

                    song_order = []
                    for item, frame in enumerate(current_frames):
                        if item == self.live_controller.selected_row:
                            if frame[
                                    'verseSubpage'] == 1:  # First page of a verse/chorus
                                song_order.append("(" + frame['verseTag'] +
                                                  ")")
                            else:  # Not first page of verse/chorus, so verseTag already in list
                                song_order[-1] = "(" + frame['verseTag'] + ")"
                        else:
                            if frame['verseSubpage'] == 1:
                                song_order.append(frame['verseTag'])

                    subpage_list = []
                    subpage = 1
                    for item, frame in enumerate(current_frames):
                        if frame['verseSubpage'] == 1:
                            subpage = 1
                            subpage_list.append("1")
                        else:
                            subpage = subpage + 1
                            subpage_list[-1] = str(subpage)

                    json_data = {
                        'status': 'update',
                        'update_id':
                        str(self.service_manager.last_update_count),
                        'current_slide': current_slide.replace("\"", "'"),
                        'next_slide': next_slide.replace("\"", "'"),
                        'song_order': ' '.join(song_order),
                        'subpages': ' '.join(subpage_list),
                        'played_key': musician_key,
                        'slide_type': 'songs'
                    }

                    if capo == 0:
                        self.service_manager.stored_update_id = self.service_manager.last_update_count
                        self.service_manager.stored_chord_json_data = json_data

        elif current_item and current_item.get_plugin_name() == 'custom':
            if update_id == str(self.service_manager.last_update_count):
                json_data = {'status': 'current'}
            else:
                current_frames = current_item.get_frames()
                current_slide = str(
                    current_frames[self.live_controller.selected_row]['html'])
                if (self.live_controller.selected_row +
                        1) != len(current_frames):
                    next_slide = str(
                        current_frames[self.live_controller.selected_row +
                                       1]['html'])
                else:
                    next_slide = ''

                json_data = {
                    'status': 'update',
                    'update_id': str(self.service_manager.last_update_count),
                    'current_slide': current_slide.replace("\"", "'"),
                    'next_slide': next_slide.replace("\"", "'"),
                    'song_order': '',
                    'subpages': '',
                    'played_key': '',
                    'slide_type': 'custom'
                }

        elif current_item and current_item.get_plugin_name() == 'bibles':
            if update_id == str(self.service_manager.last_update_count):
                json_data = {'status': 'current'}
            else:
                current_frames = current_item.get_frames()
                current_slide = str(
                    current_frames[self.live_controller.selected_row]['html'])
                if (self.live_controller.selected_row +
                        1) != len(current_frames):
                    next_slide = str(
                        current_frames[self.live_controller.selected_row +
                                       1]['html'])
                else:
                    next_slide = ''

                json_data = {
                    'status':
                    'update',
                    'update_id':
                    str(self.service_manager.last_update_count),
                    'current_slide':
                    current_slide.replace("\"", "'"),
                    'next_slide':
                    next_slide.replace("\"", "'"),
                    'song_order':
                    current_frames[self.live_controller.selected_row]
                    ['extraInfo'],
                    'subpages':
                    '',
                    'played_key':
                    '',
                    'slide_type':
                    'bibles'
                }

        else:
            json_data = {'status': 'inactive'}

        self.do_json_header()
        return json.dumps(json_data).encode()