def save_song(self, song): """ Save a song to the database, using the db_manager :param song: :return: """ db_song = Song.populate(title=song['title'], copyright=song['copyright'], ccli_number=song['ccli_number']) song_xml = SongXML() verse_order = [] for verse in song['verses']: verse_type, verse_number = verse['label'].split(' ')[:2] verse_type = VerseType.from_loose_input(verse_type) verse_number = int(verse_number) song_xml.add_verse_to_lyrics(VerseType.tags[verse_type], verse_number, verse['lyrics']) verse_order.append('%s%s' % (VerseType.tags[verse_type], verse_number)) db_song.verse_order = ' '.join(verse_order) db_song.lyrics = song_xml.extract_xml() clean_song(self.db_manager, db_song) self.db_manager.save_object(db_song) db_song.authors_songs = [] for author_name in song['authors']: author = self.db_manager.get_object_filtered(Author, Author.display_name == author_name) if not author: author = Author.populate(first_name=author_name.rsplit(' ', 1)[0], last_name=author_name.rsplit(' ', 1)[1], display_name=author_name) db_song.add_author(author) self.db_manager.save_object(db_song) return db_song
def save_song(self, song): """ Save a song to the database, using the db_manager :param song: :return: """ db_song = Song.populate(title=song['title'], copyright=song['copyright'], ccli_number=song['ccli_number']) song_xml = SongXML() verse_order = [] for verse in song['verses']: if ' ' in verse['label']: verse_type, verse_number = verse['label'].split(' ', 1) else: verse_type = verse['label'] verse_number = 1 verse_type = VerseType.from_loose_input(verse_type) verse_number = int(verse_number) song_xml.add_verse_to_lyrics(VerseType.tags[verse_type], verse_number, verse['lyrics']) verse_order.append('%s%s' % (VerseType.tags[verse_type], verse_number)) db_song.verse_order = ' '.join(verse_order) db_song.lyrics = song_xml.extract_xml() clean_song(self.db_manager, db_song) self.db_manager.save_object(db_song) db_song.authors_songs = [] for author_name in song['authors']: author = self.db_manager.get_object_filtered( Author, Author.display_name == author_name) if not author: name_parts = author_name.rsplit(' ', 1) first_name = name_parts[0] if len(name_parts) == 1: last_name = '' else: last_name = name_parts[1] author = Author.populate(first_name=first_name, last_name=last_name, display_name=author_name) db_song.add_author(author) db_song.topics = [] for topic_name in song.get('topics', []): topic = self.db_manager.get_object_filtered( Topic, Topic.name == topic_name) if not topic: topic = Topic.populate(name=topic_name) db_song.topics.append(topic) self.db_manager.save_object(db_song) return db_song
def save_song(self, song): """ Save a song to the database, using the db_manager :param song: :return: """ db_song = Song.populate(title=song['title'], copyright=song['copyright'], ccli_number=song['ccli_number']) song_xml = SongXML() verse_order = [] for verse in song['verses']: if ' ' in verse['label']: verse_type, verse_number = verse['label'].split(' ', 1) else: verse_type = verse['label'] verse_number = 1 verse_type = VerseType.from_loose_input(verse_type) verse_number = int(verse_number) song_xml.add_verse_to_lyrics(VerseType.tags[verse_type], verse_number, verse['lyrics']) verse_order.append('{tag}{number}'.format(tag=VerseType.tags[verse_type], number=verse_number)) db_song.verse_order = ' '.join(verse_order) db_song.lyrics = song_xml.extract_xml() clean_song(self.db_manager, db_song) self.db_manager.save_object(db_song) db_song.authors_songs = [] for author_name in song['authors']: author = self.db_manager.get_object_filtered(Author, Author.display_name == author_name) if not author: name_parts = author_name.rsplit(' ', 1) first_name = name_parts[0] if len(name_parts) == 1: last_name = '' else: last_name = name_parts[1] author = Author.populate(first_name=first_name, last_name=last_name, display_name=author_name) db_song.add_author(author) for topic_name in song.get('topics', []): topic = self.db_manager.get_object_filtered(Topic, Topic.name == topic_name) if not topic: topic = Topic.populate(name=topic_name) db_song.topics.append(topic) self.db_manager.save_object(db_song) return db_song
def save_song(self, song): """ Save a song to the database, using the db_manager :param song: :return: """ db_song = Song.populate(title=song['title'], copyright=song['copyright'], ccli_number=song['ccli_number']) song_xml = SongXML() verse_order = [] for verse in song['verses']: verse_type, verse_number = verse['label'].split(' ')[:2] verse_type = VerseType.from_loose_input(verse_type) verse_number = int(verse_number) song_xml.add_verse_to_lyrics(VerseType.tags[verse_type], verse_number, verse['lyrics']) verse_order.append('%s%s' % (VerseType.tags[verse_type], verse_number)) db_song.verse_order = ' '.join(verse_order) db_song.lyrics = song_xml.extract_xml() clean_song(self.db_manager, db_song) self.db_manager.save_object(db_song) db_song.authors_songs = [] for author_name in song['authors']: author = self.db_manager.get_object_filtered( Author, Author.display_name == author_name) if not author: author = Author.populate(first_name=author_name.rsplit(' ', 1)[0], last_name=author_name.rsplit(' ', 1)[1], display_name=author_name) db_song.add_author(author) self.db_manager.save_object(db_song) return db_song
def setupUi(self): self.song_vertical_layout = QtWidgets.QVBoxLayout(self) self.song_vertical_layout.setObjectName('song_vertical_layout') self.song_group_box = QtWidgets.QGroupBox(self) self.song_group_box.setObjectName('song_group_box') self.song_group_box.setFixedWidth(300) self.song_group_box_layout = QtWidgets.QVBoxLayout(self.song_group_box) self.song_group_box_layout.setObjectName('song_group_box_layout') self.song_info_form_layout = QtWidgets.QFormLayout() self.song_info_form_layout.setObjectName('song_info_form_layout') # Add title widget. self.song_title_label = QtWidgets.QLabel(self) self.song_title_label.setObjectName('song_title_label') self.song_info_form_layout.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.song_title_label) self.song_title_content = QtWidgets.QLabel(self) self.song_title_content.setObjectName('song_title_content') self.song_title_content.setText(self.song.title) self.song_title_content.setWordWrap(True) self.song_info_form_layout.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.song_title_content) # Add alternate title widget. self.song_alternate_title_label = QtWidgets.QLabel(self) self.song_alternate_title_label.setObjectName( 'song_alternate_title_label') self.song_info_form_layout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.song_alternate_title_label) self.song_alternate_title_content = QtWidgets.QLabel(self) self.song_alternate_title_content.setObjectName( 'song_alternate_title_content') self.song_alternate_title_content.setText(self.song.alternate_title) self.song_alternate_title_content.setWordWrap(True) self.song_info_form_layout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.song_alternate_title_content) # Add CCLI number widget. self.song_ccli_number_label = QtWidgets.QLabel(self) self.song_ccli_number_label.setObjectName('song_ccli_number_label') self.song_info_form_layout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.song_ccli_number_label) self.song_ccli_number_content = QtWidgets.QLabel(self) self.song_ccli_number_content.setObjectName('song_ccli_number_content') self.song_ccli_number_content.setText(self.song.ccli_number) self.song_ccli_number_content.setWordWrap(True) self.song_info_form_layout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.song_ccli_number_content) # Add copyright widget. self.song_copyright_label = QtWidgets.QLabel(self) self.song_copyright_label.setObjectName('song_copyright_label') self.song_info_form_layout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.song_copyright_label) self.song_copyright_content = QtWidgets.QLabel(self) self.song_copyright_content.setObjectName('song_copyright_content') self.song_copyright_content.setWordWrap(True) self.song_copyright_content.setText(self.song.copyright) self.song_info_form_layout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.song_copyright_content) # Add comments widget. self.song_comments_label = QtWidgets.QLabel(self) self.song_comments_label.setObjectName('song_comments_label') self.song_info_form_layout.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.song_comments_label) self.song_comments_content = QtWidgets.QLabel(self) self.song_comments_content.setObjectName('song_comments_content') self.song_comments_content.setText(self.song.comments) self.song_comments_content.setWordWrap(True) self.song_info_form_layout.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.song_comments_content) # Add authors widget. self.song_authors_label = QtWidgets.QLabel(self) self.song_authors_label.setObjectName('song_authors_label') self.song_info_form_layout.setWidget(5, QtWidgets.QFormLayout.LabelRole, self.song_authors_label) self.song_authors_content = QtWidgets.QLabel(self) self.song_authors_content.setObjectName('song_authors_content') self.song_authors_content.setWordWrap(True) authors_text = ', '.join( [author.display_name for author in self.song.authors]) self.song_authors_content.setText(authors_text) self.song_info_form_layout.setWidget(5, QtWidgets.QFormLayout.FieldRole, self.song_authors_content) # Add verse order widget. self.song_verse_order_label = QtWidgets.QLabel(self) self.song_verse_order_label.setObjectName('song_verse_order_label') self.song_info_form_layout.setWidget(6, QtWidgets.QFormLayout.LabelRole, self.song_verse_order_label) self.song_verse_order_content = QtWidgets.QLabel(self) self.song_verse_order_content.setObjectName('song_verse_order_content') self.song_verse_order_content.setText(self.song.verse_order) self.song_verse_order_content.setWordWrap(True) self.song_info_form_layout.setWidget(6, QtWidgets.QFormLayout.FieldRole, self.song_verse_order_content) self.song_group_box_layout.addLayout(self.song_info_form_layout) # Add verses widget. self.song_info_verse_list_widget = QtWidgets.QTableWidget( self.song_group_box) self.song_info_verse_list_widget.setColumnCount(1) self.song_info_verse_list_widget.horizontalHeader().setVisible(False) self.song_info_verse_list_widget.setObjectName( 'song_info_verse_list_widget') self.song_info_verse_list_widget.setSelectionMode( QtWidgets.QAbstractItemView.NoSelection) self.song_info_verse_list_widget.setEditTriggers( QtWidgets.QAbstractItemView.NoEditTriggers) self.song_info_verse_list_widget.setHorizontalScrollBarPolicy( QtCore.Qt.ScrollBarAlwaysOff) self.song_info_verse_list_widget.setVerticalScrollBarPolicy( QtCore.Qt.ScrollBarAlwaysOff) self.song_info_verse_list_widget.setAlternatingRowColors(True) song_xml = SongXML() verses = song_xml.get_verses(self.song.lyrics) self.song_info_verse_list_widget.setRowCount(len(verses)) song_tags = [] for verse_number, verse in enumerate(verses): item = QtWidgets.QTableWidgetItem() item.setText(verse[1]) self.song_info_verse_list_widget.setItem(verse_number, 0, item) # 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() song_tags.append(str(verse_tag + verse[0]['label'])) self.song_info_verse_list_widget.setVerticalHeaderLabels(song_tags) # Resize table fields to content and table to columns self.song_info_verse_list_widget.setColumnWidth( 0, self.song_group_box.width()) self.song_info_verse_list_widget.resizeRowsToContents() # The 6 is a trial and error value since verticalHeader().length() + offset() is a little bit to small. # It seems there is no clean way to determine the real height of the table contents. # The "correct" value slightly fluctuates depending on the theme used, in the worst case # Some pixels are missing at the bottom of the table, but all themes I tried still allowed # to read the last verse line, so I'll just leave it at that. self.song_info_verse_list_widget.setFixedHeight( self.song_info_verse_list_widget.verticalHeader().length() + self.song_info_verse_list_widget.verticalHeader().offset() + 6) self.song_group_box_layout.addWidget(self.song_info_verse_list_widget) self.song_group_box_layout.addStretch() self.song_vertical_layout.addWidget(self.song_group_box) self.song_remove_button = QtWidgets.QPushButton(self) self.song_remove_button.setObjectName('song_remove_button') self.song_remove_button.setIcon(build_icon(':/songs/song_delete.png')) self.song_remove_button.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) self.song_vertical_layout.addWidget(self.song_remove_button, alignment=QtCore.Qt.AlignHCenter)
def _process_lyrics(self, foilpresenterfolie, song): """ Processes the verses and search_lyrics for the song. :param foilpresenterfolie: The foilpresenterfolie object (lxml.objectify.ObjectifiedElement). :param song: The song object. """ sxml = SongXML() temp_verse_order = {} temp_verse_order_backup = [] temp_sortnr_backup = 1 temp_sortnr_liste = [] verse_count = { VerseType.tags[VerseType.Verse]: 1, VerseType.tags[VerseType.Chorus]: 1, VerseType.tags[VerseType.Bridge]: 1, VerseType.tags[VerseType.Ending]: 1, VerseType.tags[VerseType.Other]: 1, VerseType.tags[VerseType.Intro]: 1, VerseType.tags[VerseType.PreChorus]: 1 } if not hasattr(foilpresenterfolie.strophen, 'strophe'): self.importer.log_error( to_str(foilpresenterfolie.titel), str( translate( 'SongsPlugin.FoilPresenterSongImport', 'Invalid Foilpresenter song file. No verses found.'))) self.save_song = False return for strophe in foilpresenterfolie.strophen.strophe: text = to_str(strophe.text_) if hasattr(strophe, 'text_') else '' verse_name = to_str(strophe.key) children = strophe.getchildren() sortnr = False for child in children: if child.tag == 'sortnr': verse_sortnr = to_str(strophe.sortnr) sortnr = True # In older Version there is no sortnr, but we need one if not sortnr: verse_sortnr = str(temp_sortnr_backup) temp_sortnr_backup += 1 # Foilpresenter allows e. g. "Ref" or "1", but we need "C1" or "V1". temp_sortnr_liste.append(verse_sortnr) temp_verse_name = re.compile('[0-9].*').sub('', verse_name) temp_verse_name = temp_verse_name[:3].lower() if temp_verse_name == 'ref': verse_type = VerseType.tags[VerseType.Chorus] elif temp_verse_name == 'r': verse_type = VerseType.tags[VerseType.Chorus] elif temp_verse_name == '': verse_type = VerseType.tags[VerseType.Verse] elif temp_verse_name == 'v': verse_type = VerseType.tags[VerseType.Verse] elif temp_verse_name == 'bri': verse_type = VerseType.tags[VerseType.Bridge] elif temp_verse_name == 'cod': verse_type = VerseType.tags[VerseType.Ending] elif temp_verse_name == 'sch': verse_type = VerseType.tags[VerseType.Ending] elif temp_verse_name == 'pre': verse_type = VerseType.tags[VerseType.PreChorus] elif temp_verse_name == 'int': verse_type = VerseType.tags[VerseType.Intro] else: verse_type = VerseType.tags[VerseType.Other] verse_number = re.compile('[a-zA-Z.+-_ ]*').sub('', verse_name) # Foilpresenter allows e. g. "C", but we need "C1". if not verse_number: verse_number = str(verse_count[verse_type]) verse_count[verse_type] += 1 else: # test if foilpresenter have the same versenumber two times with # different parts raise the verse number for value in temp_verse_order_backup: if value == ''.join((verse_type, verse_number)): verse_number = str(int(verse_number) + 1) verse_type_index = VerseType.from_tag(verse_type[0]) verse_type = VerseType.tags[verse_type_index] temp_verse_order[verse_sortnr] = ''.join( (verse_type[0], verse_number)) temp_verse_order_backup.append(''.join( (verse_type[0], verse_number))) sxml.add_verse_to_lyrics(verse_type, verse_number, text) song.lyrics = str(sxml.extract_xml(), 'utf-8') # Process verse order verse_order = [] verse_strophenr = [] try: for strophennummer in foilpresenterfolie.reihenfolge.strophennummer: verse_strophenr.append(strophennummer) except AttributeError: pass # Currently we do not support different "parts"! if '0' in temp_verse_order: for vers in temp_verse_order_backup: verse_order.append(vers) else: for number in verse_strophenr: numberx = temp_sortnr_liste[int(number)] verse_order.append(temp_verse_order[str(numberx)]) song.verse_order = ' '.join(verse_order)
def setupUi(self): self.song_vertical_layout = QtGui.QVBoxLayout(self) self.song_vertical_layout.setObjectName('song_vertical_layout') self.song_group_box = QtGui.QGroupBox(self) self.song_group_box.setObjectName('song_group_box') self.song_group_box.setFixedWidth(300) self.song_group_box_layout = QtGui.QVBoxLayout(self.song_group_box) self.song_group_box_layout.setObjectName('song_group_box_layout') self.song_info_form_layout = QtGui.QFormLayout() self.song_info_form_layout.setObjectName('song_info_form_layout') # Add title widget. self.song_title_label = QtGui.QLabel(self) self.song_title_label.setObjectName('song_title_label') self.song_info_form_layout.setWidget(0, QtGui.QFormLayout.LabelRole, self.song_title_label) self.song_title_content = QtGui.QLabel(self) self.song_title_content.setObjectName('song_title_content') self.song_title_content.setText(self.song.title) self.song_title_content.setWordWrap(True) self.song_info_form_layout.setWidget(0, QtGui.QFormLayout.FieldRole, self.song_title_content) # Add alternate title widget. self.song_alternate_title_label = QtGui.QLabel(self) self.song_alternate_title_label.setObjectName('song_alternate_title_label') self.song_info_form_layout.setWidget(1, QtGui.QFormLayout.LabelRole, self.song_alternate_title_label) self.song_alternate_title_content = QtGui.QLabel(self) self.song_alternate_title_content.setObjectName('song_alternate_title_content') self.song_alternate_title_content.setText(self.song.alternate_title) self.song_alternate_title_content.setWordWrap(True) self.song_info_form_layout.setWidget(1, QtGui.QFormLayout.FieldRole, self.song_alternate_title_content) # Add CCLI number widget. self.song_ccli_number_label = QtGui.QLabel(self) self.song_ccli_number_label.setObjectName('song_ccli_number_label') self.song_info_form_layout.setWidget(2, QtGui.QFormLayout.LabelRole, self.song_ccli_number_label) self.song_ccli_number_content = QtGui.QLabel(self) self.song_ccli_number_content.setObjectName('song_ccli_number_content') self.song_ccli_number_content.setText(self.song.ccli_number) self.song_ccli_number_content.setWordWrap(True) self.song_info_form_layout.setWidget(2, QtGui.QFormLayout.FieldRole, self.song_ccli_number_content) # Add copyright widget. self.song_copyright_label = QtGui.QLabel(self) self.song_copyright_label.setObjectName('song_copyright_label') self.song_info_form_layout.setWidget(3, QtGui.QFormLayout.LabelRole, self.song_copyright_label) self.song_copyright_content = QtGui.QLabel(self) self.song_copyright_content.setObjectName('song_copyright_content') self.song_copyright_content.setWordWrap(True) self.song_copyright_content.setText(self.song.copyright) self.song_info_form_layout.setWidget(3, QtGui.QFormLayout.FieldRole, self.song_copyright_content) # Add comments widget. self.song_comments_label = QtGui.QLabel(self) self.song_comments_label.setObjectName('song_comments_label') self.song_info_form_layout.setWidget(4, QtGui.QFormLayout.LabelRole, self.song_comments_label) self.song_comments_content = QtGui.QLabel(self) self.song_comments_content.setObjectName('song_comments_content') self.song_comments_content.setText(self.song.comments) self.song_comments_content.setWordWrap(True) self.song_info_form_layout.setWidget(4, QtGui.QFormLayout.FieldRole, self.song_comments_content) # Add authors widget. self.song_authors_label = QtGui.QLabel(self) self.song_authors_label.setObjectName('song_authors_label') self.song_info_form_layout.setWidget(5, QtGui.QFormLayout.LabelRole, self.song_authors_label) self.song_authors_content = QtGui.QLabel(self) self.song_authors_content.setObjectName('song_authors_content') self.song_authors_content.setWordWrap(True) authors_text = ', '.join([author.display_name for author in self.song.authors]) self.song_authors_content.setText(authors_text) self.song_info_form_layout.setWidget(5, QtGui.QFormLayout.FieldRole, self.song_authors_content) # Add verse order widget. self.song_verse_order_label = QtGui.QLabel(self) self.song_verse_order_label.setObjectName('song_verse_order_label') self.song_info_form_layout.setWidget(6, QtGui.QFormLayout.LabelRole, self.song_verse_order_label) self.song_verse_order_content = QtGui.QLabel(self) self.song_verse_order_content.setObjectName('song_verse_order_content') self.song_verse_order_content.setText(self.song.verse_order) self.song_verse_order_content.setWordWrap(True) self.song_info_form_layout.setWidget(6, QtGui.QFormLayout.FieldRole, self.song_verse_order_content) self.song_group_box_layout.addLayout(self.song_info_form_layout) # Add verses widget. self.song_info_verse_list_widget = QtGui.QTableWidget(self.song_group_box) self.song_info_verse_list_widget.setColumnCount(1) self.song_info_verse_list_widget.horizontalHeader().setVisible(False) self.song_info_verse_list_widget.setObjectName('song_info_verse_list_widget') self.song_info_verse_list_widget.setSelectionMode(QtGui.QAbstractItemView.NoSelection) self.song_info_verse_list_widget.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers) self.song_info_verse_list_widget.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) self.song_info_verse_list_widget.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) self.song_info_verse_list_widget.setAlternatingRowColors(True) song_xml = SongXML() verses = song_xml.get_verses(self.song.lyrics) self.song_info_verse_list_widget.setRowCount(len(verses)) song_tags = [] for verse_number, verse in enumerate(verses): item = QtGui.QTableWidgetItem() item.setText(verse[1]) self.song_info_verse_list_widget.setItem(verse_number, 0, item) # 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() song_tags.append(str(verse_tag + verse[0]['label'])) self.song_info_verse_list_widget.setVerticalHeaderLabels(song_tags) # Resize table fields to content and table to columns self.song_info_verse_list_widget.setColumnWidth(0, self.song_group_box.width()) self.song_info_verse_list_widget.resizeRowsToContents() # The 6 is a trial and error value since verticalHeader().length() + offset() is a little bit to small. # It seems there is no clean way to determine the real height of the table contents. # The "correct" value slightly fluctuates depending on the theme used, in the worst case # Some pixels are missing at the bottom of the table, but all themes I tried still allowed # to read the last verse line, so I'll just leave it at that. self.song_info_verse_list_widget.setFixedHeight(self.song_info_verse_list_widget.verticalHeader().length() + self.song_info_verse_list_widget.verticalHeader().offset() + 6) self.song_group_box_layout.addWidget(self.song_info_verse_list_widget) self.song_group_box_layout.addStretch() self.song_vertical_layout.addWidget(self.song_group_box) self.song_remove_button = QtGui.QPushButton(self) self.song_remove_button.setObjectName('song_remove_button') self.song_remove_button.setIcon(build_icon(':/songs/song_delete.png')) self.song_remove_button.setSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed) self.song_vertical_layout.addWidget(self.song_remove_button, alignment=QtCore.Qt.AlignHCenter)
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
def _process_lyrics(self, foilpresenterfolie, song): """ Processes the verses and search_lyrics for the song. :param foilpresenterfolie: The foilpresenterfolie object (lxml.objectify.ObjectifiedElement). :param song: The song object. """ sxml = SongXML() temp_verse_order = {} temp_verse_order_backup = [] temp_sortnr_backup = 1 temp_sortnr_liste = [] verse_count = { VerseType.tags[VerseType.Verse]: 1, VerseType.tags[VerseType.Chorus]: 1, VerseType.tags[VerseType.Bridge]: 1, VerseType.tags[VerseType.Ending]: 1, VerseType.tags[VerseType.Other]: 1, VerseType.tags[VerseType.Intro]: 1, VerseType.tags[VerseType.PreChorus]: 1 } if not hasattr(foilpresenterfolie.strophen, 'strophe'): self.importer.log_error(self._child(foilpresenterfolie.titel), str(translate('SongsPlugin.FoilPresenterSongImport', 'Invalid Foilpresenter song file. No verses found.'))) self.save_song = False return for strophe in foilpresenterfolie.strophen.strophe: text = self._child(strophe.text_) if hasattr(strophe, 'text_') else '' verse_name = self._child(strophe.key) children = strophe.getchildren() sortnr = False for child in children: if child.tag == 'sortnr': verse_sortnr = self._child(strophe.sortnr) sortnr = True # In older Version there is no sortnr, but we need one if not sortnr: verse_sortnr = str(temp_sortnr_backup) temp_sortnr_backup += 1 # Foilpresenter allows e. g. "Ref" or "1", but we need "C1" or "V1". temp_sortnr_liste.append(verse_sortnr) temp_verse_name = re.compile('[0-9].*').sub('', verse_name) temp_verse_name = temp_verse_name[:3].lower() if temp_verse_name == 'ref': verse_type = VerseType.tags[VerseType.Chorus] elif temp_verse_name == 'r': verse_type = VerseType.tags[VerseType.Chorus] elif temp_verse_name == '': verse_type = VerseType.tags[VerseType.Verse] elif temp_verse_name == 'v': verse_type = VerseType.tags[VerseType.Verse] elif temp_verse_name == 'bri': verse_type = VerseType.tags[VerseType.Bridge] elif temp_verse_name == 'cod': verse_type = VerseType.tags[VerseType.Ending] elif temp_verse_name == 'sch': verse_type = VerseType.tags[VerseType.Ending] elif temp_verse_name == 'pre': verse_type = VerseType.tags[VerseType.PreChorus] elif temp_verse_name == 'int': verse_type = VerseType.tags[VerseType.Intro] else: verse_type = VerseType.tags[VerseType.Other] verse_number = re.compile('[a-zA-Z.+-_ ]*').sub('', verse_name) # Foilpresenter allows e. g. "C", but we need "C1". if not verse_number: verse_number = str(verse_count[verse_type]) verse_count[verse_type] += 1 else: # test if foilpresenter have the same versenumber two times with # different parts raise the verse number for value in temp_verse_order_backup: if value == ''.join((verse_type, verse_number)): verse_number = str(int(verse_number) + 1) verse_type_index = VerseType.from_tag(verse_type[0]) verse_type = VerseType.tags[verse_type_index] temp_verse_order[verse_sortnr] = ''.join((verse_type[0], verse_number)) temp_verse_order_backup.append(''.join((verse_type[0], verse_number))) sxml.add_verse_to_lyrics(verse_type, verse_number, text) song.lyrics = str(sxml.extract_xml(), 'utf-8') # Process verse order verse_order = [] verse_strophenr = [] try: for strophennummer in foilpresenterfolie.reihenfolge.strophennummer: verse_strophenr.append(strophennummer) except AttributeError: pass # Currently we do not support different "parts"! if '0' in temp_verse_order: for vers in temp_verse_order_backup: verse_order.append(vers) else: for number in verse_strophenr: numberx = temp_sortnr_liste[int(number)] verse_order.append(temp_verse_order[str(numberx)]) song.verse_order = ' '.join(verse_order)
def finish(self): """ All fields have been set to this song. Write the song to disk. """ if not self.check_complete(): self.set_defaults() return False log.info( 'committing song {title} to database'.format(title=self.title)) song = Song() song.title = self.title if self.import_wizard is not None: # TODO: Verify format() with template variables self.import_wizard.increment_progress_bar( WizardStrings.ImportingType % song.title) song.alternate_title = self.alternate_title # Values will be set when cleaning the song. song.search_title = '' song.search_lyrics = '' song.verse_order = '' song.song_number = self.song_number verses_changed_to_other = {} sxml = SongXML() other_count = 1 for (verse_def, verse_text, lang) in self.verses: if verse_def[0].lower() in VerseType.tags: verse_tag = verse_def[0].lower() else: new_verse_def = '{tag}{count:d}'.format( tag=VerseType.tags[VerseType.Other], count=other_count) verses_changed_to_other[verse_def] = new_verse_def other_count += 1 verse_tag = VerseType.tags[VerseType.Other] log.info('Versetype {old} changing to {new}'.format( old=verse_def, new=new_verse_def)) verse_def = new_verse_def sxml.add_verse_to_lyrics(verse_tag, verse_def[1:], verse_text, lang) song.lyrics = str(sxml.extract_xml(), 'utf-8') if not self.verse_order_list and self.verse_order_list_generated_useful: self.verse_order_list = self.verse_order_list_generated self.verse_order_list = [ verses_changed_to_other.get(v, v) for v in self.verse_order_list ] song.verse_order = ' '.join(self.verse_order_list) song.copyright = self.copyright song.comments = self.comments song.theme_name = self.theme_name song.ccli_number = self.ccli_number for author_text, author_type in self.authors: author = self.manager.get_object_filtered( Author, Author.display_name == author_text) if not author: author = Author.populate(display_name=author_text, last_name=author_text.split(' ')[-1], first_name=' '.join( author_text.split(' ')[:-1])) song.add_author(author, author_type) if self.song_book_name: song_book = self.manager.get_object_filtered( Book, Book.name == self.song_book_name) if song_book is None: song_book = Book.populate(name=self.song_book_name, publisher=self.song_book_pub) song.add_songbook_entry(song_book, song.song_number) for topic_text in self.topics: if not topic_text: continue topic = self.manager.get_object_filtered(Topic, Topic.name == topic_text) if topic is None: topic = Topic.populate(name=topic_text) song.topics.append(topic) # We need to save the song now, before adding the media files, so that # we know where to save the media files to. clean_song(self.manager, song) self.manager.save_object(song) # Now loop through the media files, copy them to the correct location, # and save the song again. for filename, weight in self.media_files: media_file = self.manager.get_object_filtered( MediaFile, MediaFile.file_name == filename) if not media_file: if os.path.dirname(filename): filename = self.copy_media_file(song.id, filename) song.media_files.append( MediaFile.populate(file_name=filename, weight=weight)) self.manager.save_object(song) self.set_defaults() return True
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
def finish(self): """ All fields have been set to this song. Write the song to disk. """ if not self.check_complete(): self.set_defaults() return False log.info('committing song %s to database', self.title) song = Song() song.title = self.title if self.import_wizard is not None: self.import_wizard.increment_progress_bar(WizardStrings.ImportingType % song.title) song.alternate_title = self.alternate_title # Values will be set when cleaning the song. song.search_title = '' song.search_lyrics = '' song.verse_order = '' song.song_number = self.song_number verses_changed_to_other = {} sxml = SongXML() other_count = 1 for (verse_def, verse_text, lang) in self.verses: if verse_def[0].lower() in VerseType.tags: verse_tag = verse_def[0].lower() else: new_verse_def = '%s%d' % (VerseType.tags[VerseType.Other], other_count) verses_changed_to_other[verse_def] = new_verse_def other_count += 1 verse_tag = VerseType.tags[VerseType.Other] log.info('Versetype %s changing to %s', verse_def, new_verse_def) verse_def = new_verse_def sxml.add_verse_to_lyrics(verse_tag, verse_def[1:], verse_text, lang) song.lyrics = str(sxml.extract_xml(), 'utf-8') if not self.verse_order_list and self.verse_order_list_generated_useful: self.verse_order_list = self.verse_order_list_generated self.verse_order_list = [verses_changed_to_other.get(v, v) for v in self.verse_order_list] song.verse_order = ' '.join(self.verse_order_list) song.copyright = self.copyright song.comments = self.comments song.theme_name = self.theme_name song.ccli_number = self.ccli_number for author_text in self.authors: author = self.manager.get_object_filtered(Author, Author.display_name == author_text) if not author: author = Author.populate(display_name=author_text, last_name=author_text.split(' ')[-1], first_name=' '.join(author_text.split(' ')[:-1])) song.add_author(author) if self.song_book_name: song_book = self.manager.get_object_filtered(Book, Book.name == self.song_book_name) if song_book is None: song_book = Book.populate(name=self.song_book_name, publisher=self.song_book_pub) song.book = song_book for topic_text in self.topics: if not topic_text: continue topic = self.manager.get_object_filtered(Topic, Topic.name == topic_text) if topic is None: topic = Topic.populate(name=topic_text) song.topics.append(topic) # We need to save the song now, before adding the media files, so that # we know where to save the media files to. clean_song(self.manager, song) self.manager.save_object(song) # Now loop through the media files, copy them to the correct location, # and save the song again. for filename, weight in self.media_files: media_file = self.manager.get_object_filtered(MediaFile, MediaFile.file_name == filename) if not media_file: if os.path.dirname(filename): filename = self.copy_media_file(song.id, filename) song.media_files.append(MediaFile.populate(file_name=filename, weight=weight)) self.manager.save_object(song) self.set_defaults() return True