~trb143/openlp/themecombo-24

« back to all changes in this revision

Viewing changes to openlp/plugins/songs/lib/importers/openlp.py

  • Committer: Raoul Snyman
  • Author(s): raoul at snyman
  • Date: 2016-04-27 21:26:14 UTC
  • mfrom: (2624.1.1 bug-1557514-2.4)
  • Revision ID: raoul@snyman.info-20160427212614-6zoksrks8gmd1388
"Fix bug #1557514 by auto-detecting the columns of the tables in the songs database

Add this to your merge proposal:
--------------------------------
lp:~raoul-snyman/openlp/bug-1557514-2.4 (revision 2625)
[SUCCESS] https://ci.openlp.io/job/Branch-01-Pull/1502/
[SUCCESS] https://ci.openlp.io/job/Branch-02-Functional-Tests/1413/
[SUCCESS] https://ci.openlp.io/job/Branch-03-Interface-Tests/1351/
[SUCCESS] https://ci.openlp.io/job/Branch-04a-Windows_Functional_Tests/1147/
[SUCCESS] https://ci.op..."

Show diffs side-by-side

added added

removed removed

Lines of Context:
51
51
        :param manager: The song manager for the running OpenLP installation.
52
52
        :param kwargs: The database providing the data to import.
53
53
        """
54
 
        SongImport.__init__(self, manager, **kwargs)
 
54
        super(OpenLPSongImport, self).__init__(manager, **kwargs)
55
55
        self.source_session = None
56
56
 
57
57
    def do_import(self, progress_dialog=None):
63
63
 
64
64
        class OldAuthor(BaseModel):
65
65
            """
66
 
            Author model
 
66
            Maps to the authors table
67
67
            """
68
68
            pass
69
69
 
70
70
        class OldBook(BaseModel):
71
71
            """
72
 
            Book model
 
72
            Maps to the songbooks table
73
73
            """
74
74
            pass
75
75
 
76
76
        class OldMediaFile(BaseModel):
77
77
            """
78
 
            MediaFile model
 
78
            Maps to the media_files table
79
79
            """
80
80
            pass
81
81
 
82
82
        class OldSong(BaseModel):
83
83
            """
84
 
            Song model
 
84
            Maps to the songs table
85
85
            """
86
86
            pass
87
87
 
88
88
        class OldTopic(BaseModel):
89
89
            """
90
 
            Topic model
 
90
            Maps to the topics table
 
91
            """
 
92
            pass
 
93
 
 
94
        class OldSongBookEntry(BaseModel):
 
95
            """
 
96
            Maps to the songs_songbooks table
91
97
            """
92
98
            pass
93
99
 
94
100
        # Check the file type
95
 
        if not self.import_source.endswith('.sqlite'):
 
101
        if not isinstance(self.import_source, str) or not self.import_source.endswith('.sqlite'):
96
102
            self.log_error(self.import_source, translate('SongsPlugin.OpenLPSongImport',
97
103
                                                         'Not a valid OpenLP 2 song database.'))
98
104
            return
99
105
        self.import_source = 'sqlite:///%s' % self.import_source
100
 
        # Load the db file
 
106
        # Load the db file and reflect it
101
107
        engine = create_engine(self.import_source)
102
108
        source_meta = MetaData()
103
109
        source_meta.reflect(engine)
104
110
        self.source_session = scoped_session(sessionmaker(bind=engine))
 
111
        # Run some checks to see which version of the database we have
105
112
        if 'media_files' in list(source_meta.tables.keys()):
106
113
            has_media_files = True
107
114
        else:
108
115
            has_media_files = False
 
116
        if 'songs_songbooks' in list(source_meta.tables.keys()):
 
117
            has_songs_books = True
 
118
        else:
 
119
            has_songs_books = False
 
120
        # Load up the tabls and map them out
109
121
        source_authors_table = source_meta.tables['authors']
110
122
        source_song_books_table = source_meta.tables['song_books']
111
123
        source_songs_table = source_meta.tables['songs']
113
125
        source_authors_songs_table = source_meta.tables['authors_songs']
114
126
        source_songs_topics_table = source_meta.tables['songs_topics']
115
127
        source_media_files_songs_table = None
 
128
        # Set up media_files relations
116
129
        if has_media_files:
117
130
            source_media_files_table = source_meta.tables['media_files']
118
131
            source_media_files_songs_table = source_meta.tables.get('media_files_songs')
120
133
                class_mapper(OldMediaFile)
121
134
            except UnmappedClassError:
122
135
                mapper(OldMediaFile, source_media_files_table)
 
136
        if has_songs_books:
 
137
            source_songs_songbooks_table = source_meta.tables['songs_songbooks']
 
138
            try:
 
139
                class_mapper(OldSongBookEntry)
 
140
            except UnmappedClassError:
 
141
                mapper(OldSongBookEntry, source_songs_songbooks_table, properties={'songbook': relation(OldBook)})
 
142
        # Set up the songs relationships
123
143
        song_props = {
124
144
            'authors': relation(OldAuthor, backref='songs', secondary=source_authors_songs_table),
125
 
            'book': relation(OldBook, backref='songs'),
126
145
            'topics': relation(OldTopic, backref='songs', secondary=source_songs_topics_table)
127
146
        }
128
147
        if has_media_files:
134
153
                    relation(OldMediaFile, backref='songs',
135
154
                             foreign_keys=[source_media_files_table.c.song_id],
136
155
                             primaryjoin=source_songs_table.c.id == source_media_files_table.c.song_id)
 
156
        if has_songs_books:
 
157
            song_props['songbook_entries'] = relation(OldSongBookEntry, backref='song', cascade='all, delete-orphan')
 
158
        else:
 
159
            song_props['book'] = relation(OldBook, backref='songs')
 
160
        # Map the rest of the tables
137
161
        try:
138
162
            class_mapper(OldAuthor)
139
163
        except UnmappedClassError:
163
187
                old_titles = song.search_title.split('@')
164
188
                if len(old_titles) > 1:
165
189
                    new_song.alternate_title = old_titles[1]
166
 
            # Values will be set when cleaning the song.
 
190
            # Transfer the values to the new song object
167
191
            new_song.search_title = ''
168
192
            new_song.search_lyrics = ''
169
 
            new_song.song_number = song.song_number
170
193
            new_song.lyrics = song.lyrics
171
194
            new_song.verse_order = song.verse_order
172
195
            new_song.copyright = song.copyright
173
196
            new_song.comments = song.comments
174
197
            new_song.theme_name = song.theme_name
175
198
            new_song.ccli_number = song.ccli_number
 
199
            if hasattr(song, 'song_number') and song.song_number:
 
200
                new_song.song_number = song.song_number
 
201
            # Find or create all the authors and add them to the new song object
176
202
            for author in song.authors:
177
203
                existing_author = self.manager.get_object_filtered(Author, Author.display_name == author.display_name)
178
 
                if existing_author is None:
 
204
                if not existing_author:
179
205
                    existing_author = Author.populate(
180
206
                        first_name=author.first_name,
181
207
                        last_name=author.last_name,
182
208
                        display_name=author.display_name)
183
209
                new_song.add_author(existing_author)
184
 
            if song.book:
185
 
                existing_song_book = self.manager.get_object_filtered(Book, Book.name == song.book.name)
186
 
                if existing_song_book is None:
187
 
                    existing_song_book = Book.populate(name=song.book.name, publisher=song.book.publisher)
188
 
                new_song.book = existing_song_book
 
210
            # Find or create all the topics and add them to the new song object
189
211
            if song.topics:
190
212
                for topic in song.topics:
191
213
                    existing_topic = self.manager.get_object_filtered(Topic, Topic.name == topic.name)
192
 
                    if existing_topic is None:
 
214
                    if not existing_topic:
193
215
                        existing_topic = Topic.populate(name=topic.name)
194
216
                    new_song.topics.append(existing_topic)
195
 
            if has_media_files:
196
 
                if song.media_files:
197
 
                    for media_file in song.media_files:
198
 
                        existing_media_file = self.manager.get_object_filtered(
199
 
                            MediaFile, MediaFile.file_name == media_file.file_name)
200
 
                        if existing_media_file:
201
 
                            new_song.media_files.append(existing_media_file)
202
 
                        else:
203
 
                            new_song.media_files.append(MediaFile.populate(file_name=media_file.file_name))
 
217
            # Find or create all the songbooks and add them to the new song object
 
218
            if has_songs_books and song.songbook_entries:
 
219
                for entry in song.songbook_entries:
 
220
                    existing_book = self.manager.get_object_filtered(Book, Book.name == entry.songbook.name)
 
221
                    if not existing_book:
 
222
                        existing_book = Book.populate(name=entry.songbook.name, publisher=entry.songbook.publisher)
 
223
                    new_song.add_songbook_entry(existing_book, entry.entry)
 
224
            elif song.book:
 
225
                existing_book = self.manager.get_object_filtered(Book, Book.name == song.book.name)
 
226
                if not existing_book:
 
227
                    existing_book = Book.populate(name=song.book.name, publisher=song.book.publisher)
 
228
                new_song.add_songbook_entry(existing_book, '')
 
229
            # Find or create all the media files and add them to the new song object
 
230
            if has_media_files and song.media_files:
 
231
                for media_file in song.media_files:
 
232
                    existing_media_file = self.manager.get_object_filtered(
 
233
                        MediaFile, MediaFile.file_name == media_file.file_name)
 
234
                    if existing_media_file:
 
235
                        new_song.media_files.append(existing_media_file)
 
236
                    else:
 
237
                        new_song.media_files.append(MediaFile.populate(file_name=media_file.file_name))
204
238
            clean_song(self.manager, new_song)
205
239
            self.manager.save_object(new_song)
206
240
            if progress_dialog: