def _process_songbooks(self, foilpresenterfolie, song): """ Adds the song book and song number specified in the XML to the song. :param foilpresenterfolie: The property object (lxml.objectify.ObjectifiedElement). :param song: The song object. """ song.song_book_id = 0 song.song_number = '' try: for bucheintrag in foilpresenterfolie.buch.bucheintrag: book_name = to_str(bucheintrag.name) if book_name: book = self.manager.get_object_filtered( Book, Book.name == book_name) if book is None: # We need to create a book, because it does not exist. book = Book.populate(name=book_name, publisher='') self.manager.save_object(book) song.song_book_id = book.id try: if to_str(bucheintrag.nummer): song.song_number = to_str(bucheintrag.nummer) except AttributeError: pass # We only support one song book, so take the first one. break except AttributeError: pass
def _process_songbooks(self, properties, song): """ Adds the song book and song number specified in the XML to the song. ``properties`` The property object (lxml.objectify.ObjectifiedElement). ``song`` The song object. """ song.song_book_id = None song.song_number = u'' if hasattr(properties, u'songbooks'): for songbook in properties.songbooks.songbook: book_name = songbook.get(u'name', u'') if book_name: book = self.manager.get_object_filtered(Book, Book.name == book_name) if book is None: # We need to create a book, because it does not exist. book = Book.populate(name=book_name, publisher=u'') self.manager.save_object(book) song.song_book_id = book.id song.song_number = songbook.get(u'entry', u'') # We only support one song book, so take the first one. break
def test_add_songbooks(self): """ Test that adding songbooks to a song works correctly """ # GIVEN: A mocked song and songbook song = Song() song.songbook_entries = [] songbook = Book() songbook.name = "Thy Word" # WHEN: We add two songbooks to a Song song.add_songbook_entry(songbook, "120") song.add_songbook_entry(songbook, "550A") # THEN: The song should have two songbook entries self.assertEqual(len(song.songbook_entries), 2, 'There should be two Songbook entries.')
def _process_songbooks(self, foilpresenterfolie, song): """ Adds the song book and song number specified in the XML to the song. :param foilpresenterfolie: The property object (lxml.objectify.ObjectifiedElement). :param song: The song object. """ song.song_book_id = 0 song.song_number = '' try: for bucheintrag in foilpresenterfolie.buch.bucheintrag: book_name = self._child(bucheintrag.name) if book_name: book = self.manager.get_object_filtered(Book, Book.name == book_name) if book is None: # We need to create a book, because it does not exist. book = Book.populate(name=book_name, publisher='') self.manager.save_object(book) song.song_book_id = book.id try: if self._child(bucheintrag.nummer): song.song_number = self._child(bucheintrag.nummer) except AttributeError: pass # We only support one song book, so take the first one. break except AttributeError: pass
def on_add_book_button_clicked(self): """ Add a book to the list. """ if self.song_book_form.exec_(): book = Book.populate(name=self.song_book_form.name_edit.text(), publisher=self.song_book_form.publisher_edit.text()) if self.check_song_book_exists(book): if self.manager.save_object(book): self.reset_song_books() else: critical_error_message_box( message=translate('SongsPlugin.SongMaintenanceForm', 'Could not add your book.')) else: critical_error_message_box( message=translate('SongsPlugin.SongMaintenanceForm', 'This book already exists.'))
def on_add_book_button_clicked(self): """ Add a book to the list. """ if self.song_book_form.exec(): book = Book.populate(name=self.song_book_form.name_edit.text(), publisher=self.song_book_form.publisher_edit.text()) if self.check_song_book_exists(book): if self.manager.save_object(book): self.reset_song_books() else: critical_error_message_box( message=translate('SongsPlugin.SongMaintenanceForm', 'Could not add your book.')) else: critical_error_message_box( message=translate('SongsPlugin.SongMaintenanceForm', 'This book already exists.'))
def _process_songbooks(self, properties, song): """ Adds the song book and song number specified in the XML to the song. :param properties: The property object (lxml.objectify.ObjectifiedElement). :param song: The song object. """ if hasattr(properties, 'songbooks'): for songbook in properties.songbooks.songbook: book_name = songbook.get('name', '') if book_name: book = self.manager.get_object_filtered(Book, Book.name == book_name) if book is None: # We need to create a book, because it does not exist. book = Book.populate(name=book_name, publisher='') self.manager.save_object(book) song.add_songbook_entry(book, songbook.get('entry', ''))
def _validate_song(self): """ Check the validity of the song. """ # This checks data in the form *not* self.song. self.song is still # None at this point. log.debug('Validate Song') # Lets be nice and assume the data is correct. if not self.title_edit.text(): self.song_tab_widget.setCurrentIndex(0) self.title_edit.setFocus() critical_error_message_box( message=translate('SongsPlugin.EditSongForm', 'You need to type in a song title.')) return False if self.verse_list_widget.rowCount() == 0: self.song_tab_widget.setCurrentIndex(0) self.verse_list_widget.setFocus() critical_error_message_box( message=translate('SongsPlugin.EditSongForm', 'You need to type in at least one verse.')) return False if self.authors_list_view.count() == 0: self.song_tab_widget.setCurrentIndex(1) self.authors_list_view.setFocus() critical_error_message_box( message=translate('SongsPlugin.EditSongForm', 'You need to have an author for this song.')) return False if self.verse_order_edit.text(): result = self._validate_verse_list(self.verse_order_edit.text(), self.verse_list_widget.rowCount()) if not result: return False text = self.song_book_combo_box.currentText() if self.song_book_combo_box.findText(text, QtCore.Qt.MatchExactly) < 0: if QtGui.QMessageBox.question(self, translate('SongsPlugin.EditSongForm', 'Add Book'), translate('SongsPlugin.EditSongForm', 'This song book does not exist, do you want to add it?'), QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.Yes) == QtGui.QMessageBox.Yes: book = Book.populate(name=text, publisher='') self.manager.save_object(book) else: return False return True
def do_import(self, progress_dialog=None): """ Run the import for an OpenLP version 2 song database. :param progress_dialog: The QProgressDialog used when importing songs from the FRW. """ class OldAuthor(BaseModel): """ Author model """ pass class OldBook(BaseModel): """ Book model """ pass class OldMediaFile(BaseModel): """ MediaFile model """ pass class OldSong(BaseModel): """ Song model """ pass class OldTopic(BaseModel): """ Topic model """ pass # Check the file type if not self.import_source.endswith('.sqlite'): self.log_error(self.import_source, translate('SongsPlugin.OpenLPSongImport', 'Not a valid OpenLP 2.0 song database.')) return self.import_source = 'sqlite:///%s' % self.import_source # Load the db file engine = create_engine(self.import_source) source_meta = MetaData() source_meta.reflect(engine) self.source_session = scoped_session(sessionmaker(bind=engine)) if 'media_files' in list(source_meta.tables.keys()): has_media_files = True else: has_media_files = False source_authors_table = source_meta.tables['authors'] source_song_books_table = source_meta.tables['song_books'] source_songs_table = source_meta.tables['songs'] source_topics_table = source_meta.tables['topics'] source_authors_songs_table = source_meta.tables['authors_songs'] source_songs_topics_table = source_meta.tables['songs_topics'] source_media_files_songs_table = None if has_media_files: source_media_files_table = source_meta.tables['media_files'] source_media_files_songs_table = source_meta.tables.get('media_files_songs') try: class_mapper(OldMediaFile) except UnmappedClassError: mapper(OldMediaFile, source_media_files_table) song_props = { 'authors': relation(OldAuthor, backref='songs', secondary=source_authors_songs_table), 'book': relation(OldBook, backref='songs'), 'topics': relation(OldTopic, backref='songs', secondary=source_songs_topics_table) } if has_media_files: if isinstance(source_media_files_songs_table, Table): song_props['media_files'] = relation(OldMediaFile, backref='songs', secondary=source_media_files_songs_table) else: song_props['media_files'] = \ relation(OldMediaFile, backref='songs', foreign_keys=[source_media_files_table.c.song_id], primaryjoin=source_songs_table.c.id == source_media_files_table.c.song_id) try: class_mapper(OldAuthor) except UnmappedClassError: mapper(OldAuthor, source_authors_table) try: class_mapper(OldBook) except UnmappedClassError: mapper(OldBook, source_song_books_table) try: class_mapper(OldSong) except UnmappedClassError: mapper(OldSong, source_songs_table, properties=song_props) try: class_mapper(OldTopic) except UnmappedClassError: mapper(OldTopic, source_topics_table) source_songs = self.source_session.query(OldSong).all() if self.import_wizard: self.import_wizard.progress_bar.setMaximum(len(source_songs)) for song in source_songs: new_song = Song() new_song.title = song.title if has_media_files and hasattr(song, 'alternate_title'): new_song.alternate_title = song.alternate_title else: old_titles = song.search_title.split('@') if len(old_titles) > 1: new_song.alternate_title = old_titles[1] # Values will be set when cleaning the song. if hasattr(song, 'song_key'): new_song.song_key = song.song_key if hasattr(song, 'transpose_by'): new_song.transpose_by = song.transpose_by new_song.search_title = '' new_song.search_lyrics = '' new_song.song_number = song.song_number new_song.lyrics = song.lyrics new_song.verse_order = song.verse_order new_song.copyright = song.copyright new_song.comments = song.comments new_song.theme_name = song.theme_name new_song.ccli_number = song.ccli_number for author in song.authors: existing_author = self.manager.get_object_filtered(Author, Author.display_name == author.display_name) if existing_author is None: existing_author = Author.populate( first_name=author.first_name, last_name=author.last_name, display_name=author.display_name) new_song.add_author(existing_author) if song.book: existing_song_book = self.manager.get_object_filtered(Book, Book.name == song.book.name) if existing_song_book is None: existing_song_book = Book.populate(name=song.book.name, publisher=song.book.publisher) new_song.book = existing_song_book if song.topics: for topic in song.topics: existing_topic = self.manager.get_object_filtered(Topic, Topic.name == topic.name) if existing_topic is None: existing_topic = Topic.populate(name=topic.name) new_song.topics.append(existing_topic) if has_media_files: if song.media_files: for media_file in song.media_files: existing_media_file = self.manager.get_object_filtered( MediaFile, MediaFile.file_name == media_file.file_name) if existing_media_file: new_song.media_files.append(existing_media_file) else: new_song.media_files.append(MediaFile.populate(file_name=media_file.file_name)) clean_song(self.manager, new_song) self.manager.save_object(new_song) if progress_dialog: progress_dialog.setValue(progress_dialog.value() + 1) progress_dialog.setLabelText(WizardStrings.ImportingType % new_song.title) else: self.import_wizard.increment_progress_bar(WizardStrings.ImportingType % new_song.title) if self.stop_import_flag: break self.source_session.close() engine.dispose()
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 do_import(self, progress_dialog=None): """ Run the import for an OpenLP version 2 song database. :param progress_dialog: The QProgressDialog used when importing songs from the FRW. """ class OldAuthor(BaseModel): """ Maps to the authors table """ pass class OldBook(BaseModel): """ Maps to the songbooks table """ pass class OldMediaFile(BaseModel): """ Maps to the media_files table """ pass class OldSong(BaseModel): """ Maps to the songs table """ pass class OldTopic(BaseModel): """ Maps to the topics table """ pass class OldSongBookEntry(BaseModel): """ Maps to the songs_songbooks table """ pass # Check the file type if not isinstance(self.import_source, str) or not self.import_source.endswith('.sqlite'): self.log_error(self.import_source, translate('SongsPlugin.OpenLPSongImport', 'Not a valid OpenLP 2 song database.')) return self.import_source = 'sqlite:///{url}'.format(url=self.import_source) # Load the db file and reflect it engine = create_engine(self.import_source) source_meta = MetaData() source_meta.reflect(engine) self.source_session = scoped_session(sessionmaker(bind=engine)) # Run some checks to see which version of the database we have if 'media_files' in list(source_meta.tables.keys()): has_media_files = True else: has_media_files = False if 'songs_songbooks' in list(source_meta.tables.keys()): has_songs_books = True else: has_songs_books = False # Load up the tabls and map them out source_authors_table = source_meta.tables['authors'] source_song_books_table = source_meta.tables['song_books'] source_songs_table = source_meta.tables['songs'] source_topics_table = source_meta.tables['topics'] source_authors_songs_table = source_meta.tables['authors_songs'] source_songs_topics_table = source_meta.tables['songs_topics'] source_media_files_songs_table = None # Set up media_files relations if has_media_files: source_media_files_table = source_meta.tables['media_files'] source_media_files_songs_table = source_meta.tables.get('media_files_songs') try: class_mapper(OldMediaFile) except UnmappedClassError: mapper(OldMediaFile, source_media_files_table) if has_songs_books: source_songs_songbooks_table = source_meta.tables['songs_songbooks'] try: class_mapper(OldSongBookEntry) except UnmappedClassError: mapper(OldSongBookEntry, source_songs_songbooks_table, properties={'songbook': relation(OldBook)}) # Set up the songs relationships song_props = { 'authors': relation(OldAuthor, backref='songs', secondary=source_authors_songs_table), 'topics': relation(OldTopic, backref='songs', secondary=source_songs_topics_table) } if has_media_files: if isinstance(source_media_files_songs_table, Table): song_props['media_files'] = relation(OldMediaFile, backref='songs', secondary=source_media_files_songs_table) else: song_props['media_files'] = \ relation(OldMediaFile, backref='songs', foreign_keys=[source_media_files_table.c.song_id], primaryjoin=source_songs_table.c.id == source_media_files_table.c.song_id) if has_songs_books: song_props['songbook_entries'] = relation(OldSongBookEntry, backref='song', cascade='all, delete-orphan') else: song_props['book'] = relation(OldBook, backref='songs') # Map the rest of the tables try: class_mapper(OldAuthor) except UnmappedClassError: mapper(OldAuthor, source_authors_table) try: class_mapper(OldBook) except UnmappedClassError: mapper(OldBook, source_song_books_table) try: class_mapper(OldSong) except UnmappedClassError: mapper(OldSong, source_songs_table, properties=song_props) try: class_mapper(OldTopic) except UnmappedClassError: mapper(OldTopic, source_topics_table) source_songs = self.source_session.query(OldSong).all() if self.import_wizard: self.import_wizard.progress_bar.setMaximum(len(source_songs)) for song in source_songs: new_song = Song() new_song.title = song.title if has_media_files and hasattr(song, 'alternate_title'): new_song.alternate_title = song.alternate_title else: old_titles = song.search_title.split('@') if len(old_titles) > 1: new_song.alternate_title = old_titles[1] # Transfer the values to the new song object new_song.search_title = '' new_song.search_lyrics = '' new_song.lyrics = song.lyrics new_song.verse_order = song.verse_order new_song.copyright = song.copyright new_song.comments = song.comments new_song.theme_name = song.theme_name new_song.ccli_number = song.ccli_number if hasattr(song, 'song_number') and song.song_number: new_song.song_number = song.song_number # Find or create all the authors and add them to the new song object for author in song.authors: existing_author = self.manager.get_object_filtered(Author, Author.display_name == author.display_name) if not existing_author: existing_author = Author.populate( first_name=author.first_name, last_name=author.last_name, display_name=author.display_name) new_song.add_author(existing_author) # Find or create all the topics and add them to the new song object if song.topics: for topic in song.topics: existing_topic = self.manager.get_object_filtered(Topic, Topic.name == topic.name) if not existing_topic: existing_topic = Topic.populate(name=topic.name) new_song.topics.append(existing_topic) # Find or create all the songbooks and add them to the new song object if has_songs_books and song.songbook_entries: for entry in song.songbook_entries: existing_book = self.manager.get_object_filtered(Book, Book.name == entry.songbook.name) if not existing_book: existing_book = Book.populate(name=entry.songbook.name, publisher=entry.songbook.publisher) new_song.add_songbook_entry(existing_book, entry.entry) elif song.book: existing_book = self.manager.get_object_filtered(Book, Book.name == song.book.name) if not existing_book: existing_book = Book.populate(name=song.book.name, publisher=song.book.publisher) new_song.add_songbook_entry(existing_book, '') # Find or create all the media files and add them to the new song object if has_media_files and song.media_files: for media_file in song.media_files: existing_media_file = self.manager.get_object_filtered( MediaFile, MediaFile.file_name == media_file.file_name) if existing_media_file: new_song.media_files.append(existing_media_file) else: new_song.media_files.append(MediaFile.populate(file_name=media_file.file_name)) clean_song(self.manager, new_song) self.manager.save_object(new_song) if progress_dialog: progress_dialog.setValue(progress_dialog.value() + 1) # TODO: Verify format() with template strings progress_dialog.setLabelText(WizardStrings.ImportingType % new_song.title) else: # TODO: Verify format() with template strings self.import_wizard.increment_progress_bar(WizardStrings.ImportingType % new_song.title) if self.stop_import_flag: break self.source_session.close() engine.dispose()
def finish(self): """ All fields have been set to this song. Write the song to disk. """ if not self.checkComplete(): self.setDefaults() 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.songNumber 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.verseOrderList and self.verseOrderListGeneratedUseful: self.verseOrderList = self.verseOrderListGenerated self.verseOrderList = [verses_changed_to_other.get(v, v) for v in self.verseOrderList] song.verse_order = ' '.join(self.verseOrderList) song.copyright = self.copyright song.comments = self.comments song.theme_name = self.themeName song.ccli_number = self.ccliNumber for authortext in self.authors: author = self.manager.get_object_filtered(Author, Author.display_name == authortext) if not author: author = Author.populate(display_name=authortext, last_name=authortext.split(' ')[-1], first_name=' '.join(authortext.split(' ')[:-1])) song.authors.append(author) if self.songBookName: song_book = self.manager.get_object_filtered(Book, Book.name == self.songBookName) if song_book is None: song_book = Book.populate(name=self.songBookName, publisher=self.songBookPub) song.book = song_book for topictext in self.topics: if not topictext: continue topic = self.manager.get_object_filtered(Topic, Topic.name == topictext) if topic is None: topic = Topic.populate(name=topictext) 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.mediaFiles: media_file = self.manager.get_object_filtered(MediaFile, MediaFile.file_name == filename) if not media_file: if os.path.dirname(filename): filename = self.copyMediaFile(song.id, filename) song.media_files.append(MediaFile.populate(file_name=filename, weight=weight)) self.manager.save_object(song) self.setDefaults() return True
def do_import(self, progress_dialog=None): """ Run the import for an OpenLP version 2 song database. :param progress_dialog: The QProgressDialog used when importing songs from the FRW. """ class OldAuthorSong(BaseModel): """ Maps to the authors_songs table """ pass class OldAuthor(BaseModel): """ Maps to the authors table """ pass class OldBook(BaseModel): """ Maps to the songbooks table """ pass class OldMediaFile(BaseModel): """ Maps to the media_files table """ pass class OldSong(BaseModel): """ Maps to the songs table """ pass class OldTopic(BaseModel): """ Maps to the topics table """ pass class OldSongBookEntry(BaseModel): """ Maps to the songs_songbooks table """ pass # Check the file type if self.import_source.suffix != '.sqlite': self.log_error( self.import_source, translate('SongsPlugin.OpenLPSongImport', 'Not a valid OpenLP 2 song database.')) return self.import_source = 'sqlite:///{url}'.format(url=self.import_source) # Load the db file and reflect it engine = create_engine(self.import_source) source_meta = MetaData() source_meta.reflect(engine) self.source_session = scoped_session(sessionmaker(bind=engine)) # Run some checks to see which version of the database we have table_list = list(source_meta.tables.keys()) if 'media_files' in table_list: has_media_files = True else: has_media_files = False if 'songs_songbooks' in table_list: has_songs_books = True else: has_songs_books = False if 'authors_songs' in table_list: has_authors_songs = True else: has_authors_songs = False # Load up the tabls and map them out try: source_authors_table = source_meta.tables['authors'] source_song_books_table = source_meta.tables['song_books'] source_songs_table = source_meta.tables['songs'] source_topics_table = source_meta.tables['topics'] source_authors_songs_table = source_meta.tables['authors_songs'] source_songs_topics_table = source_meta.tables['songs_topics'] source_media_files_songs_table = None except KeyError: self.log_error( self.import_source, translate('SongsPlugin.OpenLPSongImport', 'Not a valid OpenLP 2 song database.')) return # Set up media_files relations if has_media_files: source_media_files_table = source_meta.tables['media_files'] source_media_files_songs_table = source_meta.tables.get( 'media_files_songs') try: class_mapper(OldMediaFile) except UnmappedClassError: mapper(OldMediaFile, source_media_files_table) if has_songs_books: source_songs_songbooks_table = source_meta.tables[ 'songs_songbooks'] try: class_mapper(OldSongBookEntry) except UnmappedClassError: mapper(OldSongBookEntry, source_songs_songbooks_table, properties={'songbook': relation(OldBook)}) if has_authors_songs: try: class_mapper(OldAuthorSong) except UnmappedClassError: mapper(OldAuthorSong, source_authors_songs_table) if has_authors_songs and 'author_type' in source_authors_songs_table.c.keys( ): has_author_type = True else: has_author_type = False # Set up the songs relationships song_props = { 'authors': relation(OldAuthor, backref='songs', secondary=source_authors_songs_table), 'topics': relation(OldTopic, backref='songs', secondary=source_songs_topics_table) } if has_media_files: if isinstance(source_media_files_songs_table, Table): song_props['media_files'] = relation( OldMediaFile, backref='songs', secondary=source_media_files_songs_table) else: song_props['media_files'] = \ relation(OldMediaFile, backref='songs', foreign_keys=[source_media_files_table.c.song_id], primaryjoin=source_songs_table.c.id == source_media_files_table.c.song_id) if has_songs_books: song_props['songbook_entries'] = relation( OldSongBookEntry, backref='song', cascade='all, delete-orphan') else: song_props['book'] = relation(OldBook, backref='songs') if has_authors_songs: song_props['authors_songs'] = relation(OldAuthorSong) # Map the rest of the tables try: class_mapper(OldAuthor) except UnmappedClassError: mapper(OldAuthor, source_authors_table) try: class_mapper(OldBook) except UnmappedClassError: mapper(OldBook, source_song_books_table) try: class_mapper(OldSong) except UnmappedClassError: mapper(OldSong, source_songs_table, properties=song_props) try: class_mapper(OldTopic) except UnmappedClassError: mapper(OldTopic, source_topics_table) source_songs = self.source_session.query(OldSong).all() if self.import_wizard: self.import_wizard.progress_bar.setMaximum(len(source_songs)) for song in source_songs: new_song = Song() new_song.title = song.title if has_media_files and hasattr(song, 'alternate_title'): new_song.alternate_title = song.alternate_title else: old_titles = song.search_title.split('@') if len(old_titles) > 1: new_song.alternate_title = old_titles[1] # Transfer the values to the new song object new_song.search_title = '' new_song.search_lyrics = '' new_song.lyrics = song.lyrics new_song.verse_order = song.verse_order new_song.copyright = song.copyright new_song.comments = song.comments new_song.theme_name = song.theme_name new_song.ccli_number = song.ccli_number if hasattr(song, 'song_number') and song.song_number: new_song.song_number = song.song_number # Find or create all the authors and add them to the new song object for author in song.authors: existing_author = self.manager.get_object_filtered( Author, Author.display_name == author.display_name) if not existing_author: existing_author = Author.populate( first_name=author.first_name, last_name=author.last_name, display_name=author.display_name) # If this is a new database, we need to import the author_type too author_type = None if has_author_type: for author_song in song.authors_songs: if author_song.author_id == author.id: author_type = author_song.author_type break new_song.add_author(existing_author, author_type) # Find or create all the topics and add them to the new song object if song.topics: for topic in song.topics: existing_topic = self.manager.get_object_filtered( Topic, Topic.name == topic.name) if not existing_topic: existing_topic = Topic.populate(name=topic.name) new_song.topics.append(existing_topic) # Find or create all the songbooks and add them to the new song object if has_songs_books and song.songbook_entries: for entry in song.songbook_entries: existing_book = self.manager.get_object_filtered( Book, Book.name == entry.songbook.name) if not existing_book: existing_book = Book.populate( name=entry.songbook.name, publisher=entry.songbook.publisher) new_song.add_songbook_entry(existing_book, entry.entry) elif hasattr(song, 'book') and song.book: existing_book = self.manager.get_object_filtered( Book, Book.name == song.book.name) if not existing_book: existing_book = Book.populate( name=song.book.name, publisher=song.book.publisher) # Get the song_number from "songs" table "song_number" field. (This is db structure from 2.2.1) # If there's a number, add it to the song, otherwise it will be "". existing_number = song.song_number if hasattr( song, 'song_number') else '' if existing_number: new_song.add_songbook_entry(existing_book, existing_number) else: new_song.add_songbook_entry(existing_book, '') # Find or create all the media files and add them to the new song object if has_media_files and song.media_files: for media_file in song.media_files: existing_media_file = self.manager.get_object_filtered( MediaFile, MediaFile.file_path == media_file.file_path) if existing_media_file: new_song.media_files.append(existing_media_file) else: new_song.media_files.append( MediaFile.populate(file_name=media_file.file_name)) clean_song(self.manager, new_song) self.manager.save_object(new_song) if progress_dialog: progress_dialog.setValue(progress_dialog.value() + 1) progress_dialog.setLabelText( WizardStrings.ImportingType.format(source=new_song.title)) else: self.import_wizard.increment_progress_bar( WizardStrings.ImportingType.format(source=new_song.title)) if self.stop_import_flag: break self.source_session.close() engine.dispose()