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 mediaitem import SongMediaItem
|
||||||
from songimport import SongImport
|
from songimport import SongImport
|
||||||
from opensongimport import OpenSongImport
|
from opensongimport import OpenSongImport
|
||||||
|
from olpimport import OpenLPSongImport
|
||||||
try:
|
try:
|
||||||
from sofimport import SofImport
|
from sofimport import SofImport
|
||||||
from oooimport import OooImport
|
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.song_number = u''
|
||||||
self.alternate_title = u''
|
self.alternate_title = u''
|
||||||
self.copyright = u''
|
self.copyright = u''
|
||||||
self.comment = u''
|
self.comments = u''
|
||||||
self.theme_name = u''
|
self.theme_name = u''
|
||||||
self.ccli_number = u''
|
self.ccli_number = u''
|
||||||
self.authors = []
|
self.authors = []
|
||||||
@ -253,7 +253,7 @@ class SongImport(object):
|
|||||||
song.lyrics = unicode(sxml.extract_xml(), u'utf-8')
|
song.lyrics = unicode(sxml.extract_xml(), u'utf-8')
|
||||||
song.verse_order = u' '.join(self.verse_order_list)
|
song.verse_order = u' '.join(self.verse_order_list)
|
||||||
song.copyright = self.copyright
|
song.copyright = self.copyright
|
||||||
song.comment = self.comment
|
song.comments = self.comments
|
||||||
song.theme_name = self.theme_name
|
song.theme_name = self.theme_name
|
||||||
song.ccli_number = self.ccli_number
|
song.ccli_number = self.ccli_number
|
||||||
for authortext in self.authors:
|
for authortext in self.authors:
|
||||||
@ -274,7 +274,8 @@ class SongImport(object):
|
|||||||
for topictext in self.topics:
|
for topictext in self.topics:
|
||||||
if len(topictext) == 0:
|
if len(topictext) == 0:
|
||||||
continue
|
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:
|
if topic is None:
|
||||||
topic = Topic.populate(name=topictext)
|
topic = Topic.populate(name=topictext)
|
||||||
song.topics.append(topic)
|
song.topics.append(topic)
|
||||||
@ -303,8 +304,8 @@ class SongImport(object):
|
|||||||
print u'NUMBER: ' + self.song_number
|
print u'NUMBER: ' + self.song_number
|
||||||
for topictext in self.topics:
|
for topictext in self.topics:
|
||||||
print u'TOPIC: ' + topictext
|
print u'TOPIC: ' + topictext
|
||||||
if self.comment:
|
if self.comments:
|
||||||
print u'COMMENT: ' + self.comment
|
print u'COMMENTS: ' + self.comments
|
||||||
if self.theme_name:
|
if self.theme_name:
|
||||||
print u'THEME: ' + self.theme_name
|
print u'THEME: ' + self.theme_name
|
||||||
if self.ccli_number:
|
if self.ccli_number:
|
||||||
|
@ -30,7 +30,7 @@ from PyQt4 import QtCore, QtGui
|
|||||||
from openlp.core.lib import Plugin, build_icon, PluginStatus, Receiver, \
|
from openlp.core.lib import Plugin, build_icon, PluginStatus, Receiver, \
|
||||||
translate
|
translate
|
||||||
from openlp.core.lib.db import Manager
|
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
|
from openlp.plugins.songs.lib.db import init_schema, Song
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -157,7 +157,19 @@ class SongsPlugin(Plugin):
|
|||||||
import_menu.addAction(self.ImportOpenSongItem)
|
import_menu.addAction(self.ImportOpenSongItem)
|
||||||
QtCore.QObject.connect(self.ImportOpenSongItem,
|
QtCore.QObject.connect(self.ImportOpenSongItem,
|
||||||
QtCore.SIGNAL(u'triggered()'), self.onImportOpenSongItemClick)
|
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):
|
def addExportMenuItem(self, export_menu):
|
||||||
"""
|
"""
|
||||||
@ -218,6 +230,25 @@ class SongsPlugin(Plugin):
|
|||||||
QtGui.QMessageBox.Ok)
|
QtGui.QMessageBox.Ok)
|
||||||
Receiver.send_message(u'songs_load_list')
|
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):
|
def onImportOooItemClick(self):
|
||||||
filenames = QtGui.QFileDialog.getOpenFileNames(
|
filenames = QtGui.QFileDialog.getOpenFileNames(
|
||||||
None, translate('SongsPlugin',
|
None, translate('SongsPlugin',
|
||||||
|
Loading…
Reference in New Issue
Block a user