forked from openlp/openlp
OpenLP v2 song DB importer
This commit is contained in:
parent
80eb8e36af
commit
7e623ea226
@ -142,6 +142,7 @@ from songstab import SongsTab
|
||||
from mediaitem import SongMediaItem
|
||||
from songimport import SongImport
|
||||
from opensongimport import OpenSongImport
|
||||
from olpimport import OpenLPSongImport
|
||||
try:
|
||||
from sofimport import SofImport
|
||||
from oooimport import OooImport
|
||||
|
198
openlp/plugins/songs/lib/olpimport.py
Normal file
198
openlp/plugins/songs/lib/olpimport.py
Normal file
@ -0,0 +1,198 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
||||
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2010 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
|
||||
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
|
||||
# Thompson, Jon Tibble, Carsten Tinggaard #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# This program is free software; you can redistribute it and/or modify it #
|
||||
# under the terms of the GNU General Public License as published by the Free #
|
||||
# Software Foundation; version 2 of the License. #
|
||||
# #
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT #
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
||||
# more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU General Public License along #
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
"""
|
||||
The :mod:`olpimport` module provides the functionality for importing OpenLP
|
||||
song databases into the current installation database.
|
||||
"""
|
||||
import logging
|
||||
|
||||
from sqlalchemy import create_engine, MetaData
|
||||
from sqlalchemy.orm import class_mapper, mapper, relation, scoped_session, \
|
||||
sessionmaker
|
||||
from sqlalchemy.orm.exc import UnmappedClassError
|
||||
|
||||
from openlp.core.lib.db import BaseModel
|
||||
from openlp.plugins.songs.lib.db import Author, Book, Song, Topic #, AudioFile
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
class OldAudioFile(BaseModel):
|
||||
"""
|
||||
AudioFile model
|
||||
"""
|
||||
pass
|
||||
|
||||
class OldAuthor(BaseModel):
|
||||
"""
|
||||
Author model
|
||||
"""
|
||||
pass
|
||||
|
||||
class OldBook(BaseModel):
|
||||
"""
|
||||
Book model
|
||||
"""
|
||||
pass
|
||||
|
||||
class OldSong(BaseModel):
|
||||
"""
|
||||
Song model
|
||||
"""
|
||||
pass
|
||||
|
||||
class OldTopic(BaseModel):
|
||||
"""
|
||||
Topic model
|
||||
"""
|
||||
pass
|
||||
|
||||
class OpenLPSongImport(object):
|
||||
"""
|
||||
|
||||
"""
|
||||
def __init__(self, master_manager, source_db):
|
||||
"""
|
||||
|
||||
"""
|
||||
self.master_manager = master_manager
|
||||
self.import_source = source_db
|
||||
self.source_session = None
|
||||
|
||||
def import_source_v2_db(self):
|
||||
"""
|
||||
|
||||
"""
|
||||
engine = create_engine(self.import_source)
|
||||
source_meta = MetaData()
|
||||
source_meta.reflect(engine)
|
||||
self.source_session = scoped_session(sessionmaker(bind=engine))
|
||||
if u'audio_files' in source_meta.tables.keys():
|
||||
has_audio_files = True
|
||||
else:
|
||||
has_audio_files = False
|
||||
source_authors_table = source_meta.tables[u'authors']
|
||||
source_song_books_table = source_meta.tables[u'song_books']
|
||||
source_songs_table = source_meta.tables[u'songs']
|
||||
source_topics_table = source_meta.tables[u'topics']
|
||||
source_authors_songs_table = source_meta.tables[u'authors_songs']
|
||||
source_songs_topics_table = source_meta.tables[u'songs_topics']
|
||||
if has_audio_files:
|
||||
source_audio_files_table = source_meta.tables[u'audio_files']
|
||||
source_audio_files_songs_table = \
|
||||
source_meta.tables[u'audio_files_songs']
|
||||
try:
|
||||
class_mapper(OldAudioFile)
|
||||
except UnmappedClassError:
|
||||
mapper(OldAudioFile, source_audio_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_audio_files:
|
||||
song_props['audio_files'] = relation(OldAudioFile, backref='songs',
|
||||
secondary=source_audio_files_songs_table)
|
||||
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()
|
||||
for song in source_songs:
|
||||
new_song = Song()
|
||||
new_song.title = song.title
|
||||
if has_audio_files:
|
||||
new_song.alternate_title = song.alternate_title
|
||||
else:
|
||||
new_song.alternate_title = u''
|
||||
new_song.search_title = song.search_title
|
||||
new_song.song_number = song.song_number
|
||||
new_song.lyrics = song.lyrics
|
||||
new_song.search_lyrics = song.search_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 song.authors:
|
||||
for author in song.authors:
|
||||
existing_author = self.master_manager.get_object_filtered(
|
||||
Author, Author.display_name == author.display_name)
|
||||
if existing_author:
|
||||
new_song.authors.append(existing_author)
|
||||
else:
|
||||
new_song.authors.append(Author.populate(
|
||||
first_name=author.first_name,
|
||||
last_name=author.last_name,
|
||||
display_name=author.display_name))
|
||||
else:
|
||||
au = self.master_manager.get_object_filtered(Author,
|
||||
Author.display_name == u'Author Unknown')
|
||||
if au:
|
||||
new_song.authors.append(au)
|
||||
else:
|
||||
new_song.authors.append(Author.populate(
|
||||
display_name=u'Author Unknown'))
|
||||
if song.song_book_id != 0:
|
||||
existing_song_book = self.master_manager.get_object_filtered(
|
||||
Book, Book.name == song.book.name)
|
||||
if existing_song_book:
|
||||
new_song.book = existing_song_book
|
||||
else:
|
||||
new_song.book = Book.populate(name=song.book.name,
|
||||
publisher=song.book.publisher)
|
||||
if song.topics:
|
||||
for topic in song.topics:
|
||||
existing_topic = self.master_manager.get_object_filtered(
|
||||
Topic, Topic.name == topic.name)
|
||||
if existing_topic:
|
||||
new_song.topics.append(existing_topic)
|
||||
else:
|
||||
new_song.topics.append(Topic.populate(name=topic.name))
|
||||
# if has_audio_files:
|
||||
# if song.audio_files:
|
||||
# for audio_file in song.audio_files:
|
||||
# existing_audio_file = \
|
||||
# self.master_manager.get_object_filtered(AudioFile,
|
||||
# AudioFile.file_name == audio_file.file_name)
|
||||
# if existing_audio_file:
|
||||
# new_song.audio_files.remove(audio_file)
|
||||
# new_song.audio_files.append(existing_audio_file)
|
||||
self.master_manager.save_object(new_song)
|
||||
engine.dispose()
|
@ -50,7 +50,7 @@ class SongImport(object):
|
||||
self.song_number = u''
|
||||
self.alternate_title = u''
|
||||
self.copyright = u''
|
||||
self.comment = u''
|
||||
self.comments = u''
|
||||
self.theme_name = u''
|
||||
self.ccli_number = u''
|
||||
self.authors = []
|
||||
@ -253,7 +253,7 @@ class SongImport(object):
|
||||
song.lyrics = unicode(sxml.extract_xml(), u'utf-8')
|
||||
song.verse_order = u' '.join(self.verse_order_list)
|
||||
song.copyright = self.copyright
|
||||
song.comment = self.comment
|
||||
song.comments = self.comments
|
||||
song.theme_name = self.theme_name
|
||||
song.ccli_number = self.ccli_number
|
||||
for authortext in self.authors:
|
||||
@ -274,7 +274,8 @@ class SongImport(object):
|
||||
for topictext in self.topics:
|
||||
if len(topictext) == 0:
|
||||
continue
|
||||
topic = self.manager.get_object_filtered(Topic, Topic.name == topictext)
|
||||
topic = self.manager.get_object_filtered(Topic,
|
||||
Topic.name == topictext)
|
||||
if topic is None:
|
||||
topic = Topic.populate(name=topictext)
|
||||
song.topics.append(topic)
|
||||
@ -303,8 +304,8 @@ class SongImport(object):
|
||||
print u'NUMBER: ' + self.song_number
|
||||
for topictext in self.topics:
|
||||
print u'TOPIC: ' + topictext
|
||||
if self.comment:
|
||||
print u'COMMENT: ' + self.comment
|
||||
if self.comments:
|
||||
print u'COMMENTS: ' + self.comments
|
||||
if self.theme_name:
|
||||
print u'THEME: ' + self.theme_name
|
||||
if self.ccli_number:
|
||||
|
@ -30,7 +30,7 @@ from PyQt4 import QtCore, QtGui
|
||||
from openlp.core.lib import Plugin, build_icon, PluginStatus, Receiver, \
|
||||
translate
|
||||
from openlp.core.lib.db import Manager
|
||||
from openlp.plugins.songs.lib import SongMediaItem, SongsTab
|
||||
from openlp.plugins.songs.lib import OpenLPSongImport, SongMediaItem, SongsTab
|
||||
from openlp.plugins.songs.lib.db import init_schema, Song
|
||||
|
||||
try:
|
||||
@ -157,7 +157,19 @@ class SongsPlugin(Plugin):
|
||||
import_menu.addAction(self.ImportOpenSongItem)
|
||||
QtCore.QObject.connect(self.ImportOpenSongItem,
|
||||
QtCore.SIGNAL(u'triggered()'), self.onImportOpenSongItemClick)
|
||||
|
||||
# OpenLP v2 import menu item - ditto above regarding refactoring into
|
||||
# an import wizard
|
||||
self.ImportOpenLPSongItem = QtGui.QAction(import_menu)
|
||||
self.ImportOpenLPSongItem.setObjectName(u'ImportOpenLPSongItem')
|
||||
self.ImportOpenLPSongItem.setText(translate('SongsPlugin',
|
||||
'OpenLP v2 (temporary)'))
|
||||
self.ImportOpenLPSongItem.setToolTip(translate('SongsPlugin',
|
||||
'Import an OpenLP v2 song database'))
|
||||
self.ImportOpenLPSongItem.setStatusTip(translate('SongsPlugin',
|
||||
'Import an OpenLP v2 song database'))
|
||||
import_menu.addAction(self.ImportOpenLPSongItem)
|
||||
QtCore.QObject.connect(self.ImportOpenLPSongItem,
|
||||
QtCore.SIGNAL(u'triggered()'), self.onImportOpenLPSongItemClick)
|
||||
|
||||
def addExportMenuItem(self, export_menu):
|
||||
"""
|
||||
@ -218,6 +230,25 @@ class SongsPlugin(Plugin):
|
||||
QtGui.QMessageBox.Ok)
|
||||
Receiver.send_message(u'songs_load_list')
|
||||
|
||||
def onImportOpenLPSongItemClick(self):
|
||||
filenames = QtGui.QFileDialog.getOpenFileNames(None,
|
||||
translate('SongsPlugin', 'Select OpenLP database(s) to import...'),
|
||||
u'', u'OpenLP databases (*.sqlite);;All Files (*)')
|
||||
try:
|
||||
for filename in filenames:
|
||||
db_url = u'sqlite:///%s' % filename
|
||||
importer = OpenLPSongImport(self.manager, db_url)
|
||||
importer.import_source_v2_db()
|
||||
QtGui.QMessageBox.information(None, translate('SongsPlugin',
|
||||
'Database(s) imported'), translate('SongsPlugin', 'Your '
|
||||
'OpenLP v2 song databases have been successfully imported'))
|
||||
except:
|
||||
log.exception(u'Failed to import OpenLP v2 database(s)')
|
||||
QtGui.QMessageBox.critical(None, translate('SongsPlugin',
|
||||
'Import Error'), translate('SongsPlugin',
|
||||
'Error importing OpenLP v2 database(s)'))
|
||||
Receiver.send_message(u'songs_load_list')
|
||||
|
||||
def onImportOooItemClick(self):
|
||||
filenames = QtGui.QFileDialog.getOpenFileNames(
|
||||
None, translate('SongsPlugin',
|
||||
|
Loading…
Reference in New Issue
Block a user