RFC PT2: Refactor Manager

This commit is contained in:
Jon Tibble 2010-06-13 00:00:14 +01:00
parent 5f2042168d
commit 54aa8958fe
11 changed files with 176 additions and 351 deletions

View File

@ -25,10 +25,17 @@
""" """
The :mod:`db` module provides the core database functionality for OpenLP The :mod:`db` module provides the core database functionality for OpenLP
""" """
import logging
from PyQt4 import QtCore
from sqlalchemy import create_engine, MetaData from sqlalchemy import create_engine, MetaData
from sqlalchemy.exceptions import InvalidRequestError
from sqlalchemy.orm import scoped_session, sessionmaker from sqlalchemy.orm import scoped_session, sessionmaker
from openlp.core.utils import AppLocation
log = logging.getLogger(__name__)
def init_db(url, auto_flush=True, auto_commit=False): def init_db(url, auto_flush=True, auto_commit=False):
""" """
Initialise and return the session and metadata for a database Initialise and return the session and metadata for a database
@ -62,3 +69,117 @@ class BaseModel(object):
for key in kwargs: for key in kwargs:
me.__setattr__(key, kwargs[key]) me.__setattr__(key, kwargs[key])
return me return me
class Manager(object):
"""
Provide generic object persistence management
"""
def __init__(self, plugin_name, init_schema):
"""
Runs the initialisation process that includes creating the connection
to the database and the tables if they don't exist.
``plugin_name``
The name to setup paths and settings section names
"""
settings = QtCore.QSettings()
settings.beginGroup(plugin_name)
self.db_url = u''
db_type = unicode(
settings.value(u'db type', QtCore.QVariant(u'sqlite')).toString())
if db_type == u'sqlite':
self.db_url = u'sqlite:///%s/%s.sqlite' % (
AppLocation.get_section_data_path(plugin_name), plugin_name)
else:
self.db_url = u'%s://%s:%s@%s/%s' % (db_type,
unicode(settings.value(u'db username').toString()),
unicode(settings.value(u'db password').toString()),
unicode(settings.value(u'db hostname').toString()),
unicode(settings.value(u'db database').toString()))
settings.endGroup()
self.session = init_schema(self.db_url)
def insert_object(self, object_instance):
"""
Save an object to the database
``object_instance``
The object to save
"""
try:
self.session.add(object_instance)
self.session.commit()
return True
except InvalidRequestError:
self.session.rollback()
log.exception(u'Object save failed')
return False
def get_object(self, object_class, id=None):
"""
Return the details of an object
``object_class``
The type of object to return
``id``
The unique reference for the class instance to return
"""
if not id:
return object_class()
else:
return self.session.query(object_class).get(id)
def get_all_objects(self, object_class, order_by_ref=None):
"""
Returns all the objects from the database
``object_class``
The type of object to return
``order_by_ref``
Any parameters to order the returned objects by. Defaults to None.
"""
if order_by_ref:
return self.session.query(object_class).order_by(order_by_ref).all()
return self.session.query(object_class).all()
def delete_object(self, object_class, id):
"""
Delete an object from the database
``object_class``
The type of object to delete
``id``
The unique reference for the class instance to be deleted
"""
if id != 0:
object = self.get_object(object_class, id)
try:
self.session.delete(object)
self.session.commit()
return True
except InvalidRequestError:
self.session.rollback()
log.exception(u'Failed to delete object')
return False
else:
return True
def delete_all_objects(self, object_class):
"""
Delete all object records
``object_class``
The type of object to delete
"""
try:
self.session.query(object_class).delete(synchronize_session=False)
self.session.commit()
return True
except InvalidRequestError:
self.session.rollback()
log.exception(u'Failed to delete all %s records',
object_class.__name__)
return False

View File

@ -28,7 +28,9 @@ import logging
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import Plugin, build_icon, PluginStatus, translate from openlp.core.lib import Plugin, build_icon, PluginStatus, translate
from openlp.plugins.alerts.lib import AlertsManager, AlertsTab, DBManager from openlp.core.lib.db import Manager
from openlp.plugins.alerts.lib import AlertsManager, AlertsTab
from openlp.plugins.alerts.lib.db import init_schema
from openlp.plugins.alerts.forms import AlertForm from openlp.plugins.alerts.forms import AlertForm
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -41,7 +43,7 @@ class alertsPlugin(Plugin):
self.weight = -3 self.weight = -3
self.icon = build_icon(u':/media/media_image.png') self.icon = build_icon(u':/media/media_image.png')
self.alertsmanager = AlertsManager(self) self.alertsmanager = AlertsManager(self)
self.manager = DBManager() self.manager = Manager(u'alerts', init_schema)
self.alertForm = AlertForm(self.manager, self) self.alertForm = AlertForm(self.manager, self)
self.status = PluginStatus.Active self.status = PluginStatus.Active

View File

@ -62,7 +62,7 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
def loadList(self): def loadList(self):
self.AlertListWidget.clear() self.AlertListWidget.clear()
alerts = self.manager.get_all_alerts() alerts = self.manager.get_all_objects(AlertItem, AlertItem.text)
for alert in alerts: for alert in alerts:
item_name = QtGui.QListWidgetItem(alert.text) item_name = QtGui.QListWidgetItem(alert.text)
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(alert.id)) item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(alert.id))
@ -82,7 +82,7 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
item = self.AlertListWidget.currentItem() item = self.AlertListWidget.currentItem()
if item: if item:
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
self.parent.manager.delete_alert(item_id) self.manager.delete_object(AlertItem, item_id)
row = self.AlertListWidget.row(item) row = self.AlertListWidget.row(item)
self.AlertListWidget.takeItem(row) self.AlertListWidget.takeItem(row)
self.AlertTextEdit.setText(u'') self.AlertTextEdit.setText(u'')
@ -98,15 +98,15 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
else: else:
alert = AlertItem() alert = AlertItem()
alert.text = unicode(self.AlertTextEdit.text()) alert.text = unicode(self.AlertTextEdit.text())
self.manager.save_alert(alert) self.manager.insert_object(alert)
self.AlertTextEdit.setText(u'') self.AlertTextEdit.setText(u'')
self.loadList() self.loadList()
def onSaveClick(self): def onSaveClick(self):
if self.item_id: if self.item_id:
alert = self.manager.get_alert(self.item_id) alert = self.manager.get_object(AlertItem, self.item_id)
alert.text = unicode(self.AlertTextEdit.text()) alert.text = unicode(self.AlertTextEdit.text())
self.manager.save_alert(alert) self.manager.insert_object(alert)
self.item_id = None self.item_id = None
self.loadList() self.loadList()
else: else:
@ -148,4 +148,3 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
self.parent.alertsmanager.displayAlert(text) self.parent.alertsmanager.displayAlert(text)
return True return True
return False return False

View File

@ -25,4 +25,3 @@
from alertsmanager import AlertsManager from alertsmanager import AlertsManager
from alertstab import AlertsTab from alertstab import AlertsTab
from manager import DBManager

View File

@ -1,112 +0,0 @@
# -*- 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 #
###############################################################################
import logging
from PyQt4 import QtCore
from sqlalchemy.exceptions import InvalidRequestError
from openlp.core.utils import AppLocation
from openlp.plugins.alerts.lib.db import init_schema, AlertItem
log = logging.getLogger(__name__)
class DBManager(object):
"""
The Song Manager provides a central location for all database code. This
class takes care of connecting to the database and running all the queries.
"""
log.info(u'Alerts DB loaded')
def __init__(self):
"""
Creates the connection to the database, and creates the tables if they
don't exist.
"""
log.debug(u'Alerts Initialising')
settings = QtCore.QSettings()
settings.beginGroup(u'alerts')
self.db_url = u''
db_type = unicode(
settings.value(u'db type', QtCore.QVariant(u'sqlite')).toString())
if db_type == u'sqlite':
self.db_url = u'sqlite:///%s/alerts.sqlite' % \
AppLocation.get_section_data_path(u'alerts')
else:
self.db_url = u'%s://%s:%s@%s/%s' % (db_type,
unicode(settings.value(u'db username').toString()),
unicode(settings.value(u'db password').toString()),
unicode(settings.value(u'db hostname').toString()),
unicode(settings.value(u'db database').toString()))
settings.endGroup()
self.session = init_schema(self.db_url)
log.debug(u'Alerts Initialised')
def get_all_alerts(self):
"""
Returns the details of a Alert Show
"""
return self.session.query(AlertItem).order_by(AlertItem.text).all()
def save_alert(self, alert_item):
"""
Saves a Alert show to the database
"""
log.debug(u'Alert added')
try:
self.session.add(alert_item)
self.session.commit()
log.debug(u'Alert saved')
return True
except InvalidRequestError:
self.session.rollback()
log.exception(u'Alert save failed')
return False
def get_alert(self, id=None):
"""
Returns the details of a Alert
"""
if id is None:
return AlertItem()
else:
return self.session.query(AlertItem).get(id)
def delete_alert(self, id):
"""
Delete a Alert show
"""
if id != 0:
alert_item = self.get_alert(id)
try:
self.session.delete(alert_item)
self.session.commit()
return True
except InvalidRequestError:
self.session.rollback()
log.exception(u'Alert deleton failed')
return False
else:
return True

View File

@ -30,7 +30,7 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import SongXMLBuilder, SongXMLParser, Receiver, translate from openlp.core.lib import SongXMLBuilder, SongXMLParser, Receiver, translate
from openlp.plugins.songs.forms import EditVerseForm from openlp.plugins.songs.forms import EditVerseForm
from openlp.plugins.songs.lib.db import Song from openlp.plugins.songs.lib.db import Book, Song, Author, Topic
from editsongdialog import Ui_EditSongDialog from editsongdialog import Ui_EditSongDialog
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -125,7 +125,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.TopicRemoveButton.setEnabled(False) self.TopicRemoveButton.setEnabled(False)
def loadAuthors(self): def loadAuthors(self):
authors = self.songmanager.get_authors() authors = self.songmanager.get_all_objects(Author, Author.display_name)
authorsCompleter = QtGui.QCompleter( authorsCompleter = QtGui.QCompleter(
[author.display_name for author in authors], [author.display_name for author in authors],
self.AuthorsSelectionComboItem) self.AuthorsSelectionComboItem)
@ -139,7 +139,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
row, QtCore.QVariant(author.id)) row, QtCore.QVariant(author.id))
def loadTopics(self): def loadTopics(self):
topics = self.songmanager.get_topics() topics = self.songmanager.get_all_objects(Topic, Topic.name)
topicsCompleter = QtGui.QCompleter( topicsCompleter = QtGui.QCompleter(
[topic.name for topic in topics], self.SongTopicCombo) [topic.name for topic in topics], self.SongTopicCombo)
topicsCompleter.setCaseSensitivity(QtCore.Qt.CaseInsensitive) topicsCompleter.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
@ -151,7 +151,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.SongTopicCombo.setItemData(row, QtCore.QVariant(topic.id)) self.SongTopicCombo.setItemData(row, QtCore.QVariant(topic.id))
def loadBooks(self): def loadBooks(self):
books = self.songmanager.get_books() books = self.songmanager.get_all_objects(Book, Book.name)
booksCompleter = QtGui.QCompleter( booksCompleter = QtGui.QCompleter(
[book.name for book in books], self.SongbookCombo) [book.name for book in books], self.SongbookCombo)
booksCompleter.setCaseSensitivity(QtCore.Qt.CaseInsensitive) booksCompleter.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
@ -201,11 +201,12 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.loadAuthors() self.loadAuthors()
self.loadTopics() self.loadTopics()
self.loadBooks() self.loadBooks()
self.song = self.songmanager.get_song(id) self.song = self.songmanager.get_object(Song, id)
self.TitleEditItem.setText(self.song.title) self.TitleEditItem.setText(self.song.title)
title = self.song.search_title.split(u'@') title = self.song.search_title.split(u'@')
if self.song.song_book_id != 0: if self.song.song_book_id != 0:
book_name = self.songmanager.get_book(self.song.song_book_id) book_name = self.songmanager.get_object(Book,
self.song.song_book_id)
id = self.SongbookCombo.findText( id = self.SongbookCombo.findText(
unicode(book_name.name), QtCore.Qt.MatchExactly) unicode(book_name.name), QtCore.Qt.MatchExactly)
if id == -1: if id == -1:
@ -301,7 +302,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
item = int(self.AuthorsSelectionComboItem.currentIndex()) item = int(self.AuthorsSelectionComboItem.currentIndex())
if item > -1: if item > -1:
item_id = (self.AuthorsSelectionComboItem.itemData(item)).toInt()[0] item_id = (self.AuthorsSelectionComboItem.itemData(item)).toInt()[0]
author = self.songmanager.get_author(item_id) author = self.songmanager.get_object(Author, item_id)
self.song.authors.append(author) self.song.authors.append(author)
author_item = QtGui.QListWidgetItem(unicode(author.display_name)) author_item = QtGui.QListWidgetItem(unicode(author.display_name))
author_item.setData(QtCore.Qt.UserRole, QtCore.QVariant(author.id)) author_item.setData(QtCore.Qt.UserRole, QtCore.QVariant(author.id))
@ -315,7 +316,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.AuthorRemoveButton.setEnabled(False) self.AuthorRemoveButton.setEnabled(False)
item = self.AuthorsListView.currentItem() item = self.AuthorsListView.currentItem()
author_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] author_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
author = self.songmanager.get_author(author_id) author = self.songmanager.get_object(Author, author_id)
self.song.authors.remove(author) self.song.authors.remove(author)
row = self.AuthorsListView.row(item) row = self.AuthorsListView.row(item)
self.AuthorsListView.takeItem(row) self.AuthorsListView.takeItem(row)
@ -324,7 +325,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
item = int(self.SongTopicCombo.currentIndex()) item = int(self.SongTopicCombo.currentIndex())
if item > -1: if item > -1:
item_id = (self.SongTopicCombo.itemData(item)).toInt()[0] item_id = (self.SongTopicCombo.itemData(item)).toInt()[0]
topic = self.songmanager.get_topic(item_id) topic = self.songmanager.get_object(Topic, item_id)
self.song.topics.append(topic) self.song.topics.append(topic)
topic_item = QtGui.QListWidgetItem(unicode(topic.name)) topic_item = QtGui.QListWidgetItem(unicode(topic.name))
topic_item.setData(QtCore.Qt.UserRole, QtCore.QVariant(topic.id)) topic_item.setData(QtCore.Qt.UserRole, QtCore.QVariant(topic.id))
@ -337,7 +338,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.TopicRemoveButton.setEnabled(False) self.TopicRemoveButton.setEnabled(False)
item = self.TopicsListView.currentItem() item = self.TopicsListView.currentItem()
topic_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] topic_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
topic = self.songmanager.get_topic(topic_id) topic = self.songmanager.get_object(Topic, topic_id)
self.song.topics.remove(topic) self.song.topics.remove(topic)
row = self.TopicsListView.row(item) row = self.TopicsListView.row(item)
self.TopicsListView.takeItem(row) self.TopicsListView.takeItem(row)
@ -550,7 +551,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.song.ccli_number = unicode(self.CCLNumberEdit.text()) self.song.ccli_number = unicode(self.CCLNumberEdit.text())
self.processLyrics() self.processLyrics()
self.processTitle() self.processTitle()
self.songmanager.save_song(self.song) self.songmanager.insert_object(self.song)
return True return True
def processLyrics(self): def processLyrics(self):
@ -596,4 +597,3 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.song.search_title = self.song.search_title.replace(u'{', u'') self.song.search_title = self.song.search_title.replace(u'{', u'')
self.song.search_title = self.song.search_title.replace(u'}', u'') self.song.search_title = self.song.search_title.replace(u'}', u'')
self.song.search_title = self.song.search_title.replace(u'?', u'') self.song.search_title = self.song.search_title.replace(u'?', u'')

View File

@ -26,11 +26,9 @@
from PyQt4 import QtGui, QtCore from PyQt4 import QtGui, QtCore
from openlp.core.lib import translate from openlp.core.lib import translate
from openlp.plugins.songs.forms import AuthorsForm, TopicsForm, SongBookForm
from openlp.plugins.songs.lib.db import Author, Book, Topic from openlp.plugins.songs.lib.db import Author, Book, Topic
from songmaintenancedialog import Ui_SongMaintenanceDialog from songmaintenancedialog import Ui_SongMaintenanceDialog
from authorsform import AuthorsForm
from topicsform import TopicsForm
from songbookform import SongBookForm
class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog): class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
""" """
@ -81,17 +79,17 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
else: else:
return -1 return -1
def _deleteItem(self, list_widget, get_func, del_func, reset_func, def _deleteItem(self, item_class, list_widget, reset_func, dlg_title,
dlg_title, del_text, err_text, sel_text): del_text, err_text, sel_text):
item_id = self._getCurrentItemId(list_widget) item_id = self._getCurrentItemId(list_widget)
if item_id != -1: if item_id != -1:
item = get_func(item_id) item = self.songmanager.get_object(item_class, item_id)
if item and len(item.songs) == 0: if item and len(item.songs) == 0:
if QtGui.QMessageBox.warning(self, dlg_title, del_text, if QtGui.QMessageBox.warning(self, dlg_title, del_text,
QtGui.QMessageBox.StandardButtons( QtGui.QMessageBox.StandardButtons(
QtGui.QMessageBox.No | QtGui.QMessageBox.Yes) QtGui.QMessageBox.No | QtGui.QMessageBox.Yes)
) == QtGui.QMessageBox.Yes: ) == QtGui.QMessageBox.Yes:
del_func(item.id) self.songmanager.delete_object(item_class, item.id)
reset_func() reset_func()
else: else:
QtGui.QMessageBox.critical(self, dlg_title, err_text) QtGui.QMessageBox.critical(self, dlg_title, err_text)
@ -100,7 +98,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
def resetAuthors(self): def resetAuthors(self):
self.AuthorsListWidget.clear() self.AuthorsListWidget.clear()
authors = self.songmanager.get_authors() authors = self.songmanager.get_all_objects(Author, Author.display_name)
for author in authors: for author in authors:
if author.display_name: if author.display_name:
author_name = QtGui.QListWidgetItem(author.display_name) author_name = QtGui.QListWidgetItem(author.display_name)
@ -112,7 +110,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
def resetTopics(self): def resetTopics(self):
self.TopicsListWidget.clear() self.TopicsListWidget.clear()
topics = self.songmanager.get_topics() topics = self.songmanager.get_all_objects(Topic, Topic.name)
for topic in topics: for topic in topics:
topic_name = QtGui.QListWidgetItem(topic.name) topic_name = QtGui.QListWidgetItem(topic.name)
topic_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(topic.id)) topic_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(topic.id))
@ -120,7 +118,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
def resetBooks(self): def resetBooks(self):
self.BooksListWidget.clear() self.BooksListWidget.clear()
books = self.songmanager.get_books() books = self.songmanager.get_all_objects(Book, Book.name)
for book in books: for book in books:
book_name = QtGui.QListWidgetItem(book.name) book_name = QtGui.QListWidgetItem(book.name)
book_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(book.id)) book_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(book.id))
@ -133,7 +131,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
first_name=unicode(self.authorform.FirstNameEdit.text()), first_name=unicode(self.authorform.FirstNameEdit.text()),
last_name=unicode(self.authorform.LastNameEdit.text()), last_name=unicode(self.authorform.LastNameEdit.text()),
display_name=unicode(self.authorform.DisplayEdit.text())) display_name=unicode(self.authorform.DisplayEdit.text()))
if self.songmanager.save_author(author): if self.songmanager.insert_object(author):
self.resetAuthors() self.resetAuthors()
else: else:
QtGui.QMessageBox.critical( QtGui.QMessageBox.critical(
@ -145,7 +143,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
def onTopicAddButtonClick(self): def onTopicAddButtonClick(self):
if self.topicform.exec_(): if self.topicform.exec_():
topic = Topic.populate(name=unicode(self.topicform.NameEdit.text())) topic = Topic.populate(name=unicode(self.topicform.NameEdit.text()))
if self.songmanager.save_topic(topic): if self.songmanager.insert_object(topic):
self.resetTopics() self.resetTopics()
else: else:
QtGui.QMessageBox.critical( QtGui.QMessageBox.critical(
@ -159,7 +157,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
book = Book.populate( book = Book.populate(
name=unicode(self.bookform.NameEdit.text()), name=unicode(self.bookform.NameEdit.text()),
publisher=unicode(self.bookform.PublisherEdit.text())) publisher=unicode(self.bookform.PublisherEdit.text()))
if self.songmanager.save_book(book): if self.songmanager.insert_object(book):
self.resetBooks() self.resetBooks()
else: else:
QtGui.QMessageBox.critical( QtGui.QMessageBox.critical(
@ -171,7 +169,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
def onAuthorEditButtonClick(self): def onAuthorEditButtonClick(self):
author_id = self._getCurrentItemId(self.AuthorsListWidget) author_id = self._getCurrentItemId(self.AuthorsListWidget)
if author_id != -1: if author_id != -1:
author = self.songmanager.get_author(author_id) author = self.songmanager.get_object(Author, author_id)
self.authorform.setAutoDisplayName(False) self.authorform.setAutoDisplayName(False)
self.authorform.FirstNameEdit.setText(author.first_name) self.authorform.FirstNameEdit.setText(author.first_name)
self.authorform.LastNameEdit.setText(author.last_name) self.authorform.LastNameEdit.setText(author.last_name)
@ -182,7 +180,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
author.last_name = unicode(self.authorform.LastNameEdit.text()) author.last_name = unicode(self.authorform.LastNameEdit.text())
author.display_name = unicode( author.display_name = unicode(
self.authorform.DisplayEdit.text()) self.authorform.DisplayEdit.text())
if self.songmanager.save_author(author): if self.songmanager.insert_object(author):
self.resetAuthors() self.resetAuthors()
else: else:
QtGui.QMessageBox.critical( QtGui.QMessageBox.critical(
@ -194,11 +192,11 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
def onTopicEditButtonClick(self): def onTopicEditButtonClick(self):
topic_id = self._getCurrentItemId(self.TopicsListWidget) topic_id = self._getCurrentItemId(self.TopicsListWidget)
if topic_id != -1: if topic_id != -1:
topic = self.songmanager.get_topic(topic_id) topic = self.songmanager.get_object(Topic, topic_id)
self.topicform.NameEdit.setText(topic.name) self.topicform.NameEdit.setText(topic.name)
if self.topicform.exec_(False): if self.topicform.exec_(False):
topic.name = unicode(self.topicform.NameEdit.text()) topic.name = unicode(self.topicform.NameEdit.text())
if self.songmanager.save_topic(topic): if self.songmanager.insert_object(topic):
self.resetTopics() self.resetTopics()
else: else:
QtGui.QMessageBox.critical( QtGui.QMessageBox.critical(
@ -210,13 +208,13 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
def onBookEditButtonClick(self): def onBookEditButtonClick(self):
book_id = self._getCurrentItemId(self.BooksListWidget) book_id = self._getCurrentItemId(self.BooksListWidget)
if book_id != -1: if book_id != -1:
book = self.songmanager.get_book(book_id) book = self.songmanager.get_object(Book, book_id)
self.bookform.NameEdit.setText(book.name) self.bookform.NameEdit.setText(book.name)
self.bookform.PublisherEdit.setText(book.publisher) self.bookform.PublisherEdit.setText(book.publisher)
if self.bookform.exec_(False): if self.bookform.exec_(False):
book.name = unicode(self.bookform.NameEdit.text()) book.name = unicode(self.bookform.NameEdit.text())
book.publisher = unicode(self.bookform.PublisherEdit.text()) book.publisher = unicode(self.bookform.PublisherEdit.text())
if self.songmanager.save_book(book): if self.songmanager.insert_object(book):
self.resetBooks() self.resetBooks()
else: else:
QtGui.QMessageBox.critical( QtGui.QMessageBox.critical(
@ -229,9 +227,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
""" """
Delete the author if the author is not attached to any songs Delete the author if the author is not attached to any songs
""" """
self._deleteItem( self._deleteItem(Author, self.AuthorsListWidget, self.resetAuthors,
self.AuthorsListWidget, self.songmanager.get_author,
self.songmanager.delete_author, self.resetAuthors,
translate(u'SongsPlugin.SongMaintenanceForm', u'Delete Author'), translate(u'SongsPlugin.SongMaintenanceForm', u'Delete Author'),
translate(u'SongsPlugin.SongMaintenanceForm', translate(u'SongsPlugin.SongMaintenanceForm',
u'Are you sure you want to delete the selected author?'), u'Are you sure you want to delete the selected author?'),
@ -245,9 +241,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
""" """
Delete the Book is the Book is not attached to any songs Delete the Book is the Book is not attached to any songs
""" """
self._deleteItem( self._deleteItem(Topic, self.TopicsListWidget, self.resetTopics,
self.TopicsListWidget, self.songmanager.get_topic,
self.songmanager.delete_topic, self.resetTopics,
translate(u'SongsPlugin.SongMaintenanceForm', u'Delete Topic'), translate(u'SongsPlugin.SongMaintenanceForm', u'Delete Topic'),
translate(u'SongsPlugin.SongMaintenanceForm', translate(u'SongsPlugin.SongMaintenanceForm',
u'Are you sure you want to delete the selected topic?'), u'Are you sure you want to delete the selected topic?'),
@ -261,9 +255,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
""" """
Delete the Book is the Book is not attached to any songs Delete the Book is the Book is not attached to any songs
""" """
self._deleteItem( self._deleteItem(Book, self.BooksListWidget, self.resetBooks,
self.BooksListWidget, self.songmanager.get_book,
self.songmanager.delete_book, self.resetBooks,
translate(u'SongsPlugin.SongMaintenanceForm', u'Delete Book'), translate(u'SongsPlugin.SongMaintenanceForm', u'Delete Book'),
translate(u'SongsPlugin.SongMaintenanceForm', translate(u'SongsPlugin.SongMaintenanceForm',
u'Are you sure you want to delete the selected book?'), u'Are you sure you want to delete the selected book?'),

View File

@ -25,10 +25,7 @@
import logging import logging
from PyQt4 import QtCore from openlp.core.lib.db import Manager
from sqlalchemy.exceptions import InvalidRequestError
from openlp.core.utils import AppLocation
from openlp.plugins.songs.lib.db import init_schema, Song, Author, Topic, Book from openlp.plugins.songs.lib.db import init_schema, Song, Author, Topic, Book
#from openlp.plugins.songs.lib import OpenLyricsSong, OpenSongSong, CCLISong, \ #from openlp.plugins.songs.lib import OpenLyricsSong, OpenSongSong, CCLISong, \
# CSVSong # CSVSong
@ -79,7 +76,7 @@ class SongFormat(object):
] ]
class SongManager(object): class SongManager(Manager):
""" """
The Song Manager provides a central location for all database code. This The Song Manager provides a central location for all database code. This
class takes care of connecting to the database and running all the queries. class takes care of connecting to the database and running all the queries.
@ -92,34 +89,9 @@ class SongManager(object):
don't exist. don't exist.
""" """
log.debug(u'Song Initialising') log.debug(u'Song Initialising')
settings = QtCore.QSettings() Manager.__init__(self, u'songs', init_schema)
settings.beginGroup(u'songs')
self.db_url = u''
db_type = unicode(settings.value(u'songs/db type',
QtCore.QVariant(u'sqlite')).toString())
if db_type == u'sqlite':
self.db_url = u'sqlite:///%s/songs.sqlite' % \
AppLocation.get_section_data_path(u'songs')
else:
self.db_url = u'%s://%s:%s@%s/%s' % (db_type,
unicode(settings.value(
u'db username', QtCore.QVariant(u'')).toString()),
unicode(settings.value(
u'db password', QtCore.QVariant(u'')).toString()),
unicode(settings.value(
u'db hostname', QtCore.QVariant(u'')).toString()),
unicode(settings.value(
u'db database', QtCore.QVariant(u'')).toString()))
self.session = init_schema(self.db_url)
settings.endGroup()
log.debug(u'Song Initialised') log.debug(u'Song Initialised')
def get_songs(self):
"""
Returns the details of a song
"""
return self.session.query(Song).order_by(Song.title).all()
def search_song_title(self, keywords): def search_song_title(self, keywords):
""" """
Searches the song title for keywords. Searches the song title for keywords.
@ -143,174 +115,23 @@ class SongManager(object):
return self.session.query(Author).filter(Author.display_name.like( return self.session.query(Author).filter(Author.display_name.like(
u'%' + keywords + u'%')).order_by(Author.display_name.asc()).all() u'%' + keywords + u'%')).order_by(Author.display_name.asc()).all()
def get_song(self, id=None):
"""
Returns the details of a song
"""
if id is None:
return Song()
else:
return self.session.query(Song).get(id)
def save_song(self, song):
"""
Saves a song to the database
"""
try:
self.session.add(song)
self.session.commit()
return True
except InvalidRequestError:
log.exception(u'Could not save song to song database')
self.session.rollback()
return False
def delete_song(self, songid):
song = self.get_song(songid)
try:
self.session.delete(song)
self.session.commit()
return True
except InvalidRequestError:
self.session.rollback()
log.exception(u'Could not delete song from song database')
return False
def get_authors(self):
"""
Returns a list of all the authors
"""
return self.session.query(Author).order_by(Author.display_name).all()
def get_author(self, id):
"""
Details of the Author
"""
return self.session.query(Author).get(id)
def get_author_by_name(self, name): def get_author_by_name(self, name):
""" """
Get author by display name Get author by display name
""" """
return self.session.query(Author).filter_by(display_name=name).first() return self.session.query(Author).filter_by(display_name=name).first()
def save_author(self, author):
"""
Save the Author and refresh the cache
"""
try:
self.session.add(author)
self.session.commit()
return True
except InvalidRequestError:
self.session.rollback()
log.exception(u'Could not save author to song database')
return False
def delete_author(self, authorid):
"""
Delete the author
"""
author = self.get_author(authorid)
try:
self.session.delete(author)
self.session.commit()
return True
except InvalidRequestError:
self.session.rollback()
log.exception(u'Could not delete author from song database')
return False
def get_topics(self):
"""
Returns a list of all the topics
"""
return self.session.query(Topic).order_by(Topic.name).all()
def get_topic(self, id):
"""
Details of the Topic
"""
return self.session.query(Topic).get(id)
def get_topic_by_name(self, name): def get_topic_by_name(self, name):
""" """
Get topic by name Get topic by name
""" """
return self.session.query(Topic).filter_by(name=name).first() return self.session.query(Topic).filter_by(name=name).first()
def save_topic(self, topic):
"""
Save the Topic
"""
try:
self.session.add(topic)
self.session.commit()
return True
except InvalidRequestError:
self.session.rollback()
log.exception(u'Could not save topic to song database')
return False
def delete_topic(self, topicid):
"""
Delete the topic
"""
topic = self.get_topic(topicid)
try:
self.session.delete(topic)
self.session.commit()
return True
except InvalidRequestError:
self.session.rollback()
log.exception(u'Could not delete topic from song database')
return False
def get_books(self):
"""
Returns a list of all the Books
"""
return self.session.query(Book).order_by(Book.name).all()
def get_book(self, id):
"""
Details of the Books
"""
return self.session.query(Book).get(id)
def get_book_by_name(self, name): def get_book_by_name(self, name):
""" """
Get book by name Get book by name
""" """
return self.session.query(Book).filter_by(name=name).first() return self.session.query(Book).filter_by(name=name).first()
def save_book(self, book):
"""
Save the Book
"""
try:
self.session.add(book)
self.session.commit()
return True
except InvalidRequestError:
self.session.rollback()
log.exception(u'Could not save book to song database')
return False
def delete_book(self, bookid):
"""
Delete the Book
"""
book = self.get_book(bookid)
try:
self.session.delete(book)
self.session.commit()
return True
except InvalidRequestError:
self.session.rollback()
log.exception(u'Could not delete book from song database')
return False
def get_songs_for_theme(self, theme): def get_songs_for_theme(self, theme):
return self.session.query(Song).filter(Song.theme_name == theme).all() return self.session.query(Song).filter(Song.theme_name == theme).all()

View File

@ -31,6 +31,7 @@ from openlp.core.lib import MediaManagerItem, SongXMLParser, \
BaseListWithDnD, Receiver, ItemCapabilities, translate BaseListWithDnD, Receiver, ItemCapabilities, translate
from openlp.plugins.songs.forms import EditSongForm, SongMaintenanceForm, \ from openlp.plugins.songs.forms import EditSongForm, SongMaintenanceForm, \
ImportWizardForm ImportWizardForm
from openlp.plugins.songs.lib.db import Song
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -267,7 +268,7 @@ class SongMediaItem(MediaManagerItem):
type of display is required. type of display is required.
""" """
fields = songid.split(u':') fields = songid.split(u':')
valid = self.parent.manager.get_song(fields[1]) valid = self.parent.manager.get_object(Song, fields[1])
if valid: if valid:
self.remoteSong = fields[1] self.remoteSong = fields[1]
self.remoteTriggered = fields[0] self.remoteTriggered = fields[0]
@ -301,7 +302,7 @@ class SongMediaItem(MediaManagerItem):
return return
for item in items: for item in items:
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
self.parent.manager.delete_song(item_id) self.parent.manager.delete_object(Song, item_id)
self.onSearchTextButtonClick() self.onSearchTextButtonClick()
def generateSlideData(self, service_item, item=None): def generateSlideData(self, service_item, item=None):
@ -322,7 +323,7 @@ class SongMediaItem(MediaManagerItem):
service_item.add_capability(ItemCapabilities.AllowsEdit) service_item.add_capability(ItemCapabilities.AllowsEdit)
service_item.add_capability(ItemCapabilities.AllowsPreview) service_item.add_capability(ItemCapabilities.AllowsPreview)
service_item.add_capability(ItemCapabilities.AllowsLoop) service_item.add_capability(ItemCapabilities.AllowsLoop)
song = self.parent.manager.get_song(item_id) song = self.parent.manager.get_object(Song, item_id)
service_item.theme = song.theme_name service_item.theme = song.theme_name
service_item.editId = item_id service_item.editId = item_id
if song.lyrics.startswith(u'<?xml version='): if song.lyrics.startswith(u'<?xml version='):

View File

@ -322,7 +322,7 @@ class SongImport(object):
author.display_name = authortext author.display_name = authortext
author.last_name = authortext.split(u' ')[-1] author.last_name = authortext.split(u' ')[-1]
author.first_name = u' '.join(authortext.split(u' ')[:-1]) author.first_name = u' '.join(authortext.split(u' ')[:-1])
self.manager.save_author(author) self.manager.insert_object(author)
song.authors.append(author) song.authors.append(author)
if self.song_book_name: if self.song_book_name:
song_book = self.manager.get_book_by_name(self.song_book_name) song_book = self.manager.get_book_by_name(self.song_book_name)
@ -330,16 +330,16 @@ class SongImport(object):
song_book = Book() song_book = Book()
song_book.name = self.song_book_name song_book.name = self.song_book_name
song_book.publisher = self.song_book_pub song_book.publisher = self.song_book_pub
self.manager.save_book(song_book) self.manager.insert_object(song_book)
song.song_book_id = song_book.id song.song_book_id = song_book.id
for topictext in self.topics: for topictext in self.topics:
topic = self.manager.get_topic_by_name(topictext) topic = self.manager.get_topic_by_name(topictext)
if topic is None: if topic is None:
topic = Topic() topic = Topic()
topic.name = topictext topic.name = topictext
self.manager.save_topic(topic) self.manager.insert_object(topic)
song.topics.append(topictext) song.topics.append(topictext)
self.manager.save_song(song) self.manager.insert_object(song)
def print_song(self): def print_song(self):
""" """

View File

@ -31,6 +31,7 @@ from openlp.core.lib import Plugin, build_icon, PluginStatus, Receiver, \
translate translate
from openlp.plugins.songs.lib import SongManager, SongMediaItem, SongsTab, \ from openlp.plugins.songs.lib import SongManager, SongMediaItem, SongsTab, \
SofImport, OooImport SofImport, OooImport
from openlp.plugins.songs.lib.db import Song
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -65,7 +66,8 @@ class SongsPlugin(Plugin):
self.insert_toolbox_item() self.insert_toolbox_item()
#self.ImportSongMenu.menuAction().setVisible(True) #self.ImportSongMenu.menuAction().setVisible(True)
#self.ExportSongMenu.menuAction().setVisible(True) #self.ExportSongMenu.menuAction().setVisible(True)
self.media_item.displayResultsSong(self.manager.get_songs()) self.media_item.displayResultsSong(
self.manager.get_all_objects(Song, Song.title))
def finalise(self): def finalise(self):
log.info(u'Plugin Finalise') log.info(u'Plugin Finalise')