示例#1
0
 def on_topic_add_button_clicked(self):
     item = int(self.topicsComboBox.currentIndex())
     text = self.topicsComboBox.currentText()
     if item == 0 and text:
         if QtGui.QMessageBox.question(self, translate('SongsPlugin.EditSongForm', 'Add Topic'),
                 translate('SongsPlugin.EditSongForm', 'This topic does not exist, do you want to add it?'),
                 QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.Yes) == QtGui.QMessageBox.Yes:
             topic = Topic.populate(name=text)
             self.manager.save_object(topic)
             topic_item = QtGui.QListWidgetItem(str(topic.name))
             topic_item.setData(QtCore.Qt.UserRole, topic.id)
             self.topics_list_view.addItem(topic_item)
             self.load_topics()
             self.topicsComboBox.setCurrentIndex(0)
         else:
             return
     elif item > 0:
         item_id = (self.topicsComboBox.itemData(item))
         topic = self.manager.get_object(Topic, item_id)
         if self.topics_list_view.findItems(str(topic.name),
             QtCore.Qt.MatchExactly):
             critical_error_message_box(
                 message=translate('SongsPlugin.EditSongForm', 'This topic is already in the list.'))
         else:
             topic_item = QtGui.QListWidgetItem(str(topic.name))
             topic_item.setData(QtCore.Qt.UserRole, topic.id)
             self.topics_list_view.addItem(topic_item)
         self.topicsComboBox.setCurrentIndex(0)
     else:
         QtGui.QMessageBox.warning(self, UiStrings().NISs,
             translate('SongsPlugin.EditSongForm', 'You have not selected a valid topic. Either select a topic '
             'from the list, or type in a new topic and click the "Add Topic to Song" button to add the new topic.'))
示例#2
0
    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 on_add_topic_button_clicked(self):
     """
     Add a topic to the list.
     """
     if self.topic_form.exec_():
         topic = Topic.populate(name=self.topic_form.name)
         if self.check_topic_exists(topic):
             if self.manager.save_object(topic):
                 self.reset_topics()
             else:
                 critical_error_message_box(
                     message=translate('SongsPlugin.SongMaintenanceForm', 'Could not add your topic.'))
         else:
             critical_error_message_box(
                 message=translate('SongsPlugin.SongMaintenanceForm', 'This topic already exists.'))
示例#4
0
 def on_add_topic_button_clicked(self):
     """
     Add a topic to the list.
     """
     if self.topic_form.exec():
         topic = Topic.populate(name=self.topic_form.name)
         if self.check_topic_exists(topic):
             if self.manager.save_object(topic):
                 self.reset_topics()
             else:
                 critical_error_message_box(
                     message=translate('SongsPlugin.SongMaintenanceForm', 'Could not add your topic.'))
         else:
             critical_error_message_box(
                 message=translate('SongsPlugin.SongMaintenanceForm', 'This topic already exists.'))
示例#5
0
    def _process_topics(self, properties, song):
        """
        Adds the topics to the song.

        :param properties: The property object (lxml.objectify.ObjectifiedElement).
        :param song: The song object.
        """
        if hasattr(properties, 'themes'):
            for topic_text in properties.themes.theme:
                topic_text = self._text(topic_text)
                if topic_text:
                    topic = self.manager.get_object_filtered(Topic, Topic.name == topic_text)
                    if topic is None:
                        # We need to create a topic, because it does not exist.
                        topic = Topic.populate(name=topic_text)
                        self.manager.save_object(topic)
                    song.topics.append(topic)
示例#6
0
    def _process_topics(self, properties, song):
        """
        Adds the topics to the song.

        :param properties: The property object (lxml.objectify.ObjectifiedElement).
        :param song: The song object.
        """
        if hasattr(properties, 'themes'):
            for topic_text in properties.themes.theme:
                topic_text = self._text(topic_text)
                if topic_text:
                    topic = self.manager.get_object_filtered(Topic, Topic.name == topic_text)
                    if topic is None:
                        # We need to create a topic, because it does not exist.
                        topic = Topic.populate(name=topic_text)
                        self.manager.save_object(topic)
                    song.topics.append(topic)
示例#7
0
    def _process_topics(self, foilpresenterfolie, song):
        """
        Adds the topics to the song.

        :param foilpresenterfolie:  The property object (lxml.objectify.ObjectifiedElement).
        :param song: The song object.
        """
        try:
            for name in foilpresenterfolie.kategorien.name:
                topic_text = to_str(name)
                if topic_text:
                    topic = self.manager.get_object_filtered(Topic, Topic.name == topic_text)
                    if topic is None:
                        # We need to create a topic, because it does not exist.
                        topic = Topic.populate(name=topic_text)
                        self.manager.save_object(topic)
                    song.topics.append(topic)
        except AttributeError:
            pass
示例#8
0
    def _process_topics(self, foilpresenterfolie, song):
        """
        Adds the topics to the song.

        :param foilpresenterfolie:  The property object (lxml.objectify.ObjectifiedElement).
        :param song: The song object.
        """
        try:
            for name in foilpresenterfolie.kategorien.name:
                topic_text = self._child(name)
                if topic_text:
                    topic = self.manager.get_object_filtered(Topic, Topic.name == topic_text)
                    if topic is None:
                        # We need to create a topic, because it does not exist.
                        topic = Topic.populate(name=topic_text)
                        self.manager.save_object(topic)
                    song.topics.append(topic)
        except AttributeError:
            pass
示例#9
0
    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()
示例#10
0
 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
示例#11
0
文件: openlp.py 项目: imkernel/openlp
    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()
示例#12
0
 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
示例#13
0
文件: openlp.py 项目: ipic/projecao
    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()