예제 #1
0
 def _extract_verse_order(self, verse_order):
     order = []
     order_names = str(verse_order).split()
     for item in order_names:
         if len(item) == 1:
             verse_index = VerseType.from_translated_tag(item, None)
             if verse_index is not None:
                 order.append(VerseType.tags[verse_index] + '1')
             else:
                 # it matches no verses anyway
                 order.append('')
         else:
             verse_index = VerseType.from_translated_tag(item[0], None)
             if verse_index is None:
                 # it matches no verses anyway
                 order.append('')
             else:
                 verse_tag = VerseType.tags[verse_index]
                 verse_num = item[1:].lower()
                 order.append(verse_tag + verse_num)
     return order
예제 #2
0
    def generate_slide_data(self, service_item, item=None, xml_version=False, remote=False,
                            context=ServiceItemContext.Service):
        """
        Generate the slide data. Needs to be implemented by the plugin.

        :param service_item: The service item to be built on
        :param item: The Song item to be used
        :param xml_version: The xml version (not used)
        :param remote: Triggered from remote
        :param context: Why is it being generated
        """
        log.debug('generate_slide_data: {service}, {item}, {remote}'.format(service=service_item, item=item,
                                                                            remote=self.remote_song))
        item_id = self._get_id_of_item_to_generate(item, self.remote_song)
        service_item.add_capability(ItemCapabilities.CanEdit)
        service_item.add_capability(ItemCapabilities.CanPreview)
        service_item.add_capability(ItemCapabilities.CanLoop)
        service_item.add_capability(ItemCapabilities.OnLoadUpdate)
        service_item.add_capability(ItemCapabilities.AddIfNewItem)
        service_item.add_capability(ItemCapabilities.CanSoftBreak)
        song = self.plugin.manager.get_object(Song, item_id)
        service_item.theme = song.theme_name
        service_item.edit_id = item_id
        verse_list = SongXML().get_verses(song.lyrics)
        # no verse list or only 1 space (in error)
        verse_tags_translated = False
        if VerseType.from_translated_string(str(verse_list[0][0]['type'])) is not None:
            verse_tags_translated = True
        if not song.verse_order.strip():
            for verse in verse_list:
                # We cannot use from_loose_input() here, because database is supposed to contain English lowercase
                # singlechar tags.
                verse_tag = verse[0]['type']
                verse_index = None
                if len(verse_tag) > 1:
                    verse_index = VerseType.from_translated_string(verse_tag)
                    if verse_index is None:
                        verse_index = VerseType.from_string(verse_tag, None)
                if verse_index is None:
                    verse_index = VerseType.from_tag(verse_tag)
                verse_tag = VerseType.translated_tags[verse_index].upper()
                verse_def = '{tag}{label}'.format(tag=verse_tag, label=verse[0]['label'])
                service_item.add_from_text(str(verse[1]), verse_def)
        else:
            # Loop through the verse list and expand the song accordingly.
            for order in song.verse_order.lower().split():
                if not order:
                    break
                for verse in verse_list:
                    if verse[0]['type'][0].lower() == \
                            order[0] and (verse[0]['label'].lower() == order[1:] or not order[1:]):
                        if verse_tags_translated:
                            verse_index = VerseType.from_translated_tag(verse[0]['type'])
                        else:
                            verse_index = VerseType.from_tag(verse[0]['type'])
                        verse_tag = VerseType.translated_tags[verse_index]
                        verse_def = '{tag}{text}'.format(tag=verse_tag, text=verse[0]['label'])
                        service_item.add_from_text(verse[1], verse_def)
        service_item.title = song.title
        author_list = self.generate_footer(service_item, song)
        service_item.data_string = {'title': song.search_title, 'authors': ', '.join(author_list)}
        service_item.xml_version = self.open_lyrics.song_to_xml(song)
        # Add the audio file to the service item.
        if song.media_files:
            service_item.add_capability(ItemCapabilities.HasBackgroundAudio)
            service_item.background_audio = [m.file_name for m in song.media_files]
        return True
예제 #3
0
    def generate_slide_data(self, service_item, item=None, xml_version=False, remote=False,
                            context=ServiceItemContext.Service):
        """
        Generate the slide data. Needs to be implemented by the plugin.

        :param service_item: The service item to be built on
        :param item: The Song item to be used
        :param xml_version: The xml version (not used)
        :param remote: Triggered from remote
        :param context: Why is it being generated
        """
        log.debug('generate_slide_data: %s, %s, %s' % (service_item, item, self.remote_song))
        item_id = self._get_id_of_item_to_generate(item, self.remote_song)
        service_item.add_capability(ItemCapabilities.CanEdit)
        service_item.add_capability(ItemCapabilities.CanPreview)
        service_item.add_capability(ItemCapabilities.CanLoop)
        service_item.add_capability(ItemCapabilities.OnLoadUpdate)
        service_item.add_capability(ItemCapabilities.AddIfNewItem)
        service_item.add_capability(ItemCapabilities.CanSoftBreak)
        song = self.plugin.manager.get_object(Song, item_id)
        service_item.theme = song.theme_name
        service_item.edit_id = item_id
        verse_list = SongXML().get_verses(song.lyrics)
        # no verse list or only 1 space (in error)
        verse_tags_translated = False
        if VerseType.from_translated_string(str(verse_list[0][0]['type'])) is not None:
            verse_tags_translated = True
        if not song.verse_order.strip():
            for verse in verse_list:
                # We cannot use from_loose_input() here, because database is supposed to contain English lowercase
                # singlechar tags.
                verse_tag = verse[0]['type']
                verse_index = None
                if len(verse_tag) > 1:
                    verse_index = VerseType.from_translated_string(verse_tag)
                    if verse_index is None:
                        verse_index = VerseType.from_string(verse_tag, None)
                if verse_index is None:
                    verse_index = VerseType.from_tag(verse_tag)
                verse_tag = VerseType.translated_tags[verse_index].upper()
                verse_def = '%s%s' % (verse_tag, verse[0]['label'])
                service_item.add_from_text(str(verse[1]), verse_def)
        else:
            # Loop through the verse list and expand the song accordingly.
            for order in song.verse_order.lower().split():
                if not order:
                    break
                for verse in verse_list:
                    if verse[0]['type'][0].lower() == \
                            order[0] and (verse[0]['label'].lower() == order[1:] or not order[1:]):
                        if verse_tags_translated:
                            verse_index = VerseType.from_translated_tag(verse[0]['type'])
                        else:
                            verse_index = VerseType.from_tag(verse[0]['type'])
                        verse_tag = VerseType.translated_tags[verse_index]
                        verse_def = '%s%s' % (verse_tag, verse[0]['label'])
                        service_item.add_from_text(verse[1], verse_def)
        service_item.title = song.title
        author_list = self.generate_footer(service_item, song)
        service_item.data_string = {'title': song.search_title, 'authors': ', '.join(author_list)}
        service_item.set_extra_data_dict(self.open_lyrics.song_to_line_dict(song))
        service_item.xml_version = self.open_lyrics.song_to_xml(song)
        # Add the audio file to the service item.
        if song.media_files:
            service_item.add_capability(ItemCapabilities.HasBackgroundAudio)
            service_item.background_audio = [m.file_name for m in song.media_files]
        return True
예제 #4
0
    def save_song(self, preview=False):
        """
        Get all the data from the widgets on the form, and then save it to the
        database. The form has been validated and all reference items
        (Authors, Books and Topics) have been saved before this function is
        called.

        ``preview``
            Should be ``True`` if the song is also previewed (boolean).
        """
        # The Song() assignment. No database calls should be made while a
        # Song() is in a partially complete state.
        if not self.song:
            self.song = Song()
        self.song.title = self.title_edit.text()
        self.song.alternate_title = self.alternative_edit.text()
        self.song.copyright = self.copyright_edit.text()
        # Values will be set when cleaning the song.
        self.song.search_title = ''
        self.song.search_lyrics = ''
        self.song.verse_order = ''
        self.song.comments = self.comments_edit.toPlainText()
        ordertext = self.verse_order_edit.text()
        order = []
        for item in ordertext.split():
            verse_tag = VerseType.tags[VerseType.from_translated_tag(item[0])]
            verse_num = item[1:].lower()
            order.append('%s%s' % (verse_tag, verse_num))
        self.song.verse_order = ' '.join(order)
        self.song.ccli_number = self.ccli_number_edit.text()
        self.song.song_number = self.song_book_number_edit.text()
        book_name = self.song_book_combo_box.currentText()
        if book_name:
            self.song.book = self.manager.get_object_filtered(Book,
                Book.name == book_name)
        else:
            self.song.book = None
        theme_name = self.theme_combo_box.currentText()
        if theme_name:
            self.song.theme_name = theme_name
        else:
            self.song.theme_name = None
        self._process_lyrics()
        self.song.authors = []
        for row in range(self.authors_list_view.count()):
            item = self.authors_list_view.item(row)
            authorId = (item.data(QtCore.Qt.UserRole))
            author = self.manager.get_object(Author, authorId)
            if author is not None:
                self.song.authors.append(author)
        self.song.topics = []
        for row in range(self.topics_list_view.count()):
            item = self.topics_list_view.item(row)
            topicId = (item.data(QtCore.Qt.UserRole))
            topic = self.manager.get_object(Topic, topicId)
            if topic is not None:
                self.song.topics.append(topic)
        # Save the song here because we need a valid id for the audio files.
        clean_song(self.manager, self.song)
        self.manager.save_object(self.song)
        audio_files = [a.file_name for a in self.song.media_files]
        log.debug(audio_files)
        save_path = os.path.join(AppLocation.get_section_data_path(self.media_item.plugin.name), 'audio',
            str(self.song.id))
        check_directory_exists(save_path)
        self.song.media_files = []
        files = []
        for row in range(self.audio_list_widget.count()):
            item = self.audio_list_widget.item(row)
            filename = item.data(QtCore.Qt.UserRole)
            if not filename.startswith(save_path):
                oldfile, filename = filename, os.path.join(save_path, os.path.split(filename)[1])
                shutil.copyfile(oldfile, filename)
            files.append(filename)
            media_file = MediaFile()
            media_file.file_name = filename
            media_file.type = 'audio'
            media_file.weight = row
            self.song.media_files.append(media_file)
        for audio in audio_files:
            if audio not in files:
                try:
                    os.remove(audio)
                except:
                    log.exception('Could not remove file: %s', audio)
        if not files:
            try:
                os.rmdir(save_path)
            except OSError:
                log.exception('Could not remove directory: %s', save_path)
        clean_song(self.manager, self.song)
        self.manager.save_object(self.song)
        self.media_item.auto_select_id = self.song.id
예제 #5
0
    def load_song(self, song_id, preview=False):
        """
        Loads a song.

        ``song_id``
            The song id (int).

        ``preview``
            Should be ``True`` if the song is also previewed (boolean).
        """
        log.debug('Load Song')
        self.initialise()
        self.song_tab_widget.setCurrentIndex(0)
        self.load_authors()
        self.load_topics()
        self.load_books()
        self.load_media_files()
        self.song = self.manager.get_object(Song, song_id)
        self.title_edit.setText(self.song.title)
        self.alternative_edit.setText(
            self.song.alternate_title if self.song.alternate_title else '')
        if self.song.song_book_id != 0:
            book_name = self.manager.get_object(Book, self.song.song_book_id)
            find_and_set_in_combo_box(self.song_book_combo_box, str(book_name.name))
        else:
            self.song_book_combo_box.setEditText('')
            self.song_book_combo_box.setCurrentIndex(0)
        if self.song.theme_name:
            find_and_set_in_combo_box(self.theme_combo_box, str(self.song.theme_name))
        else:
            # Clear the theme combo box in case it was previously set (bug #1212801)
            self.theme_combo_box.setEditText('')
            self.theme_combo_box.setCurrentIndex(0)
        self.copyright_edit.setText(self.song.copyright if self.song.copyright else '')
        self.comments_edit.setPlainText(self.song.comments if self.song.comments else '')
        self.ccli_number_edit.setText(self.song.ccli_number if self.song.ccli_number else '')
        self.song_book_number_edit.setText(self.song.song_number if self.song.song_number else '')
        # lazy xml migration for now
        self.verse_list_widget.clear()
        self.verse_list_widget.setRowCount(0)
        verse_tags_translated = False
        if self.song.lyrics.startswith('<?xml version='):
            songXML = SongXML()
            verse_list = songXML.get_verses(self.song.lyrics)
            for count, verse in enumerate(verse_list):
                self.verse_list_widget.setRowCount(self.verse_list_widget.rowCount() + 1)
                # This silently migrates from localized verse type markup.
                # If we trusted the database, this would be unnecessary.
                verse_tag = verse[0]['type']
                index = None
                if len(verse_tag) > 1:
                    index = VerseType.from_translated_string(verse_tag)
                    if index is None:
                        index = VerseType.from_string(verse_tag, None)
                    else:
                        verse_tags_translated = True
                if index is None:
                    index = VerseType.from_tag(verse_tag)
                verse[0]['type'] = VerseType.tags[index]
                if verse[0]['label'] == '':
                    verse[0]['label'] = '1'
                verse_def = '%s%s' % (verse[0]['type'], verse[0]['label'])
                item = QtGui.QTableWidgetItem(verse[1])
                item.setData(QtCore.Qt.UserRole, verse_def)
                self.verse_list_widget.setItem(count, 0, item)
        else:
            verses = self.song.lyrics.split('\n\n')
            for count, verse in enumerate(verses):
                self.verse_list_widget.setRowCount(self.verse_list_widget.rowCount() + 1)
                item = QtGui.QTableWidgetItem(verse)
                verse_def = '%s%s' % (VerseType.tags[VerseType.Verse], str(count + 1))
                item.setData(QtCore.Qt.UserRole, verse_def)
                self.verse_list_widget.setItem(count, 0, item)
        if self.song.verse_order:
            # we translate verse order
            translated = []
            for verse_def in self.song.verse_order.split():
                verse_index = None
                if verse_tags_translated:
                    verse_index = VerseType.from_translated_tag(verse_def[0], None)
                if verse_index is None:
                    verse_index = VerseType.from_tag(verse_def[0])
                verse_tag = VerseType.translated_tags[verse_index].upper()
                translated.append('%s%s' % (verse_tag, verse_def[1:]))
            self.verse_order_edit.setText(' '.join(translated))
        else:
            self.verse_order_edit.setText('')
        self.tag_rows()
        # clear the results
        self.authors_list_view.clear()
        for author in self.song.authors:
            author_name = QtGui.QListWidgetItem(str(author.display_name))
            author_name.setData(QtCore.Qt.UserRole, author.id)
            self.authors_list_view.addItem(author_name)
        # clear the results
        self.topics_list_view.clear()
        for topic in self.song.topics:
            topic_name = QtGui.QListWidgetItem(str(topic.name))
            topic_name.setData(QtCore.Qt.UserRole, topic.id)
            self.topics_list_view.addItem(topic_name)
        self.audio_list_widget.clear()
        for media in self.song.media_files:
            media_file = QtGui.QListWidgetItem(os.path.split(media.file_name)[1])
            media_file.setData(QtCore.Qt.UserRole, media.file_name)
            self.audio_list_widget.addItem(media_file)
        self.title_edit.setFocus()
        # Hide or show the preview button.
        self.preview_button.setVisible(preview)
        # Check if all verse tags are used.
        self.on_verse_order_text_changed(self.verse_order_edit.text())
예제 #6
0
 def generateSlideData(self, service_item, item=None, xmlVersion=False,
             remote=False, context=ServiceItemContext.Service):
     log.debug(u'generateSlideData: %s, %s, %s' % (service_item, item, self.remoteSong))
     item_id = self._getIdOfItemToGenerate(item, self.remoteSong)
     service_item.add_capability(ItemCapabilities.CanEdit)
     service_item.add_capability(ItemCapabilities.CanPreview)
     service_item.add_capability(ItemCapabilities.CanLoop)
     service_item.add_capability(ItemCapabilities.OnLoadUpdate)
     service_item.add_capability(ItemCapabilities.AddIfNewItem)
     service_item.add_capability(ItemCapabilities.CanSoftBreak)
     song = self.plugin.manager.get_object(Song, item_id)
     service_item.theme = song.theme_name
     service_item.edit_id = item_id
     if song.lyrics.startswith(u'<?xml version='):
         verse_list = SongXML().get_verses(song.lyrics)
         # no verse list or only 1 space (in error)
         verse_tags_translated = False
         if VerseType.from_translated_string(unicode(verse_list[0][0][u'type'])) is not None:
             verse_tags_translated = True
         if not song.verse_order.strip():
             for verse in verse_list:
                 # We cannot use from_loose_input() here, because database
                 # is supposed to contain English lowercase singlechar tags.
                 verse_tag = verse[0][u'type']
                 verse_index = None
                 if len(verse_tag) > 1:
                     verse_index = VerseType.from_translated_string(verse_tag)
                     if verse_index is None:
                         verse_index = VerseType.from_string(verse_tag, None)
                 if verse_index is None:
                     verse_index = VerseType.from_tag(verse_tag)
                 verse_tag = VerseType.TranslatedTags[verse_index].upper()
                 verse_def = u'%s%s' % (verse_tag, verse[0][u'label'])
                 service_item.add_from_text(unicode(verse[1]), verse_def)
         else:
             # Loop through the verse list and expand the song accordingly.
             for order in song.verse_order.lower().split():
                 if not order:
                     break
                 for verse in verse_list:
                     if verse[0][u'type'][0].lower() == order[0] and (verse[0][u'label'].lower() == order[1:] or \
                             not order[1:]):
                         if verse_tags_translated:
                             verse_index = VerseType.from_translated_tag(verse[0][u'type'])
                         else:
                             verse_index = VerseType.from_tag(verse[0][u'type'])
                         verse_tag = VerseType.TranslatedTags[verse_index]
                         verse_def = u'%s%s' % (verse_tag, verse[0][u'label'])
                         service_item.add_from_text(verse[1], verse_def)
     else:
         verses = song.lyrics.split(u'\n\n')
         for slide in verses:
             service_item.add_from_text(unicode(slide))
     service_item.title = song.title
     author_list = [unicode(author.display_name) for author in song.authors]
     service_item.raw_footer.append(song.title)
     service_item.raw_footer.append(create_separated_list(author_list))
     service_item.raw_footer.append(song.copyright)
     if Settings().value(u'general/ccli number'):
         service_item.raw_footer.append(translate('SongsPlugin.MediaItem', 'CCLI License: ') +
             Settings().value(u'general/ccli number'))
     service_item.audit = [
         song.title, author_list, song.copyright, unicode(song.ccli_number)
     ]
     service_item.data_string = {u'title': song.search_title, u'authors': u', '.join(author_list)}
     service_item.xml_version = self.openLyrics.song_to_xml(song)
     # Add the audio file to the service item.
     if song.media_files:
         service_item.add_capability(ItemCapabilities.HasBackgroundAudio)
         service_item.background_audio = [m.file_name for m in song.media_files]
     return True
예제 #7
0
파일: mediaitem.py 프로젝트: ipic/projecao
    def generate_slide_data(self,
                            service_item,
                            *,
                            item=None,
                            context=ServiceItemContext.Service,
                            **kwargs):
        """
        Generate the slide data. Needs to be implemented by the plugin.

        :param service_item: The service item to be built on
        :param item: The Song item to be used
        :param context: Why is it being generated
        :param kwargs: Consume other unused args specified by the base implementation, but not use by this one.
        """
        log.debug('generate_slide_data: {service}, {item}, {remote}'.format(
            service=service_item, item=item, remote=self.remote_song))
        item_id = self._get_id_of_item_to_generate(item, self.remote_song)
        service_item.add_capability(ItemCapabilities.CanEdit)
        service_item.add_capability(ItemCapabilities.CanPreview)
        service_item.add_capability(ItemCapabilities.CanLoop)
        service_item.add_capability(ItemCapabilities.OnLoadUpdate)
        service_item.add_capability(ItemCapabilities.AddIfNewItem)
        service_item.add_capability(ItemCapabilities.CanSoftBreak)
        service_item.add_capability(ItemCapabilities.HasMetaData)
        song = self.plugin.manager.get_object(Song, item_id)
        service_item.theme = song.theme_name
        service_item.edit_id = item_id
        verse_list = SongXML().get_verses(song.lyrics)
        if self.settings.value(
                'songs/add songbook slide') and song.songbook_entries:
            first_slide = '\n'
            for songbook_entry in song.songbook_entries:
                first_slide += '{book} #{num}'.format(
                    book=songbook_entry.songbook.name,
                    num=songbook_entry.entry)
                if songbook_entry.songbook.publisher:
                    first_slide += ' ({pub})'.format(
                        pub=songbook_entry.songbook.publisher)
                first_slide += '\n\n'

            service_item.add_from_text(first_slide, 'O1')
        # no verse list or only 1 space (in error)
        verse_tags_translated = False
        if VerseType.from_translated_string(str(
                verse_list[0][0]['type'])) is not None:
            verse_tags_translated = True
        if not song.verse_order.strip():
            for verse in verse_list:
                # We cannot use from_loose_input() here, because database is supposed to contain English lowercase
                # single char tags.
                verse_tag = verse[0]['type']
                verse_index = None
                if len(verse_tag) > 1:
                    verse_index = VerseType.from_translated_string(verse_tag)
                    if verse_index is None:
                        verse_index = VerseType.from_string(verse_tag, None)
                if verse_index is None:
                    verse_index = VerseType.from_tag(verse_tag)
                verse_tag = VerseType.translated_tags[verse_index].upper()
                verse_def = '{tag}{label}'.format(tag=verse_tag,
                                                  label=verse[0]['label'])
                force_verse = verse[1].split('[--}{--]\n')
                for split_verse in force_verse:
                    service_item.add_from_text(split_verse, verse_def)
        else:
            # Loop through the verse list and expand the song accordingly.
            for order in song.verse_order.lower().split():
                if not order:
                    break
                for verse in verse_list:
                    if verse[0]['type'][0].lower() == \
                            order[0] and (verse[0]['label'].lower() == order[1:] or not order[1:]):
                        if verse_tags_translated:
                            verse_index = VerseType.from_translated_tag(
                                verse[0]['type'])
                        else:
                            verse_index = VerseType.from_tag(verse[0]['type'])
                        verse_tag = VerseType.translated_tags[verse_index]
                        verse_def = '{tag}{label}'.format(
                            tag=verse_tag, label=verse[0]['label'])
                        force_verse = verse[1].split('[--}{--]\n')
                        for split_verse in force_verse:
                            service_item.add_from_text(split_verse, verse_def)
        service_item.title = song.title
        author_list = self.generate_footer(service_item, song)
        service_item.data_string = {
            'title': song.search_title,
            'authors': ', '.join(author_list)
        }
        service_item.xml_version = self.open_lyrics.song_to_xml(song)
        # Add the audio file to the service item.
        if song.media_files:
            if State().check_preconditions('media'):
                service_item.add_capability(
                    ItemCapabilities.HasBackgroundAudio)
                total_length = 0
                for m in song.media_files:
                    total_length += self.media_controller.media_length(
                        m.file_path)
                service_item.background_audio = [
                    m.file_path for m in song.media_files
                ]
                service_item.set_media_length(total_length)
                service_item.metadata.append(
                    '<em>{label}:</em> {media}'.format(
                        label=translate('SongsPlugin.MediaItem', 'Media'),
                        media=service_item.background_audio))
        return True