forked from openlp/openlp
Refactor database code
bzr-revno: 894
This commit is contained in:
commit
19ff5dec55
@ -22,7 +22,6 @@
|
|||||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
"""
|
"""
|
||||||
The :mod:`lib` module contains most of the components and libraries that make
|
The :mod:`lib` module contains most of the components and libraries that make
|
||||||
OpenLP work.
|
OpenLP work.
|
||||||
@ -47,6 +46,10 @@ def translate(context, text, comment=None):
|
|||||||
|
|
||||||
``text``
|
``text``
|
||||||
The text to put into the translation tables for translation.
|
The text to put into the translation tables for translation.
|
||||||
|
|
||||||
|
``comment``
|
||||||
|
An identifying string for when the same text is used in different roles
|
||||||
|
within the same context.
|
||||||
"""
|
"""
|
||||||
return QtCore.QCoreApplication.translate(context, text, comment)
|
return QtCore.QCoreApplication.translate(context, text, comment)
|
||||||
|
|
||||||
@ -115,6 +118,18 @@ def build_icon(icon):
|
|||||||
def context_menu_action(base, icon, text, slot):
|
def context_menu_action(base, icon, text, slot):
|
||||||
"""
|
"""
|
||||||
Utility method to help build context menus for plugins
|
Utility method to help build context menus for plugins
|
||||||
|
|
||||||
|
``base``
|
||||||
|
The parent menu to add this menu item to
|
||||||
|
|
||||||
|
``icon``
|
||||||
|
An icon for this action
|
||||||
|
|
||||||
|
``text``
|
||||||
|
The text to display for this action
|
||||||
|
|
||||||
|
``slot``
|
||||||
|
The code to run when this action is triggered
|
||||||
"""
|
"""
|
||||||
action = QtGui.QAction(text, base)
|
action = QtGui.QAction(text, base)
|
||||||
if icon:
|
if icon:
|
||||||
@ -125,6 +140,15 @@ def context_menu_action(base, icon, text, slot):
|
|||||||
def context_menu(base, icon, text):
|
def context_menu(base, icon, text):
|
||||||
"""
|
"""
|
||||||
Utility method to help build context menus for plugins
|
Utility method to help build context menus for plugins
|
||||||
|
|
||||||
|
``base``
|
||||||
|
The parent object to add this menu to
|
||||||
|
|
||||||
|
``icon``
|
||||||
|
An icon for this menu
|
||||||
|
|
||||||
|
``text``
|
||||||
|
The text to display for this menu
|
||||||
"""
|
"""
|
||||||
action = QtGui.QMenu(text, base)
|
action = QtGui.QMenu(text, base)
|
||||||
action.setIcon(build_icon(icon))
|
action.setIcon(build_icon(icon))
|
||||||
@ -133,6 +157,9 @@ def context_menu(base, icon, text):
|
|||||||
def context_menu_separator(base):
|
def context_menu_separator(base):
|
||||||
"""
|
"""
|
||||||
Add a separator to a context menu
|
Add a separator to a context menu
|
||||||
|
|
||||||
|
``base``
|
||||||
|
The menu object to add the separator to
|
||||||
"""
|
"""
|
||||||
action = QtGui.QAction(u'', base)
|
action = QtGui.QAction(u'', base)
|
||||||
action.setSeparator(True)
|
action.setSeparator(True)
|
||||||
@ -200,5 +227,4 @@ from themexmlhandler import ThemeXML
|
|||||||
from renderer import Renderer
|
from renderer import Renderer
|
||||||
from rendermanager import RenderManager
|
from rendermanager import RenderManager
|
||||||
from mediamanageritem import MediaManagerItem
|
from mediamanageritem import MediaManagerItem
|
||||||
from basemodel import BaseModel
|
|
||||||
from baselistwithdnd import BaseListWithDnD
|
from baselistwithdnd import BaseListWithDnD
|
||||||
|
@ -1,40 +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 #
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
class BaseModel(object):
|
|
||||||
"""
|
|
||||||
BaseModel provides a base object with a set of generic functions
|
|
||||||
"""
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def populate(cls, **kwargs):
|
|
||||||
"""
|
|
||||||
Creates an instance of a class and populates it, returning the instance
|
|
||||||
"""
|
|
||||||
me = cls()
|
|
||||||
for key in kwargs:
|
|
||||||
me.__setattr__(key, kwargs[key])
|
|
||||||
return me
|
|
||||||
|
|
245
openlp/core/lib/db.py
Normal file
245
openlp/core/lib/db.py
Normal file
@ -0,0 +1,245 @@
|
|||||||
|
# -*- 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:`db` module provides the core database functionality for OpenLP
|
||||||
|
"""
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
|
||||||
|
from PyQt4 import QtCore
|
||||||
|
from sqlalchemy import create_engine, MetaData
|
||||||
|
from sqlalchemy.exceptions import InvalidRequestError
|
||||||
|
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):
|
||||||
|
"""
|
||||||
|
Initialise and return the session and metadata for a database
|
||||||
|
|
||||||
|
``url``
|
||||||
|
The database to initialise connection with
|
||||||
|
|
||||||
|
``auto_flush``
|
||||||
|
Sets the flushing behaviour of the session
|
||||||
|
|
||||||
|
``auto_commit``
|
||||||
|
Sets the commit behaviour of the session
|
||||||
|
"""
|
||||||
|
engine = create_engine(url)
|
||||||
|
metadata = MetaData(bind=engine)
|
||||||
|
session = scoped_session(sessionmaker(autoflush=auto_flush,
|
||||||
|
autocommit=auto_commit, bind=engine))
|
||||||
|
return session, metadata
|
||||||
|
|
||||||
|
def delete_database(plugin_name, db_file_name=None):
|
||||||
|
"""
|
||||||
|
Remove a database file from the system.
|
||||||
|
|
||||||
|
``plugin_name``
|
||||||
|
The name of the plugin to remove the database for
|
||||||
|
|
||||||
|
``db_file_name``
|
||||||
|
The database file name. Defaults to None resulting in the
|
||||||
|
plugin_name being used.
|
||||||
|
"""
|
||||||
|
db_file_path = None
|
||||||
|
if db_file_name:
|
||||||
|
db_file_path = os.path.join(
|
||||||
|
AppLocation.get_section_data_path(plugin_name), db_file_name)
|
||||||
|
else:
|
||||||
|
db_file_path = os.path.join(
|
||||||
|
AppLocation.get_section_data_path(plugin_name), plugin_name)
|
||||||
|
try:
|
||||||
|
os.remove(db_file_path)
|
||||||
|
return True
|
||||||
|
except OSError:
|
||||||
|
return False
|
||||||
|
|
||||||
|
class BaseModel(object):
|
||||||
|
"""
|
||||||
|
BaseModel provides a base object with a set of generic functions
|
||||||
|
"""
|
||||||
|
@classmethod
|
||||||
|
def populate(cls, **kwargs):
|
||||||
|
"""
|
||||||
|
Creates an instance of a class and populates it, returning the instance
|
||||||
|
"""
|
||||||
|
me = cls()
|
||||||
|
for key in kwargs:
|
||||||
|
me.__setattr__(key, kwargs[key])
|
||||||
|
return me
|
||||||
|
|
||||||
|
class Manager(object):
|
||||||
|
"""
|
||||||
|
Provide generic object persistence management
|
||||||
|
"""
|
||||||
|
def __init__(self, plugin_name, init_schema, db_file_name=None):
|
||||||
|
"""
|
||||||
|
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
|
||||||
|
|
||||||
|
``init_schema``
|
||||||
|
The init_schema function for this database
|
||||||
|
|
||||||
|
``db_file_name``
|
||||||
|
The file name to use for this database. Defaults to None resulting
|
||||||
|
in the plugin_name being used.
|
||||||
|
"""
|
||||||
|
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':
|
||||||
|
if db_file_name:
|
||||||
|
self.db_url = u'sqlite:///%s/%s' % (
|
||||||
|
AppLocation.get_section_data_path(plugin_name),
|
||||||
|
db_file_name)
|
||||||
|
else:
|
||||||
|
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 save_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, key=None):
|
||||||
|
"""
|
||||||
|
Return the details of an object
|
||||||
|
|
||||||
|
``object_class``
|
||||||
|
The type of object to return
|
||||||
|
|
||||||
|
``key``
|
||||||
|
The unique reference or primary key for the instance to return
|
||||||
|
"""
|
||||||
|
if not key:
|
||||||
|
return object_class()
|
||||||
|
else:
|
||||||
|
return self.session.query(object_class).get(key)
|
||||||
|
|
||||||
|
def get_object_filtered(self, object_class, filter_string):
|
||||||
|
"""
|
||||||
|
Returns an object matching specified criteria
|
||||||
|
|
||||||
|
``object_class``
|
||||||
|
The type of object to return
|
||||||
|
|
||||||
|
``filter_string``
|
||||||
|
The criteria to select the object by
|
||||||
|
"""
|
||||||
|
return self.session.query(object_class).filter(filter_string).first()
|
||||||
|
|
||||||
|
def get_all_objects(self, object_class, order_by_ref=None):
|
||||||
|
"""
|
||||||
|
Returns all the objects from the database
|
||||||
|
|
||||||
|
``object_class``
|
||||||
|
The type of objects 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 get_all_objects_filtered(self, object_class, filter_string):
|
||||||
|
"""
|
||||||
|
Returns a selection of objects from the database
|
||||||
|
|
||||||
|
``object_class``
|
||||||
|
The type of objects to return
|
||||||
|
|
||||||
|
``filter_string``
|
||||||
|
The filter governing selection of objects to return
|
||||||
|
"""
|
||||||
|
return self.session.query(object_class).filter(filter_string).all()
|
||||||
|
|
||||||
|
def delete_object(self, object_class, key):
|
||||||
|
"""
|
||||||
|
Delete an object from the database
|
||||||
|
|
||||||
|
``object_class``
|
||||||
|
The type of object to delete
|
||||||
|
|
||||||
|
``key``
|
||||||
|
The unique reference or primary key for the instance to be deleted
|
||||||
|
"""
|
||||||
|
if key != 0:
|
||||||
|
object_instance = self.get_object(object_class, key)
|
||||||
|
try:
|
||||||
|
self.session.delete(object_instance)
|
||||||
|
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
|
@ -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,11 +43,14 @@ 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
|
||||||
|
|
||||||
def get_settings_tab(self):
|
def get_settings_tab(self):
|
||||||
|
"""
|
||||||
|
Return the settings tab for the Alerts plugin
|
||||||
|
"""
|
||||||
self.alertsTab = AlertsTab(self)
|
self.alertsTab = AlertsTab(self)
|
||||||
return self.alertsTab
|
return self.alertsTab
|
||||||
|
|
||||||
|
@ -25,8 +25,8 @@
|
|||||||
|
|
||||||
from PyQt4 import QtGui, QtCore
|
from PyQt4 import QtGui, QtCore
|
||||||
|
|
||||||
from openlp.plugins.alerts.lib.models import AlertItem
|
|
||||||
from openlp.core.lib import translate
|
from openlp.core.lib import translate
|
||||||
|
from openlp.plugins.alerts.lib.db import AlertItem
|
||||||
|
|
||||||
from alertdialog import Ui_AlertDialog
|
from alertdialog import Ui_AlertDialog
|
||||||
|
|
||||||
@ -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,7 +98,7 @@ 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.save_object(alert)
|
||||||
self.AlertTextEdit.setText(u'')
|
self.AlertTextEdit.setText(u'')
|
||||||
self.loadList()
|
self.loadList()
|
||||||
|
|
||||||
@ -107,9 +107,9 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
|
|||||||
Save an alert
|
Save an alert
|
||||||
"""
|
"""
|
||||||
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.save_object(alert)
|
||||||
self.item_id = None
|
self.item_id = None
|
||||||
self.loadList()
|
self.loadList()
|
||||||
else:
|
else:
|
||||||
|
@ -25,4 +25,3 @@
|
|||||||
|
|
||||||
from alertsmanager import AlertsManager
|
from alertsmanager import AlertsManager
|
||||||
from alertstab import AlertsTab
|
from alertstab import AlertsTab
|
||||||
from manager import DBManager
|
|
||||||
|
@ -1,32 +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 #
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
from openlp.core.lib import BaseModel
|
|
||||||
|
|
||||||
class AlertItem(BaseModel):
|
|
||||||
"""
|
|
||||||
Custom Slide model
|
|
||||||
"""
|
|
||||||
pass
|
|
@ -22,18 +22,36 @@
|
|||||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
"""
|
||||||
|
The :mod:`db` module provides the database and schema that is the backend for
|
||||||
|
the Alerts plugin
|
||||||
|
"""
|
||||||
|
|
||||||
from sqlalchemy import create_engine
|
from sqlalchemy import Column, Table, types
|
||||||
from sqlalchemy.orm import scoped_session, sessionmaker, mapper
|
from sqlalchemy.orm import mapper
|
||||||
|
|
||||||
from openlp.plugins.alerts.lib.meta import metadata
|
from openlp.core.lib.db import BaseModel, init_db
|
||||||
from openlp.plugins.alerts.lib.tables import *
|
|
||||||
from openlp.plugins.alerts.lib.classes import *
|
class AlertItem(BaseModel):
|
||||||
|
"""
|
||||||
|
AlertItem model
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def init_schema(url):
|
||||||
|
"""
|
||||||
|
Setup the alerts database connection and initialise the database schema
|
||||||
|
|
||||||
|
``url``
|
||||||
|
The database to setup
|
||||||
|
"""
|
||||||
|
session, metadata = init_db(url)
|
||||||
|
|
||||||
|
alerts_table = Table(u'alerts', metadata,
|
||||||
|
Column(u'id', types.Integer(), primary_key=True),
|
||||||
|
Column(u'text', types.UnicodeText, nullable=False))
|
||||||
|
|
||||||
def init_models(url):
|
|
||||||
engine = create_engine(url)
|
|
||||||
metadata.bind = engine
|
|
||||||
session = scoped_session(sessionmaker(autoflush=True, autocommit=False,
|
|
||||||
bind=engine))
|
|
||||||
mapper(AlertItem, alerts_table)
|
mapper(AlertItem, alerts_table)
|
||||||
|
|
||||||
|
metadata.create_all(checkfirst=True)
|
||||||
return session
|
return session
|
@ -1,114 +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.models import init_models, metadata, 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_models(self.db_url)
|
|
||||||
metadata.create_all(checkfirst=True)
|
|
||||||
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
|
|
||||||
|
|
@ -1,38 +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 #
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
from sqlalchemy import MetaData
|
|
||||||
|
|
||||||
__all__ = ['session', 'metadata', 'engine']
|
|
||||||
|
|
||||||
# SQLAlchemy database engine. Updated by model.init_model()
|
|
||||||
engine = None
|
|
||||||
|
|
||||||
# SQLAlchemy session manager. Updated by model.init_model()
|
|
||||||
session = None
|
|
||||||
|
|
||||||
# Global metadata. If you have multiple databases with overlapping table
|
|
||||||
# names, you'll need a metadata for each database
|
|
||||||
metadata = MetaData()
|
|
@ -1,33 +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 #
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
from sqlalchemy import Column, Table, types
|
|
||||||
|
|
||||||
from openlp.plugins.alerts.lib.meta import metadata
|
|
||||||
|
|
||||||
# Definition of the "alerts" table
|
|
||||||
alerts_table = Table(u'alerts', metadata,
|
|
||||||
Column(u'id', types.Integer(), primary_key=True),
|
|
||||||
Column(u'text', types.UnicodeText, nullable=False))
|
|
@ -32,6 +32,7 @@ from PyQt4 import QtCore, QtGui
|
|||||||
|
|
||||||
from bibleimportwizard import Ui_BibleImportWizard
|
from bibleimportwizard import Ui_BibleImportWizard
|
||||||
from openlp.core.lib import Receiver, SettingsManager, translate
|
from openlp.core.lib import Receiver, SettingsManager, translate
|
||||||
|
from openlp.core.lib.db import delete_database
|
||||||
from openlp.core.utils import AppLocation
|
from openlp.core.utils import AppLocation
|
||||||
from openlp.plugins.bibles.lib.manager import BibleFormat
|
from openlp.plugins.bibles.lib.manager import BibleFormat
|
||||||
|
|
||||||
@ -224,7 +225,7 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
|
|||||||
Show the file open dialog for the OSIS file.
|
Show the file open dialog for the OSIS file.
|
||||||
"""
|
"""
|
||||||
self.getFileName(
|
self.getFileName(
|
||||||
translate('BiblesPlugin.ImportWizardForm', 'Open OSIS File'),
|
translate('BiblesPlugin.ImportWizardForm', 'Open OSIS File'),
|
||||||
self.OSISLocationEdit)
|
self.OSISLocationEdit)
|
||||||
|
|
||||||
def onBooksFileButtonClicked(self):
|
def onBooksFileButtonClicked(self):
|
||||||
@ -239,10 +240,8 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
|
|||||||
"""
|
"""
|
||||||
Show the file open dialog for the verses CSV file.
|
Show the file open dialog for the verses CSV file.
|
||||||
"""
|
"""
|
||||||
self.getFileName(
|
self.getFileName(translate('BiblesPlugin.ImportWizardForm',
|
||||||
translate('BiblesPlugin.ImportWizardForm',
|
'Open Verses CSV File'), self.CsvVerseLocationEdit)
|
||||||
'Open Verses CSV File'),
|
|
||||||
self.CsvVerseLocationEdit)
|
|
||||||
|
|
||||||
def onOpenSongBrowseButtonClicked(self):
|
def onOpenSongBrowseButtonClicked(self):
|
||||||
"""
|
"""
|
||||||
@ -451,7 +450,7 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
|
|||||||
self.ImportProgressLabel.setText(
|
self.ImportProgressLabel.setText(
|
||||||
translate('BiblesPlugin.ImportWizardForm',
|
translate('BiblesPlugin.ImportWizardForm',
|
||||||
'Your Bible import failed.'))
|
'Your Bible import failed.'))
|
||||||
importer.delete()
|
delete_database(self.bibleplugin.settingsSection, importer.file)
|
||||||
|
|
||||||
def postImport(self):
|
def postImport(self):
|
||||||
self.ImportProgressBar.setValue(self.ImportProgressBar.maximum())
|
self.ImportProgressBar.setValue(self.ImportProgressBar.maximum())
|
||||||
|
@ -97,11 +97,11 @@ class CSVBible(BibleDB):
|
|||||||
book_ptr = book.name
|
book_ptr = book.name
|
||||||
self.wizard.incrementProgressBar(
|
self.wizard.incrementProgressBar(
|
||||||
u'Importing %s %s' % (book.name, line[1]))
|
u'Importing %s %s' % (book.name, line[1]))
|
||||||
self.commit()
|
self.session.commit()
|
||||||
self.create_verse(book.id, line[1], line[2],
|
self.create_verse(book.id, line[1], line[2],
|
||||||
unicode(line[3], details['encoding']))
|
unicode(line[3], details['encoding']))
|
||||||
Receiver.send_message(u'openlp_process_events')
|
Receiver.send_message(u'openlp_process_events')
|
||||||
self.commit()
|
self.session.commit()
|
||||||
except IOError:
|
except IOError:
|
||||||
log.exception(u'Loading verses from file failed')
|
log.exception(u'Loading verses from file failed')
|
||||||
success = False
|
success = False
|
||||||
@ -113,5 +113,3 @@ class CSVBible(BibleDB):
|
|||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
return success
|
return success
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,20 +23,99 @@
|
|||||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
import os
|
|
||||||
import logging
|
import logging
|
||||||
import chardet
|
import chardet
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from sqlalchemy import or_
|
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
|
from sqlalchemy import Column, ForeignKey, or_, Table, types
|
||||||
|
from sqlalchemy.orm import class_mapper, mapper, relation
|
||||||
|
from sqlalchemy.orm.exc import UnmappedClassError
|
||||||
|
|
||||||
from openlp.core.lib import translate
|
from openlp.core.lib import translate
|
||||||
from openlp.plugins.bibles.lib.models import *
|
from openlp.core.lib.db import BaseModel, init_db, Manager
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
class BibleDB(QtCore.QObject):
|
class BibleMeta(BaseModel):
|
||||||
|
"""
|
||||||
|
Bible Meta Data
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
class Testament(BaseModel):
|
||||||
|
"""
|
||||||
|
Bible Testaments
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
class Book(BaseModel):
|
||||||
|
"""
|
||||||
|
Song model
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
class Verse(BaseModel):
|
||||||
|
"""
|
||||||
|
Topic model
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def init_schema(url):
|
||||||
|
"""
|
||||||
|
Setup a bible database connection and initialise the database schema
|
||||||
|
|
||||||
|
``url``
|
||||||
|
The database to setup
|
||||||
|
"""
|
||||||
|
session, metadata = init_db(url)
|
||||||
|
|
||||||
|
meta_table = Table(u'metadata', metadata,
|
||||||
|
Column(u'key', types.Unicode(255), primary_key=True, index=True),
|
||||||
|
Column(u'value', types.Unicode(255)),
|
||||||
|
)
|
||||||
|
testament_table = Table(u'testament', metadata,
|
||||||
|
Column(u'id', types.Integer, primary_key=True),
|
||||||
|
Column(u'name', types.Unicode(50)),
|
||||||
|
)
|
||||||
|
book_table = Table(u'book', metadata,
|
||||||
|
Column(u'id', types.Integer, primary_key=True),
|
||||||
|
Column(u'testament_id', types.Integer, ForeignKey(u'testament.id')),
|
||||||
|
Column(u'name', types.Unicode(50), index=True),
|
||||||
|
Column(u'abbreviation', types.Unicode(5), index=True),
|
||||||
|
)
|
||||||
|
verse_table = Table(u'verse', metadata,
|
||||||
|
Column(u'id', types.Integer, primary_key=True, index=True),
|
||||||
|
Column(u'book_id', types.Integer, ForeignKey(u'book.id'), index=True),
|
||||||
|
Column(u'chapter', types.Integer, index=True),
|
||||||
|
Column(u'verse', types.Integer, index=True),
|
||||||
|
Column(u'text', types.UnicodeText, index=True),
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
class_mapper(BibleMeta)
|
||||||
|
except UnmappedClassError:
|
||||||
|
mapper(BibleMeta, meta_table)
|
||||||
|
try:
|
||||||
|
class_mapper(Testament)
|
||||||
|
except UnmappedClassError:
|
||||||
|
mapper(Testament, testament_table,
|
||||||
|
properties={'books': relation(Book, backref='testament')})
|
||||||
|
try:
|
||||||
|
class_mapper(Book)
|
||||||
|
except UnmappedClassError:
|
||||||
|
mapper(Book, book_table,
|
||||||
|
properties={'verses': relation(Verse, backref='book')})
|
||||||
|
try:
|
||||||
|
class_mapper(Verse)
|
||||||
|
except UnmappedClassError:
|
||||||
|
mapper(Verse, verse_table)
|
||||||
|
|
||||||
|
metadata.create_all(checkfirst=True)
|
||||||
|
return session
|
||||||
|
|
||||||
|
|
||||||
|
class BibleDB(QtCore.QObject, Manager):
|
||||||
"""
|
"""
|
||||||
This class represents a database-bound Bible. It is used as a base class
|
This class represents a database-bound Bible. It is used as a base class
|
||||||
for all the custom importers, so that the can implement their own import
|
for all the custom importers, so that the can implement their own import
|
||||||
@ -73,26 +152,10 @@ class BibleDB(QtCore.QObject):
|
|||||||
self.file = self.clean_filename(self.name)
|
self.file = self.clean_filename(self.name)
|
||||||
if u'file' in kwargs:
|
if u'file' in kwargs:
|
||||||
self.file = kwargs[u'file']
|
self.file = kwargs[u'file']
|
||||||
self.db_file = os.path.join(kwargs[u'path'], self.file)
|
Manager.__init__(self, u'bibles', init_schema, self.file)
|
||||||
log.debug(u'Load bible %s on path %s', self.file, self.db_file)
|
|
||||||
settings = QtCore.QSettings()
|
|
||||||
settings.beginGroup(u'bibles')
|
|
||||||
db_type = unicode(
|
|
||||||
settings.value(u'db type', QtCore.QVariant(u'sqlite')).toString())
|
|
||||||
db_url = u''
|
|
||||||
if db_type == u'sqlite':
|
|
||||||
db_url = u'sqlite:///' + self.db_file
|
|
||||||
else:
|
|
||||||
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_models(db_url)
|
|
||||||
metadata.create_all(checkfirst=True)
|
|
||||||
if u'file' in kwargs:
|
if u'file' in kwargs:
|
||||||
self.get_name()
|
self.get_name()
|
||||||
|
self.wizard = None
|
||||||
|
|
||||||
def stop_import(self):
|
def stop_import(self):
|
||||||
"""
|
"""
|
||||||
@ -105,7 +168,7 @@ class BibleDB(QtCore.QObject):
|
|||||||
"""
|
"""
|
||||||
Returns the version name of the Bible.
|
Returns the version name of the Bible.
|
||||||
"""
|
"""
|
||||||
version_name = self.get_meta(u'Version')
|
version_name = self.get_object(BibleMeta, u'Version')
|
||||||
if version_name:
|
if version_name:
|
||||||
self.name = version_name.value
|
self.name = version_name.value
|
||||||
else:
|
else:
|
||||||
@ -125,16 +188,6 @@ class BibleDB(QtCore.QObject):
|
|||||||
old_filename = re.sub(r'[^\w]+', u'_', old_filename).strip(u'_')
|
old_filename = re.sub(r'[^\w]+', u'_', old_filename).strip(u'_')
|
||||||
return old_filename + u'.sqlite'
|
return old_filename + u'.sqlite'
|
||||||
|
|
||||||
def delete(self):
|
|
||||||
"""
|
|
||||||
Remove the Bible database file. Used when a Bible import fails.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
os.remove(self.db_file)
|
|
||||||
return True
|
|
||||||
except OSError:
|
|
||||||
return False
|
|
||||||
|
|
||||||
def register(self, wizard):
|
def register(self, wizard):
|
||||||
"""
|
"""
|
||||||
This method basically just initialialises the database. It is called
|
This method basically just initialialises the database. It is called
|
||||||
@ -146,36 +199,11 @@ class BibleDB(QtCore.QObject):
|
|||||||
The actual Qt wizard form.
|
The actual Qt wizard form.
|
||||||
"""
|
"""
|
||||||
self.wizard = wizard
|
self.wizard = wizard
|
||||||
self.create_tables()
|
|
||||||
return self.name
|
|
||||||
|
|
||||||
def commit(self):
|
|
||||||
"""
|
|
||||||
Perform a database commit.
|
|
||||||
"""
|
|
||||||
log.debug('Committing...')
|
|
||||||
self.session.commit()
|
|
||||||
|
|
||||||
def create_tables(self):
|
|
||||||
"""
|
|
||||||
Create some initial metadata.
|
|
||||||
"""
|
|
||||||
log.debug(u'createTables')
|
|
||||||
self.create_meta(u'dbversion', u'2')
|
self.create_meta(u'dbversion', u'2')
|
||||||
self.create_testament(u'Old Testament')
|
self.save_object(Testament.populate(name=u'Old Testament'))
|
||||||
self.create_testament(u'New Testament')
|
self.save_object(Testament.populate(name=u'New Testament'))
|
||||||
self.create_testament(u'Apocrypha')
|
self.save_object(Testament.populate(name=u'Apocrypha'))
|
||||||
|
return self.name
|
||||||
def create_testament(self, testament):
|
|
||||||
"""
|
|
||||||
Add a testament to the database.
|
|
||||||
|
|
||||||
``testament``
|
|
||||||
The testament name.
|
|
||||||
"""
|
|
||||||
log.debug(u'BibleDB.create_testament("%s")', testament)
|
|
||||||
self.session.add(Testament.populate(name=testament))
|
|
||||||
self.commit()
|
|
||||||
|
|
||||||
def create_book(self, name, abbrev, testament=1):
|
def create_book(self, name, abbrev, testament=1):
|
||||||
"""
|
"""
|
||||||
@ -193,8 +221,7 @@ class BibleDB(QtCore.QObject):
|
|||||||
log.debug(u'create_book %s,%s', name, abbrev)
|
log.debug(u'create_book %s,%s', name, abbrev)
|
||||||
book = Book.populate(name=name, abbreviation=abbrev,
|
book = Book.populate(name=name, abbreviation=abbrev,
|
||||||
testament_id=testament)
|
testament_id=testament)
|
||||||
self.session.add(book)
|
self.save_object(book)
|
||||||
self.commit()
|
|
||||||
return book
|
return book
|
||||||
|
|
||||||
def create_chapter(self, book_id, chapter, textlist):
|
def create_chapter(self, book_id, chapter, textlist):
|
||||||
@ -221,7 +248,7 @@ class BibleDB(QtCore.QObject):
|
|||||||
text = verse_text
|
text = verse_text
|
||||||
)
|
)
|
||||||
self.session.add(verse)
|
self.session.add(verse)
|
||||||
self.commit()
|
self.session.commit()
|
||||||
|
|
||||||
def create_verse(self, book_id, chapter, verse, text):
|
def create_verse(self, book_id, chapter, verse, text):
|
||||||
"""
|
"""
|
||||||
@ -252,31 +279,32 @@ class BibleDB(QtCore.QObject):
|
|||||||
return verse
|
return verse
|
||||||
|
|
||||||
def create_meta(self, key, value):
|
def create_meta(self, key, value):
|
||||||
log.debug(u'save_meta %s/%s', key, value)
|
"""
|
||||||
self.session.add(BibleMeta.populate(key=key, value=value))
|
Utility method to save BibleMeta objects in a Bible database
|
||||||
self.commit()
|
|
||||||
|
|
||||||
def get_books(self):
|
``key``
|
||||||
log.debug(u'BibleDB.get_books()')
|
The key for this instance
|
||||||
return self.session.query(Book).order_by(Book.id).all()
|
|
||||||
|
``value``
|
||||||
|
The value for this instance
|
||||||
|
"""
|
||||||
|
log.debug(u'save_meta %s/%s', key, value)
|
||||||
|
self.save_object(BibleMeta.populate(key=key, value=value))
|
||||||
|
|
||||||
def get_book(self, book):
|
def get_book(self, book):
|
||||||
log.debug(u'BibleDb.get_book("%s")', book)
|
"""
|
||||||
db_book = self.session.query(Book)\
|
Return a book object from the database
|
||||||
.filter(Book.name.like(book + u'%'))\
|
|
||||||
.first()
|
|
||||||
if db_book is None:
|
|
||||||
db_book = self.session.query(Book)\
|
|
||||||
.filter(Book.abbreviation.like(book + u'%'))\
|
|
||||||
.first()
|
|
||||||
return db_book
|
|
||||||
|
|
||||||
def get_chapter(self, id, chapter):
|
``book``
|
||||||
log.debug(u'BibleDB.get_chapter("%s", %s)', id, chapter)
|
The name of the book to return
|
||||||
return self.session.query(Verse)\
|
"""
|
||||||
.filter_by(chapter=chapter)\
|
log.debug(u'BibleDb.get_book("%s")', book)
|
||||||
.filter_by(book_id=id)\
|
db_book = self.session.query(Book).filter(
|
||||||
.first()
|
Book.name.like(book + u'%')).first()
|
||||||
|
if db_book is None:
|
||||||
|
db_book = self.session.query(Book).filter(
|
||||||
|
Book.abbreviation.like(book + u'%')).first()
|
||||||
|
return db_book
|
||||||
|
|
||||||
def get_verses(self, reference_list):
|
def get_verses(self, reference_list):
|
||||||
"""
|
"""
|
||||||
@ -351,6 +379,12 @@ class BibleDB(QtCore.QObject):
|
|||||||
return verses
|
return verses
|
||||||
|
|
||||||
def get_chapter_count(self, book):
|
def get_chapter_count(self, book):
|
||||||
|
"""
|
||||||
|
Return the number of chapters in a book
|
||||||
|
|
||||||
|
``book``
|
||||||
|
The book to get the chapter count for
|
||||||
|
"""
|
||||||
log.debug(u'BibleDB.get_chapter_count("%s")', book)
|
log.debug(u'BibleDB.get_chapter_count("%s")', book)
|
||||||
count = self.session.query(Verse.chapter).join(Book)\
|
count = self.session.query(Verse.chapter).join(Book)\
|
||||||
.filter(Book.name==book)\
|
.filter(Book.name==book)\
|
||||||
@ -361,6 +395,15 @@ class BibleDB(QtCore.QObject):
|
|||||||
return count
|
return count
|
||||||
|
|
||||||
def get_verse_count(self, book, chapter):
|
def get_verse_count(self, book, chapter):
|
||||||
|
"""
|
||||||
|
Return the number of verses in a chapter
|
||||||
|
|
||||||
|
``book``
|
||||||
|
The book containing the chapter
|
||||||
|
|
||||||
|
``chapter``
|
||||||
|
The chapter to get the verse count for
|
||||||
|
"""
|
||||||
log.debug(u'BibleDB.get_verse_count("%s", %s)', book, chapter)
|
log.debug(u'BibleDB.get_verse_count("%s", %s)', book, chapter)
|
||||||
count = self.session.query(Verse).join(Book)\
|
count = self.session.query(Verse).join(Book)\
|
||||||
.filter(Book.name==book)\
|
.filter(Book.name==book)\
|
||||||
@ -371,20 +414,10 @@ class BibleDB(QtCore.QObject):
|
|||||||
else:
|
else:
|
||||||
return count
|
return count
|
||||||
|
|
||||||
def get_meta(self, key):
|
|
||||||
log.debug(u'get meta %s', key)
|
|
||||||
return self.session.query(BibleMeta).get(key)
|
|
||||||
|
|
||||||
def delete_meta(self, metakey):
|
|
||||||
biblemeta = self.get_meta(metakey)
|
|
||||||
try:
|
|
||||||
self.session.delete(biblemeta)
|
|
||||||
self.commit()
|
|
||||||
return True
|
|
||||||
except:
|
|
||||||
return False
|
|
||||||
|
|
||||||
def dump_bible(self):
|
def dump_bible(self):
|
||||||
|
"""
|
||||||
|
Utility debugging method to dump the contents of a bible
|
||||||
|
"""
|
||||||
log.debug(u'.........Dumping Bible Database')
|
log.debug(u'.........Dumping Bible Database')
|
||||||
log.debug('...............................Books ')
|
log.debug('...............................Books ')
|
||||||
books = self.session.query(Book).all()
|
books = self.session.query(Book).all()
|
||||||
|
@ -35,8 +35,7 @@ from openlp.core.lib import Receiver
|
|||||||
from openlp.core.utils import AppLocation
|
from openlp.core.utils import AppLocation
|
||||||
from openlp.plugins.bibles.lib.common import BibleCommon, SearchResults, \
|
from openlp.plugins.bibles.lib.common import BibleCommon, SearchResults, \
|
||||||
unescape
|
unescape
|
||||||
from openlp.plugins.bibles.lib.db import BibleDB
|
from openlp.plugins.bibles.lib.db import BibleDB, Book
|
||||||
from openlp.plugins.bibles.lib.models import Book
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -29,12 +29,12 @@ from PyQt4 import QtCore
|
|||||||
|
|
||||||
from openlp.core.lib import SettingsManager
|
from openlp.core.lib import SettingsManager
|
||||||
from openlp.core.utils import AppLocation
|
from openlp.core.utils import AppLocation
|
||||||
|
from openlp.plugins.bibles.lib.db import BibleDB, Book, BibleMeta
|
||||||
|
|
||||||
from common import parse_reference
|
from common import parse_reference
|
||||||
from opensong import OpenSongBible
|
from opensong import OpenSongBible
|
||||||
from osis import OSISBible
|
from osis import OSISBible
|
||||||
from csvbible import CSVBible
|
from csvbible import CSVBible
|
||||||
from db import BibleDB
|
|
||||||
from http import HTTPBible
|
from http import HTTPBible
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
@ -137,11 +137,13 @@ class BibleManager(object):
|
|||||||
log.debug(u'Bible Name: "%s"', name)
|
log.debug(u'Bible Name: "%s"', name)
|
||||||
self.db_cache[name] = bible
|
self.db_cache[name] = bible
|
||||||
# look to see if lazy load bible exists and get create getter.
|
# look to see if lazy load bible exists and get create getter.
|
||||||
source = self.db_cache[name].get_meta(u'download source')
|
source = self.db_cache[name].get_object(BibleMeta,
|
||||||
|
u'download source')
|
||||||
if source:
|
if source:
|
||||||
download_name = \
|
download_name = self.db_cache[name].get_object(BibleMeta,
|
||||||
self.db_cache[name].get_meta(u'download name').value
|
u'download name').value
|
||||||
meta_proxy = self.db_cache[name].get_meta(u'proxy url')
|
meta_proxy = self.db_cache[name].get_object(BibleMeta,
|
||||||
|
u'proxy url')
|
||||||
web_bible = HTTPBible(self.parent, path=self.path,
|
web_bible = HTTPBible(self.parent, path=self.path,
|
||||||
file=filename, download_source=source.value,
|
file=filename, download_source=source.value,
|
||||||
download_name=download_name)
|
download_name=download_name)
|
||||||
@ -196,7 +198,7 @@ class BibleManager(object):
|
|||||||
u'name': book.name,
|
u'name': book.name,
|
||||||
u'chapters': self.db_cache[bible].get_chapter_count(book.name)
|
u'chapters': self.db_cache[bible].get_chapter_count(book.name)
|
||||||
}
|
}
|
||||||
for book in self.db_cache[bible].get_books()
|
for book in self.db_cache[bible].get_all_objects(Book, Book.id)
|
||||||
]
|
]
|
||||||
|
|
||||||
def get_chapter_count(self, bible, book):
|
def get_chapter_count(self, bible, book):
|
||||||
@ -249,7 +251,7 @@ class BibleManager(object):
|
|||||||
Returns the meta data for a given key
|
Returns the meta data for a given key
|
||||||
"""
|
"""
|
||||||
log.debug(u'get_meta %s,%s', bible, key)
|
log.debug(u'get_meta %s,%s', bible, key)
|
||||||
return self.db_cache[bible].get_meta(key)
|
return self.db_cache[bible].get_object(BibleMeta, key)
|
||||||
|
|
||||||
def exists(self, name):
|
def exists(self, name):
|
||||||
"""
|
"""
|
||||||
|
@ -1,94 +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 #
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
from sqlalchemy import Column, Table, MetaData, ForeignKey, types, \
|
|
||||||
create_engine
|
|
||||||
from sqlalchemy.orm import mapper, relation, sessionmaker, scoped_session
|
|
||||||
|
|
||||||
from openlp.core.lib import BaseModel
|
|
||||||
|
|
||||||
|
|
||||||
class BibleMeta(BaseModel):
|
|
||||||
"""
|
|
||||||
Bible Meta Data
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class Testament(BaseModel):
|
|
||||||
"""
|
|
||||||
Bible Testaments
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class Book(BaseModel):
|
|
||||||
"""
|
|
||||||
Song model
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class Verse(BaseModel):
|
|
||||||
"""
|
|
||||||
Topic model
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
def init_models(db_url):
|
|
||||||
engine = create_engine(db_url)
|
|
||||||
metadata.bind = engine
|
|
||||||
session = scoped_session(sessionmaker(autoflush=True, autocommit=False,
|
|
||||||
bind=engine))
|
|
||||||
return session
|
|
||||||
|
|
||||||
metadata = MetaData()
|
|
||||||
meta_table = Table(u'metadata', metadata,
|
|
||||||
Column(u'key', types.Unicode(255), primary_key=True, index=True),
|
|
||||||
Column(u'value', types.Unicode(255)),
|
|
||||||
)
|
|
||||||
testament_table = Table(u'testament', metadata,
|
|
||||||
Column(u'id', types.Integer, primary_key=True),
|
|
||||||
Column(u'name', types.Unicode(50)),
|
|
||||||
)
|
|
||||||
book_table = Table(u'book', metadata,
|
|
||||||
Column(u'id', types.Integer, primary_key=True),
|
|
||||||
Column(u'testament_id', types.Integer, ForeignKey(u'testament.id')),
|
|
||||||
Column(u'name', types.Unicode(50), index=True),
|
|
||||||
Column(u'abbreviation', types.Unicode(5), index=True),
|
|
||||||
)
|
|
||||||
verse_table = Table(u'verse', metadata,
|
|
||||||
Column(u'id', types.Integer, primary_key=True, index=True),
|
|
||||||
Column(u'book_id', types.Integer, ForeignKey(u'book.id'), index=True),
|
|
||||||
Column(u'chapter', types.Integer, index=True),
|
|
||||||
Column(u'verse', types.Integer, index=True),
|
|
||||||
Column(u'text', types.UnicodeText, index=True),
|
|
||||||
)
|
|
||||||
mapper(BibleMeta, meta_table)
|
|
||||||
mapper(Testament, testament_table,
|
|
||||||
properties={'books': relation(Book, backref='testament')})
|
|
||||||
mapper(Book, book_table,
|
|
||||||
properties={'verses': relation(Verse, backref='book')})
|
|
||||||
mapper(Verse, verse_table)
|
|
@ -90,7 +90,7 @@ class OpenSongBible(BibleDB):
|
|||||||
QtCore.QString('%s %s %s' % (
|
QtCore.QString('%s %s %s' % (
|
||||||
translate('BiblesPlugin.Opensong', 'Importing'), \
|
translate('BiblesPlugin.Opensong', 'Importing'), \
|
||||||
db_book.name, chapter.attrib[u'n'])))
|
db_book.name, chapter.attrib[u'n'])))
|
||||||
self.commit()
|
self.session.commit()
|
||||||
except IOError:
|
except IOError:
|
||||||
log.exception(u'Loading bible from OpenSong file failed')
|
log.exception(u'Loading bible from OpenSong file failed')
|
||||||
success = False
|
success = False
|
||||||
|
@ -140,7 +140,7 @@ class OSISBible(BibleDB):
|
|||||||
self.wizard.ImportProgressBar.setMaximum(260)
|
self.wizard.ImportProgressBar.setMaximum(260)
|
||||||
if last_chapter != chapter:
|
if last_chapter != chapter:
|
||||||
if last_chapter != 0:
|
if last_chapter != 0:
|
||||||
self.commit()
|
self.session.commit()
|
||||||
self.wizard.incrementProgressBar(
|
self.wizard.incrementProgressBar(
|
||||||
u'Importing %s %s...' % \
|
u'Importing %s %s...' % \
|
||||||
(self.books[match.group(1)][0], chapter))
|
(self.books[match.group(1)][0], chapter))
|
||||||
@ -169,7 +169,7 @@ class OSISBible(BibleDB):
|
|||||||
verse_text = self.spaces_regex.sub(u' ', verse_text)
|
verse_text = self.spaces_regex.sub(u' ', verse_text)
|
||||||
self.create_verse(db_book.id, chapter, verse, verse_text)
|
self.create_verse(db_book.id, chapter, verse, verse_text)
|
||||||
Receiver.send_message(u'openlp_process_events')
|
Receiver.send_message(u'openlp_process_events')
|
||||||
self.commit()
|
self.session.commit()
|
||||||
self.wizard.incrementProgressBar(u'Finishing import...')
|
self.wizard.incrementProgressBar(u'Finishing import...')
|
||||||
if match_count == 0:
|
if match_count == 0:
|
||||||
success = False
|
success = False
|
||||||
|
@ -26,8 +26,11 @@
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
from forms import EditCustomForm
|
from forms import EditCustomForm
|
||||||
|
|
||||||
from openlp.core.lib import Plugin, build_icon, PluginStatus, translate
|
from openlp.core.lib import Plugin, build_icon, PluginStatus, translate
|
||||||
from openlp.plugins.custom.lib import CustomManager, CustomMediaItem, CustomTab
|
from openlp.core.lib.db import Manager
|
||||||
|
from openlp.plugins.custom.lib import CustomMediaItem, CustomTab
|
||||||
|
from openlp.plugins.custom.lib.db import CustomSlide, init_schema
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -45,7 +48,7 @@ class CustomPlugin(Plugin):
|
|||||||
def __init__(self, plugin_helpers):
|
def __init__(self, plugin_helpers):
|
||||||
Plugin.__init__(self, u'Custom', u'1.9.2', plugin_helpers)
|
Plugin.__init__(self, u'Custom', u'1.9.2', plugin_helpers)
|
||||||
self.weight = -5
|
self.weight = -5
|
||||||
self.custommanager = CustomManager()
|
self.custommanager = Manager(u'custom', init_schema)
|
||||||
self.edit_custom_form = EditCustomForm(self.custommanager)
|
self.edit_custom_form = EditCustomForm(self.custommanager)
|
||||||
self.icon = build_icon(u':/media/media_custom.png')
|
self.icon = build_icon(u':/media/media_custom.png')
|
||||||
self.status = PluginStatus.Active
|
self.status = PluginStatus.Active
|
||||||
@ -75,6 +78,8 @@ class CustomPlugin(Plugin):
|
|||||||
return about_text
|
return about_text
|
||||||
|
|
||||||
def can_delete_theme(self, theme):
|
def can_delete_theme(self, theme):
|
||||||
if len(self.custommanager.get_customs_for_theme(theme)) == 0:
|
filter_string = u'theme_name=%s' % theme
|
||||||
|
if not self.custommanager.get_all_objects_filtered(CustomSlide,
|
||||||
|
filter_string):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
@ -29,7 +29,7 @@ from PyQt4 import QtCore, QtGui
|
|||||||
|
|
||||||
from editcustomdialog import Ui_customEditDialog
|
from editcustomdialog import Ui_customEditDialog
|
||||||
from openlp.core.lib import SongXMLBuilder, SongXMLParser, Receiver, translate
|
from openlp.core.lib import SongXMLBuilder, SongXMLParser, Receiver, translate
|
||||||
from openlp.plugins.custom.lib.models import CustomSlide
|
from openlp.plugins.custom.lib.db import CustomSlide
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -116,7 +116,7 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog):
|
|||||||
self.customSlide = CustomSlide()
|
self.customSlide = CustomSlide()
|
||||||
self.initialise()
|
self.initialise()
|
||||||
if id != 0:
|
if id != 0:
|
||||||
self.customSlide = self.custommanager.get_custom(id)
|
self.customSlide = self.custommanager.get_object(CustomSlide, id)
|
||||||
self.TitleEdit.setText(self.customSlide.title)
|
self.TitleEdit.setText(self.customSlide.title)
|
||||||
self.CreditEdit.setText(self.customSlide.credits)
|
self.CreditEdit.setText(self.customSlide.credits)
|
||||||
songXML = SongXMLParser(self.customSlide.text)
|
songXML = SongXMLParser(self.customSlide.text)
|
||||||
@ -166,8 +166,7 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog):
|
|||||||
u'utf-8')
|
u'utf-8')
|
||||||
self.customSlide.theme_name = unicode(self.ThemeComboBox.currentText(),
|
self.customSlide.theme_name = unicode(self.ThemeComboBox.currentText(),
|
||||||
u'utf-8')
|
u'utf-8')
|
||||||
self.custommanager.save_slide(self.customSlide)
|
return self.custommanager.save_object(self.customSlide)
|
||||||
return True
|
|
||||||
|
|
||||||
def onUpButtonPressed(self):
|
def onUpButtonPressed(self):
|
||||||
selectedRow = self.VerseListView.currentRow()
|
selectedRow = self.VerseListView.currentRow()
|
||||||
|
@ -23,6 +23,5 @@
|
|||||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
from manager import CustomManager
|
|
||||||
from mediaitem import CustomMediaItem
|
from mediaitem import CustomMediaItem
|
||||||
from customtab import CustomTab
|
from customtab import CustomTab
|
||||||
|
@ -1,32 +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 #
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
from openlp.core.lib import BaseModel
|
|
||||||
|
|
||||||
class CustomSlide(BaseModel):
|
|
||||||
"""
|
|
||||||
Custom Slide model
|
|
||||||
"""
|
|
||||||
pass
|
|
@ -22,18 +22,40 @@
|
|||||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
"""
|
||||||
|
The :mod:`db` module provides the database and schema that is the backend for
|
||||||
|
the Custom plugin
|
||||||
|
"""
|
||||||
|
|
||||||
from sqlalchemy import create_engine
|
from sqlalchemy import Column, Table, types
|
||||||
from sqlalchemy.orm import scoped_session, sessionmaker, mapper
|
from sqlalchemy.orm import mapper
|
||||||
|
|
||||||
from openlp.plugins.custom.lib.meta import metadata
|
from openlp.core.lib.db import BaseModel, init_db
|
||||||
from openlp.plugins.custom.lib.tables import *
|
|
||||||
from openlp.plugins.custom.lib.classes import *
|
class CustomSlide(BaseModel):
|
||||||
|
"""
|
||||||
|
CustomSlide model
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def init_schema(url):
|
||||||
|
"""
|
||||||
|
Setup the custom database connection and initialise the database schema
|
||||||
|
|
||||||
|
``url``
|
||||||
|
The database to setup
|
||||||
|
"""
|
||||||
|
session, metadata = init_db(url)
|
||||||
|
|
||||||
|
custom_slide_table = Table(u'custom_slide', metadata,
|
||||||
|
Column(u'id', types.Integer(), primary_key=True),
|
||||||
|
Column(u'title', types.Unicode(255), nullable=False),
|
||||||
|
Column(u'text', types.UnicodeText, nullable=False),
|
||||||
|
Column(u'credits', types.UnicodeText),
|
||||||
|
Column(u'theme_name', types.Unicode(128))
|
||||||
|
)
|
||||||
|
|
||||||
def init_models(url):
|
|
||||||
engine = create_engine(url)
|
|
||||||
metadata.bind = engine
|
|
||||||
session = scoped_session(sessionmaker(autoflush=True, autocommit=False,
|
|
||||||
bind=engine))
|
|
||||||
mapper(CustomSlide, custom_slide_table)
|
mapper(CustomSlide, custom_slide_table)
|
||||||
|
|
||||||
|
metadata.create_all(checkfirst=True)
|
||||||
return session
|
return session
|
@ -1,117 +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.custom.lib.models import init_models, metadata, CustomSlide
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
class CustomManager(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'Custom manager loaded')
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
"""
|
|
||||||
Creates the connection to the database, and creates the tables if they
|
|
||||||
don't exist.
|
|
||||||
"""
|
|
||||||
log.debug(u'Custom Initialising')
|
|
||||||
settings = QtCore.QSettings()
|
|
||||||
settings.beginGroup(u'custom')
|
|
||||||
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/custom.sqlite' % \
|
|
||||||
AppLocation.get_section_data_path(u'custom')
|
|
||||||
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()))
|
|
||||||
self.session = init_models(self.db_url)
|
|
||||||
metadata.create_all(checkfirst=True)
|
|
||||||
settings.endGroup()
|
|
||||||
log.debug(u'Custom Initialised')
|
|
||||||
|
|
||||||
def get_all_slides(self):
|
|
||||||
"""
|
|
||||||
Returns the details of a Custom Slide Show
|
|
||||||
"""
|
|
||||||
return self.session.query(CustomSlide).order_by(CustomSlide.title).all()
|
|
||||||
|
|
||||||
def save_slide(self, customslide):
|
|
||||||
"""
|
|
||||||
Saves a Custom slide show to the database
|
|
||||||
"""
|
|
||||||
log.debug(u'Custom Slide added')
|
|
||||||
try:
|
|
||||||
self.session.add(customslide)
|
|
||||||
self.session.commit()
|
|
||||||
log.debug(u'Custom Slide saved')
|
|
||||||
return True
|
|
||||||
except InvalidRequestError:
|
|
||||||
self.session.rollback()
|
|
||||||
log.exception(u'Custom Slide save failed')
|
|
||||||
return False
|
|
||||||
|
|
||||||
def get_custom(self, id=None):
|
|
||||||
"""
|
|
||||||
Returns the details of a Custom Slide
|
|
||||||
"""
|
|
||||||
if id is None:
|
|
||||||
return CustomSlide()
|
|
||||||
else:
|
|
||||||
return self.session.query(CustomSlide).get(id)
|
|
||||||
|
|
||||||
def delete_custom(self, id):
|
|
||||||
"""
|
|
||||||
Delete a Custom slide show
|
|
||||||
"""
|
|
||||||
if id != 0:
|
|
||||||
customslide = self.get_custom(id)
|
|
||||||
try:
|
|
||||||
self.session.delete(customslide)
|
|
||||||
self.session.commit()
|
|
||||||
return True
|
|
||||||
except InvalidRequestError:
|
|
||||||
self.session.rollback()
|
|
||||||
log.exception(u'Custom Slide deleton failed')
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
return True
|
|
||||||
|
|
||||||
def get_customs_for_theme(self, theme):
|
|
||||||
return self.session.query(
|
|
||||||
CustomSlide).filter(CustomSlide.theme_name == theme).all()
|
|
@ -29,6 +29,7 @@ from PyQt4 import QtCore, QtGui
|
|||||||
|
|
||||||
from openlp.core.lib import MediaManagerItem, SongXMLParser, BaseListWithDnD, \
|
from openlp.core.lib import MediaManagerItem, SongXMLParser, BaseListWithDnD, \
|
||||||
Receiver, ItemCapabilities, translate, check_item_selected
|
Receiver, ItemCapabilities, translate, check_item_selected
|
||||||
|
from openlp.plugins.custom.lib.db import CustomSlide
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -72,7 +73,8 @@ class CustomMediaItem(MediaManagerItem):
|
|||||||
MediaManagerItem.requiredIcons(self)
|
MediaManagerItem.requiredIcons(self)
|
||||||
|
|
||||||
def initialise(self):
|
def initialise(self):
|
||||||
self.loadCustomListView(self.parent.custommanager.get_all_slides())
|
self.loadCustomListView(self.parent.custommanager.get_all_objects(
|
||||||
|
CustomSlide, CustomSlide.title))
|
||||||
#Called to redisplay the song list screen edith from a search
|
#Called to redisplay the song list screen edith from a search
|
||||||
#or from the exit of the Song edit dialog. If remote editing is active
|
#or from the exit of the Song edit dialog. If remote editing is active
|
||||||
#Trigger it and clean up so it will not update again.
|
#Trigger it and clean up so it will not update again.
|
||||||
@ -84,10 +86,10 @@ class CustomMediaItem(MediaManagerItem):
|
|||||||
|
|
||||||
def loadCustomListView(self, list):
|
def loadCustomListView(self, list):
|
||||||
self.ListView.clear()
|
self.ListView.clear()
|
||||||
for CustomSlide in list:
|
for customSlide in list:
|
||||||
custom_name = QtGui.QListWidgetItem(CustomSlide.title)
|
custom_name = QtGui.QListWidgetItem(customSlide.title)
|
||||||
custom_name.setData(
|
custom_name.setData(
|
||||||
QtCore.Qt.UserRole, QtCore.QVariant(CustomSlide.id))
|
QtCore.Qt.UserRole, QtCore.QVariant(customSlide.id))
|
||||||
self.ListView.addItem(custom_name)
|
self.ListView.addItem(custom_name)
|
||||||
|
|
||||||
def onNewClick(self):
|
def onNewClick(self):
|
||||||
@ -106,7 +108,7 @@ class CustomMediaItem(MediaManagerItem):
|
|||||||
type of display is required.
|
type of display is required.
|
||||||
"""
|
"""
|
||||||
fields = customid.split(u':')
|
fields = customid.split(u':')
|
||||||
valid = self.parent.custommanager.get_custom(fields[1])
|
valid = self.parent.custommanager.get_object(CustomSlide, fields[1])
|
||||||
if valid:
|
if valid:
|
||||||
self.remoteCustom = fields[1]
|
self.remoteCustom = fields[1]
|
||||||
self.remoteTriggered = fields[0]
|
self.remoteTriggered = fields[0]
|
||||||
@ -136,7 +138,7 @@ class CustomMediaItem(MediaManagerItem):
|
|||||||
'You must select an item to delete.')):
|
'You must select an item to delete.')):
|
||||||
item = self.ListView.currentItem()
|
item = self.ListView.currentItem()
|
||||||
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
|
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
|
||||||
self.parent.custommanager.delete_custom(item_id)
|
self.parent.custommanager.delete_object(CustomSlide, item_id)
|
||||||
row = self.ListView.row(item)
|
row = self.ListView.row(item)
|
||||||
self.ListView.takeItem(row)
|
self.ListView.takeItem(row)
|
||||||
|
|
||||||
@ -158,7 +160,7 @@ class CustomMediaItem(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)
|
||||||
customSlide = self.parent.custommanager.get_custom(item_id)
|
customSlide = self.parent.custommanager.get_object(CustomSlide, item_id)
|
||||||
title = customSlide.title
|
title = customSlide.title
|
||||||
credit = customSlide.credits
|
credit = customSlide.credits
|
||||||
service_item.editId = item_id
|
service_item.editId = item_id
|
||||||
|
@ -1,38 +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 #
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
from sqlalchemy import MetaData
|
|
||||||
|
|
||||||
__all__ = ['session', 'metadata', 'engine']
|
|
||||||
|
|
||||||
# SQLAlchemy database engine. Updated by model.init_model()
|
|
||||||
engine = None
|
|
||||||
|
|
||||||
# SQLAlchemy session manager. Updated by model.init_model()
|
|
||||||
session = None
|
|
||||||
|
|
||||||
# Global metadata. If you have multiple databases with overlapping table
|
|
||||||
# names, you'll need a metadata for each database
|
|
||||||
metadata = MetaData()
|
|
@ -1,37 +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 #
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
from sqlalchemy import Column, Table, types
|
|
||||||
|
|
||||||
from openlp.plugins.custom.lib.meta import metadata
|
|
||||||
|
|
||||||
# Definition of the "custom slide" table
|
|
||||||
custom_slide_table = Table(u'custom_slide', metadata,
|
|
||||||
Column(u'id', types.Integer(), primary_key=True),
|
|
||||||
Column(u'title', types.Unicode(255), nullable=False),
|
|
||||||
Column(u'text', types.UnicodeText, nullable=False),
|
|
||||||
Column(u'credits', types.UnicodeText),
|
|
||||||
Column(u'theme_name', types.Unicode(128))
|
|
||||||
)
|
|
@ -24,6 +24,7 @@
|
|||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
from openlp.core.lib import translate
|
from openlp.core.lib import translate
|
||||||
|
|
||||||
class Ui_AuthorsDialog(object):
|
class Ui_AuthorsDialog(object):
|
||||||
|
@ -28,7 +28,6 @@ from PyQt4 import QtGui, QtCore
|
|||||||
from openlp.core.lib import translate
|
from openlp.core.lib import translate
|
||||||
from openlp.plugins.songs.forms.authorsdialog import Ui_AuthorsDialog
|
from openlp.plugins.songs.forms.authorsdialog import Ui_AuthorsDialog
|
||||||
|
|
||||||
|
|
||||||
class AuthorsForm(QtGui.QDialog, Ui_AuthorsDialog):
|
class AuthorsForm(QtGui.QDialog, Ui_AuthorsDialog):
|
||||||
"""
|
"""
|
||||||
Class to control the Maintenance of Authors Dialog
|
Class to control the Maintenance of Authors Dialog
|
||||||
|
@ -24,9 +24,8 @@
|
|||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
from openlp.core.lib import translate
|
|
||||||
|
|
||||||
from openlp.core.lib import build_icon
|
from openlp.core.lib import build_icon, translate
|
||||||
|
|
||||||
class Ui_EditSongDialog(object):
|
class Ui_EditSongDialog(object):
|
||||||
def setupUi(self, EditSongDialog):
|
def setupUi(self, EditSongDialog):
|
||||||
|
@ -31,7 +31,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 import VerseType
|
from openlp.plugins.songs.lib import VerseType
|
||||||
from openlp.plugins.songs.lib.models import Song, Author, Topic, Book
|
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__)
|
||||||
@ -118,7 +118,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)
|
||||||
self.AuthorsSelectionComboItem.clear()
|
self.AuthorsSelectionComboItem.clear()
|
||||||
self.AuthorsSelectionComboItem.addItem(u'')
|
self.AuthorsSelectionComboItem.addItem(u'')
|
||||||
for author in authors:
|
for author in authors:
|
||||||
@ -128,7 +128,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)
|
||||||
self.SongTopicCombo.clear()
|
self.SongTopicCombo.clear()
|
||||||
self.SongTopicCombo.addItem(u'')
|
self.SongTopicCombo.addItem(u'')
|
||||||
for topic in topics:
|
for topic in topics:
|
||||||
@ -137,7 +137,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)
|
||||||
self.SongbookCombo.clear()
|
self.SongbookCombo.clear()
|
||||||
self.SongbookCombo.addItem(u'')
|
self.SongbookCombo.addItem(u'')
|
||||||
for book in books:
|
for book in books:
|
||||||
@ -178,11 +178,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:
|
||||||
@ -289,7 +290,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||||||
QtGui.QMessageBox.Yes) == QtGui.QMessageBox.Yes:
|
QtGui.QMessageBox.Yes) == QtGui.QMessageBox.Yes:
|
||||||
author = Author.populate(first_name=text.rsplit(u' ', 1)[0],
|
author = Author.populate(first_name=text.rsplit(u' ', 1)[0],
|
||||||
last_name=text.rsplit(u' ', 1)[1], display_name=text)
|
last_name=text.rsplit(u' ', 1)[1], display_name=text)
|
||||||
self.songmanager.save_author(author)
|
self.songmanager.save_object(author)
|
||||||
self.song.authors.append(author)
|
self.song.authors.append(author)
|
||||||
author_item = QtGui.QListWidgetItem(
|
author_item = QtGui.QListWidgetItem(
|
||||||
unicode(author.display_name))
|
unicode(author.display_name))
|
||||||
@ -302,7 +303,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||||||
return
|
return
|
||||||
elif item > 0:
|
elif item > 0:
|
||||||
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))
|
||||||
@ -325,7 +326,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)
|
||||||
@ -341,7 +342,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||||||
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No,
|
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No,
|
||||||
QtGui.QMessageBox.Yes) == QtGui.QMessageBox.Yes:
|
QtGui.QMessageBox.Yes) == QtGui.QMessageBox.Yes:
|
||||||
topic = Topic.populate(name=text)
|
topic = Topic.populate(name=text)
|
||||||
self.songmanager.save_topic(topic)
|
self.songmanager.save_object(topic)
|
||||||
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,
|
topic_item.setData(QtCore.Qt.UserRole,
|
||||||
@ -353,7 +354,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||||||
return
|
return
|
||||||
elif item > 0:
|
elif item > 0:
|
||||||
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))
|
||||||
@ -375,7 +376,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)
|
||||||
@ -391,7 +392,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||||||
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No,
|
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No,
|
||||||
QtGui.QMessageBox.Yes) == QtGui.QMessageBox.Yes:
|
QtGui.QMessageBox.Yes) == QtGui.QMessageBox.Yes:
|
||||||
book = Book.populate(name=text)
|
book = Book.populate(name=text)
|
||||||
self.songmanager.save_book(book)
|
self.songmanager.save_object(book)
|
||||||
self.song.book = book
|
self.song.book = book
|
||||||
self.loadBooks()
|
self.loadBooks()
|
||||||
else:
|
else:
|
||||||
@ -630,7 +631,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||||||
if self._validate_song():
|
if self._validate_song():
|
||||||
self.processLyrics()
|
self.processLyrics()
|
||||||
self.processTitle()
|
self.processTitle()
|
||||||
self.songmanager.save_song(self.song)
|
self.songmanager.save_object(self.song)
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
from openlp.core.lib import translate
|
from openlp.core.lib import translate
|
||||||
|
|
||||||
class Ui_SongBookDialog(object):
|
class Ui_SongBookDialog(object):
|
||||||
|
@ -28,7 +28,6 @@ from PyQt4 import QtGui
|
|||||||
from openlp.core.lib import translate
|
from openlp.core.lib import translate
|
||||||
from openlp.plugins.songs.forms.songbookdialog import Ui_SongBookDialog
|
from openlp.plugins.songs.forms.songbookdialog import Ui_SongBookDialog
|
||||||
|
|
||||||
|
|
||||||
class SongBookForm(QtGui.QDialog, Ui_SongBookDialog):
|
class SongBookForm(QtGui.QDialog, Ui_SongBookDialog):
|
||||||
"""
|
"""
|
||||||
Class documentation goes here.
|
Class documentation goes here.
|
||||||
|
@ -25,12 +25,10 @@
|
|||||||
|
|
||||||
from PyQt4 import QtGui, QtCore
|
from PyQt4 import QtGui, QtCore
|
||||||
|
|
||||||
from openlp.plugins.songs.lib.classes import Author, Book, Topic
|
|
||||||
from songmaintenancedialog import Ui_SongMaintenanceDialog
|
|
||||||
from authorsform import AuthorsForm
|
|
||||||
from topicsform import TopicsForm
|
|
||||||
from songbookform import SongBookForm
|
|
||||||
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 songmaintenancedialog import Ui_SongMaintenanceDialog
|
||||||
|
|
||||||
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.save_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.save_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.save_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)
|
||||||
# Just make sure none of the fields is None
|
# Just make sure none of the fields is None
|
||||||
if author.first_name is None:
|
if author.first_name is None:
|
||||||
author.first_name = u''
|
author.first_name = u''
|
||||||
@ -189,7 +187,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.save_object(author):
|
||||||
self.resetAuthors()
|
self.resetAuthors()
|
||||||
else:
|
else:
|
||||||
QtGui.QMessageBox.critical(
|
QtGui.QMessageBox.critical(
|
||||||
@ -201,11 +199,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.save_object(topic):
|
||||||
self.resetTopics()
|
self.resetTopics()
|
||||||
else:
|
else:
|
||||||
QtGui.QMessageBox.critical(
|
QtGui.QMessageBox.critical(
|
||||||
@ -217,13 +215,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.save_object(book):
|
||||||
self.resetBooks()
|
self.resetBooks()
|
||||||
else:
|
else:
|
||||||
QtGui.QMessageBox.critical(
|
QtGui.QMessageBox.critical(
|
||||||
@ -236,9 +234,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('SongsPlugin.SongMaintenanceForm', 'Delete Author'),
|
translate('SongsPlugin.SongMaintenanceForm', 'Delete Author'),
|
||||||
translate('SongsPlugin.SongMaintenanceForm',
|
translate('SongsPlugin.SongMaintenanceForm',
|
||||||
'Are you sure you want to delete the selected author?'),
|
'Are you sure you want to delete the selected author?'),
|
||||||
@ -252,9 +248,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('SongsPlugin.SongMaintenanceForm', 'Delete Topic'),
|
translate('SongsPlugin.SongMaintenanceForm', 'Delete Topic'),
|
||||||
translate('SongsPlugin.SongMaintenanceForm',
|
translate('SongsPlugin.SongMaintenanceForm',
|
||||||
'Are you sure you want to delete the selected topic?'),
|
'Are you sure you want to delete the selected topic?'),
|
||||||
@ -268,13 +262,11 @@ 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('SongsPlugin.SongMaintenanceForm', 'Delete Book'),
|
translate('SongsPlugin.SongMaintenanceForm', 'Delete Book'),
|
||||||
translate('SongsPlugin.SongMaintenanceForm',
|
translate('SongsPlugin.SongMaintenanceForm',
|
||||||
'Are you sure you want to delete the selected book?'),
|
'Are you sure you want to delete the selected book?'),
|
||||||
translate('SongsPlugin.SongMaintenanceForm',
|
translate('SongsPlugin.SongMaintenanceForm',
|
||||||
'This book can\'t be deleted, it is currently '
|
'This book can\'t be deleted, it is currently '
|
||||||
'assigned to at least one song.'),
|
'assigned to at least one song.'),
|
||||||
translate('SongsPlugin.SongMaintenanceForm', 'No book selected!'))
|
translate('SongsPlugin.SongMaintenanceForm', u'No book selected!'))
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
from openlp.core.lib import translate
|
from openlp.core.lib import translate
|
||||||
|
|
||||||
class Ui_TopicsDialog(object):
|
class Ui_TopicsDialog(object):
|
||||||
|
@ -28,7 +28,6 @@ from PyQt4 import QtGui
|
|||||||
from openlp.core.lib import translate
|
from openlp.core.lib import translate
|
||||||
from openlp.plugins.songs.forms.topicsdialog import Ui_TopicsDialog
|
from openlp.plugins.songs.forms.topicsdialog import Ui_TopicsDialog
|
||||||
|
|
||||||
|
|
||||||
class TopicsForm(QtGui.QDialog, Ui_TopicsDialog):
|
class TopicsForm(QtGui.QDialog, Ui_TopicsDialog):
|
||||||
"""
|
"""
|
||||||
Class documentation goes here.
|
Class documentation goes here.
|
||||||
|
@ -1,52 +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 #
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
from openlp.core.lib import BaseModel
|
|
||||||
|
|
||||||
class Author(BaseModel):
|
|
||||||
"""
|
|
||||||
Author model
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
class Book(BaseModel):
|
|
||||||
"""
|
|
||||||
Book model
|
|
||||||
"""
|
|
||||||
def __repr__(self):
|
|
||||||
return u'<Book id="%s" name="%s" publisher="%s" />' % (
|
|
||||||
str(self.id), self.name, self.publisher)
|
|
||||||
|
|
||||||
class Song(BaseModel):
|
|
||||||
"""
|
|
||||||
Song model
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
class Topic(BaseModel):
|
|
||||||
"""
|
|
||||||
Topic model
|
|
||||||
"""
|
|
||||||
pass
|
|
151
openlp/plugins/songs/lib/db.py
Normal file
151
openlp/plugins/songs/lib/db.py
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
# -*- 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:`db` module provides the database and schema that is the backend for
|
||||||
|
the Songs plugin
|
||||||
|
"""
|
||||||
|
|
||||||
|
from sqlalchemy import Column, ForeignKey, Index, Table, types
|
||||||
|
from sqlalchemy.orm import mapper, relation
|
||||||
|
|
||||||
|
from openlp.core.lib.db import BaseModel, init_db
|
||||||
|
|
||||||
|
class Author(BaseModel):
|
||||||
|
"""
|
||||||
|
Author model
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
class Book(BaseModel):
|
||||||
|
"""
|
||||||
|
Book model
|
||||||
|
"""
|
||||||
|
def __repr__(self):
|
||||||
|
return u'<Book id="%s" name="%s" publisher="%s" />' % (
|
||||||
|
str(self.id), self.name, self.publisher)
|
||||||
|
|
||||||
|
class Song(BaseModel):
|
||||||
|
"""
|
||||||
|
Song model
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
class Topic(BaseModel):
|
||||||
|
"""
|
||||||
|
Topic model
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def init_schema(url):
|
||||||
|
"""
|
||||||
|
Setup the songs database connection and initialise the database schema
|
||||||
|
|
||||||
|
``url``
|
||||||
|
The database to setup
|
||||||
|
"""
|
||||||
|
session, metadata = init_db(url, auto_flush=False)
|
||||||
|
|
||||||
|
# Definition of the "authors" table
|
||||||
|
authors_table = Table(u'authors', metadata,
|
||||||
|
Column(u'id', types.Integer, primary_key=True),
|
||||||
|
Column(u'first_name', types.Unicode(128)),
|
||||||
|
Column(u'last_name', types.Unicode(128)),
|
||||||
|
Column(u'display_name', types.Unicode(255), nullable=False)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Definition of the "song_books" table
|
||||||
|
song_books_table = Table(u'song_books', metadata,
|
||||||
|
Column(u'id', types.Integer, primary_key=True),
|
||||||
|
Column(u'name', types.Unicode(128), nullable=False),
|
||||||
|
Column(u'publisher', types.Unicode(128))
|
||||||
|
)
|
||||||
|
|
||||||
|
# Definition of the "songs" table
|
||||||
|
songs_table = Table(u'songs', metadata,
|
||||||
|
Column(u'id', types.Integer, primary_key=True),
|
||||||
|
Column(u'song_book_id', types.Integer,
|
||||||
|
ForeignKey(u'song_books.id'), default=0),
|
||||||
|
Column(u'title', types.Unicode(255), nullable=False),
|
||||||
|
Column(u'lyrics', types.UnicodeText, nullable=False),
|
||||||
|
Column(u'verse_order', types.Unicode(128)),
|
||||||
|
Column(u'copyright', types.Unicode(255)),
|
||||||
|
Column(u'comments', types.UnicodeText),
|
||||||
|
Column(u'ccli_number', types.Unicode(64)),
|
||||||
|
Column(u'song_number', types.Unicode(64)),
|
||||||
|
Column(u'theme_name', types.Unicode(128)),
|
||||||
|
Column(u'search_title', types.Unicode(255), index=True, nullable=False),
|
||||||
|
Column(u'search_lyrics', types.UnicodeText, index=True, nullable=False)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Definition of the "topics" table
|
||||||
|
topics_table = Table(u'topics', metadata,
|
||||||
|
Column(u'id', types.Integer, primary_key=True),
|
||||||
|
Column(u'name', types.Unicode(128), nullable=False)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Definition of the "authors_songs" table
|
||||||
|
authors_songs_table = Table(u'authors_songs', metadata,
|
||||||
|
Column(u'author_id', types.Integer,
|
||||||
|
ForeignKey(u'authors.id'), primary_key=True),
|
||||||
|
Column(u'song_id', types.Integer,
|
||||||
|
ForeignKey(u'songs.id'), primary_key=True)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Definition of the "songs_topics" table
|
||||||
|
songs_topics_table = Table(u'songs_topics', metadata,
|
||||||
|
Column(u'song_id', types.Integer,
|
||||||
|
ForeignKey(u'songs.id'), primary_key=True),
|
||||||
|
Column(u'topic_id', types.Integer,
|
||||||
|
ForeignKey(u'topics.id'), primary_key=True)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Define table indexes
|
||||||
|
Index(u'authors_id', authors_table.c.id)
|
||||||
|
Index(u'authors_display_name_id', authors_table.c.display_name,
|
||||||
|
authors_table.c.id)
|
||||||
|
Index(u'song_books_id', song_books_table.c.id)
|
||||||
|
Index(u'songs_id', songs_table.c.id)
|
||||||
|
Index(u'topics_id', topics_table.c.id)
|
||||||
|
Index(u'authors_songs_author', authors_songs_table.c.author_id,
|
||||||
|
authors_songs_table.c.song_id)
|
||||||
|
Index(u'authors_songs_song', authors_songs_table.c.song_id,
|
||||||
|
authors_songs_table.c.author_id)
|
||||||
|
Index(u'topics_song_topic', songs_topics_table.c.topic_id,
|
||||||
|
songs_topics_table.c.song_id)
|
||||||
|
Index(u'topics_song_song', songs_topics_table.c.song_id,
|
||||||
|
songs_topics_table.c.topic_id)
|
||||||
|
|
||||||
|
mapper(Author, authors_table)
|
||||||
|
mapper(Book, song_books_table)
|
||||||
|
mapper(Song, songs_table,
|
||||||
|
properties={'authors': relation(Author, backref='songs',
|
||||||
|
secondary=authors_songs_table),
|
||||||
|
'book': relation(Book, backref='songs'),
|
||||||
|
'topics': relation(Topic, backref='songs',
|
||||||
|
secondary=songs_topics_table)})
|
||||||
|
mapper(Topic, topics_table)
|
||||||
|
|
||||||
|
metadata.create_all(checkfirst=True)
|
||||||
|
return session
|
@ -25,12 +25,8 @@
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from PyQt4 import QtCore
|
from openlp.core.lib.db import Manager
|
||||||
from sqlalchemy.exceptions import InvalidRequestError
|
from openlp.plugins.songs.lib.db import init_schema, Song, Author
|
||||||
|
|
||||||
from openlp.core.utils import AppLocation
|
|
||||||
from openlp.plugins.songs.lib.models import init_models, metadata, Song, \
|
|
||||||
Author, Topic, Book
|
|
||||||
#from openlp.plugins.songs.lib import OpenLyricsSong, OpenSongSong, CCLISong, \
|
#from openlp.plugins.songs.lib import OpenLyricsSong, OpenSongSong, CCLISong, \
|
||||||
# CSVSong
|
# CSVSong
|
||||||
|
|
||||||
@ -80,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.
|
||||||
@ -93,35 +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'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_models(self.db_url)
|
|
||||||
metadata.create_all(checkfirst=True)
|
|
||||||
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.
|
||||||
@ -144,175 +114,3 @@ 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):
|
|
||||||
"""
|
|
||||||
Get author by display name
|
|
||||||
"""
|
|
||||||
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):
|
|
||||||
"""
|
|
||||||
Get topic by name
|
|
||||||
"""
|
|
||||||
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):
|
|
||||||
"""
|
|
||||||
Get book by name
|
|
||||||
"""
|
|
||||||
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):
|
|
||||||
return self.session.query(Song).filter(Song.theme_name == theme).all()
|
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@ from openlp.core.lib import MediaManagerItem, SongXMLParser, \
|
|||||||
BaseListWithDnD, Receiver, ItemCapabilities, translate, check_item_selected
|
BaseListWithDnD, Receiver, ItemCapabilities, translate, check_item_selected
|
||||||
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__)
|
||||||
|
|
||||||
@ -268,7 +269,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]
|
||||||
@ -310,7 +311,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):
|
||||||
@ -331,7 +332,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='):
|
||||||
|
@ -1,38 +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 #
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
from sqlalchemy import MetaData
|
|
||||||
|
|
||||||
__all__ = ['session', 'metadata', 'engine']
|
|
||||||
|
|
||||||
# SQLAlchemy database engine. Updated by model.init_model()
|
|
||||||
engine = None
|
|
||||||
|
|
||||||
# SQLAlchemy session manager. Updated by model.init_model()
|
|
||||||
session = None
|
|
||||||
|
|
||||||
# Global metadata. If you have multiple databases with overlapping table
|
|
||||||
# names, you'll need a metadata for each database
|
|
||||||
metadata = MetaData()
|
|
@ -1,48 +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 #
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
from sqlalchemy import create_engine
|
|
||||||
from sqlalchemy.orm import scoped_session, sessionmaker, mapper, relation
|
|
||||||
|
|
||||||
from openlp.plugins.songs.lib.meta import metadata
|
|
||||||
from openlp.plugins.songs.lib.tables import *
|
|
||||||
from openlp.plugins.songs.lib.classes import *
|
|
||||||
|
|
||||||
def init_models(url):
|
|
||||||
engine = create_engine(url)
|
|
||||||
metadata.bind = engine
|
|
||||||
session = scoped_session(sessionmaker(autoflush=False, autocommit=False,
|
|
||||||
bind=engine))
|
|
||||||
mapper(Author, authors_table)
|
|
||||||
mapper(Book, song_books_table)
|
|
||||||
mapper(Song, songs_table,
|
|
||||||
properties={'authors': relation(Author, backref='songs',
|
|
||||||
secondary=authors_songs_table),
|
|
||||||
'book': relation(Book, backref='songs'),
|
|
||||||
'topics': relation(Topic, backref='songs',
|
|
||||||
secondary=songs_topics_table)})
|
|
||||||
mapper(Topic, topics_table)
|
|
||||||
return session
|
|
||||||
|
|
@ -27,7 +27,7 @@ import re
|
|||||||
|
|
||||||
from openlp.core.lib import SongXMLBuilder, translate
|
from openlp.core.lib import SongXMLBuilder, translate
|
||||||
from openlp.plugins.songs.lib import VerseType
|
from openlp.plugins.songs.lib import VerseType
|
||||||
from openlp.plugins.songs.lib.models import Song, Author, Topic, Book
|
from openlp.plugins.songs.lib.db import Song, Author, Topic, Book
|
||||||
|
|
||||||
class SongImport(object):
|
class SongImport(object):
|
||||||
"""
|
"""
|
||||||
@ -264,7 +264,6 @@ class SongImport(object):
|
|||||||
if len(self.authors) == 0:
|
if len(self.authors) == 0:
|
||||||
self.authors.append(u'Author unknown')
|
self.authors.append(u'Author unknown')
|
||||||
self.commit_song()
|
self.commit_song()
|
||||||
#self.print_song()
|
|
||||||
|
|
||||||
def commit_song(self):
|
def commit_song(self):
|
||||||
"""
|
"""
|
||||||
@ -303,30 +302,33 @@ class SongImport(object):
|
|||||||
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:
|
||||||
author = self.manager.get_author_by_name(authortext)
|
filter_string = u'display_name=%s' % authortext
|
||||||
|
author = self.manager.get_object_filtered(Author, filter_string)
|
||||||
if author is None:
|
if author is None:
|
||||||
author = Author()
|
author = Author()
|
||||||
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.save_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)
|
filter_string = u'name=%s' % self.song_book_name
|
||||||
|
song_book = self.manager.get_object_filtered(Book, filter_string)
|
||||||
if song_book is None:
|
if song_book is None:
|
||||||
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.save_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)
|
filter_string = u'name=%s' % topictext
|
||||||
|
topic = self.manager.get_object_filtered(Topic, filter_string)
|
||||||
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.save_object(topic)
|
||||||
song.topics.append(topictext)
|
song.topics.append(topictext)
|
||||||
self.manager.save_song(song)
|
self.manager.save_object(song)
|
||||||
|
|
||||||
def print_song(self):
|
def print_song(self):
|
||||||
"""
|
"""
|
||||||
@ -357,5 +359,3 @@ class SongImport(object):
|
|||||||
print u'THEME: ' + self.theme_name
|
print u'THEME: ' + self.theme_name
|
||||||
if self.ccli_number:
|
if self.ccli_number:
|
||||||
print u'CCLI: ' + self.ccli_number
|
print u'CCLI: ' + self.ccli_number
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,99 +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 #
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
from sqlalchemy import *
|
|
||||||
from sqlalchemy import Column, Table, ForeignKey, types
|
|
||||||
|
|
||||||
from openlp.plugins.songs.lib.meta import metadata
|
|
||||||
|
|
||||||
# Definition of the "authors" table
|
|
||||||
authors_table = Table(u'authors', metadata,
|
|
||||||
Column(u'id', types.Integer, primary_key=True),
|
|
||||||
Column(u'first_name', types.Unicode(128)),
|
|
||||||
Column(u'last_name', types.Unicode(128)),
|
|
||||||
Column(u'display_name', types.Unicode(255), nullable=False)
|
|
||||||
)
|
|
||||||
|
|
||||||
# Definition of the "song_books" table
|
|
||||||
song_books_table = Table(u'song_books', metadata,
|
|
||||||
Column(u'id', types.Integer, primary_key=True),
|
|
||||||
Column(u'name', types.Unicode(128), nullable=False),
|
|
||||||
Column(u'publisher', types.Unicode(128))
|
|
||||||
)
|
|
||||||
|
|
||||||
# Definition of the "songs" table
|
|
||||||
songs_table = Table(u'songs', metadata,
|
|
||||||
Column(u'id', types.Integer, primary_key=True),
|
|
||||||
Column(u'song_book_id', types.Integer,
|
|
||||||
ForeignKey(u'song_books.id'), default=0),
|
|
||||||
Column(u'title', types.Unicode(255), nullable=False),
|
|
||||||
Column(u'lyrics', types.UnicodeText, nullable=False),
|
|
||||||
Column(u'verse_order', types.Unicode(128)),
|
|
||||||
Column(u'copyright', types.Unicode(255)),
|
|
||||||
Column(u'comments', types.UnicodeText),
|
|
||||||
Column(u'ccli_number', types.Unicode(64)),
|
|
||||||
Column(u'song_number', types.Unicode(64)),
|
|
||||||
Column(u'theme_name', types.Unicode(128)),
|
|
||||||
Column(u'search_title', types.Unicode(255), index=True, nullable=False),
|
|
||||||
Column(u'search_lyrics', types.UnicodeText, index=True, nullable=False)
|
|
||||||
)
|
|
||||||
|
|
||||||
# Definition of the "topics" table
|
|
||||||
topics_table = Table(u'topics', metadata,
|
|
||||||
Column(u'id', types.Integer, primary_key=True),
|
|
||||||
Column(u'name', types.Unicode(128), nullable=False)
|
|
||||||
)
|
|
||||||
|
|
||||||
# Definition of the "authors_songs" table
|
|
||||||
authors_songs_table = Table(u'authors_songs', metadata,
|
|
||||||
Column(u'author_id', types.Integer,
|
|
||||||
ForeignKey(u'authors.id'), primary_key=True),
|
|
||||||
Column(u'song_id', types.Integer,
|
|
||||||
ForeignKey(u'songs.id'), primary_key=True)
|
|
||||||
)
|
|
||||||
|
|
||||||
# Definition of the "songs_topics" table
|
|
||||||
songs_topics_table = Table(u'songs_topics', metadata,
|
|
||||||
Column(u'song_id', types.Integer,
|
|
||||||
ForeignKey(u'songs.id'), primary_key=True),
|
|
||||||
Column(u'topic_id', types.Integer,
|
|
||||||
ForeignKey(u'topics.id'), primary_key=True)
|
|
||||||
)
|
|
||||||
|
|
||||||
# Define table indexes
|
|
||||||
Index(u'authors_id', authors_table.c.id)
|
|
||||||
Index(u'authors_display_name_id', authors_table.c.display_name,
|
|
||||||
authors_table.c.id)
|
|
||||||
Index(u'song_books_id', song_books_table.c.id)
|
|
||||||
Index(u'songs_id', songs_table.c.id)
|
|
||||||
Index(u'topics_id', topics_table.c.id)
|
|
||||||
Index(u'authors_songs_author', authors_songs_table.c.author_id,
|
|
||||||
authors_songs_table.c.song_id)
|
|
||||||
Index(u'authors_songs_song', authors_songs_table.c.song_id,
|
|
||||||
authors_songs_table.c.author_id)
|
|
||||||
Index(u'topics_song_topic', songs_topics_table.c.topic_id,
|
|
||||||
songs_topics_table.c.song_id)
|
|
||||||
Index(u'topics_song_song', songs_topics_table.c.song_id,
|
|
||||||
songs_topics_table.c.topic_id)
|
|
@ -30,6 +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.plugins.songs.lib import SongManager, SongMediaItem, SongsTab
|
from openlp.plugins.songs.lib import SongManager, SongMediaItem, SongsTab
|
||||||
|
from openlp.plugins.songs.lib.db import Song
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from openlp.plugins.songs.lib import SofImport, OooImport
|
from openlp.plugins.songs.lib import SofImport, OooImport
|
||||||
@ -39,7 +40,6 @@ except ImportError:
|
|||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class SongsPlugin(Plugin):
|
class SongsPlugin(Plugin):
|
||||||
"""
|
"""
|
||||||
This is the number 1 plugin, if importance were placed on any
|
This is the number 1 plugin, if importance were placed on any
|
||||||
@ -69,7 +69,8 @@ class SongsPlugin(Plugin):
|
|||||||
# self.songmanager = SongManager()
|
# self.songmanager = SongManager()
|
||||||
Plugin.initialise(self)
|
Plugin.initialise(self)
|
||||||
self.insert_toolbox_item()
|
self.insert_toolbox_item()
|
||||||
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')
|
||||||
@ -198,6 +199,7 @@ class SongsPlugin(Plugin):
|
|||||||
return about_text
|
return about_text
|
||||||
|
|
||||||
def can_delete_theme(self, theme):
|
def can_delete_theme(self, theme):
|
||||||
if len(self.manager.get_songs_for_theme(theme)) == 0:
|
filter_string = u'theme_name=%s' % theme
|
||||||
|
if not self.manager.get_all_objects_filtered(Song, filter_string):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
@ -74,16 +74,16 @@ class SongUsageDetailForm(QtGui.QDialog, Ui_SongUsageDetailDialog):
|
|||||||
filename = u'usage_detail_%s_%s.txt' % (
|
filename = u'usage_detail_%s_%s.txt' % (
|
||||||
self.FromDate.selectedDate().toString(u'ddMMyyyy'),
|
self.FromDate.selectedDate().toString(u'ddMMyyyy'),
|
||||||
self.ToDate.selectedDate().toString(u'ddMMyyyy'))
|
self.ToDate.selectedDate().toString(u'ddMMyyyy'))
|
||||||
usage = self.parent.songusagemanager.get_all_songusage(
|
usage = self.parent.songusagemanager.get_songusage_for_period(
|
||||||
self.FromDate.selectedDate(), self.ToDate.selectedDate())
|
self.FromDate.selectedDate(), self.ToDate.selectedDate())
|
||||||
outname = os.path.join(unicode(self.FileLineEdit.text()), filename)
|
outname = os.path.join(unicode(self.FileLineEdit.text()), filename)
|
||||||
file = None
|
file = None
|
||||||
try:
|
try:
|
||||||
file = open(outname, u'w')
|
file = open(outname, u'w')
|
||||||
for instance in usage:
|
for instance in usage:
|
||||||
record = u'\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"\n' % \
|
record = u'\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"\n' % (
|
||||||
(instance.usagedate,instance.usagetime, instance.title,
|
instance.usagedate, instance.usagetime, instance.title,
|
||||||
instance.copyright, instance.ccl_number , instance.authors)
|
instance.copyright, instance.ccl_number, instance.authors)
|
||||||
file.write(record)
|
file.write(record)
|
||||||
except IOError:
|
except IOError:
|
||||||
log.exception(u'Failed to write out song usage records')
|
log.exception(u'Failed to write out song usage records')
|
||||||
|
@ -22,5 +22,7 @@
|
|||||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
"""
|
||||||
from manager import SongUsageManager
|
The :mod:`lib` module contains the library functions for the songusage plugin.
|
||||||
|
"""
|
||||||
|
from openlp.plugins.songusage.lib.manager import SongUsageManager
|
||||||
|
@ -1,32 +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 #
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
from openlp.core.lib import BaseModel
|
|
||||||
|
|
||||||
class SongUsageItem(BaseModel):
|
|
||||||
"""
|
|
||||||
Audit model
|
|
||||||
"""
|
|
||||||
pass
|
|
@ -22,18 +22,42 @@
|
|||||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
"""
|
||||||
|
The :mod:`db` module provides the database and schema that is the backend for
|
||||||
|
the SongUsage plugin
|
||||||
|
"""
|
||||||
|
|
||||||
from sqlalchemy import create_engine
|
from sqlalchemy import Column, Table, types
|
||||||
from sqlalchemy.orm import scoped_session, sessionmaker, mapper
|
from sqlalchemy.orm import mapper
|
||||||
|
|
||||||
from openlp.plugins.songusage.lib.meta import metadata
|
from openlp.core.lib.db import BaseModel, init_db
|
||||||
from openlp.plugins.songusage.lib.tables import *
|
|
||||||
from openlp.plugins.songusage.lib.classes import *
|
class SongUsageItem(BaseModel):
|
||||||
|
"""
|
||||||
|
SongUsageItem model
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def init_schema(url):
|
||||||
|
"""
|
||||||
|
Setup the songusage database connection and initialise the database schema
|
||||||
|
|
||||||
|
``url``
|
||||||
|
The database to setup
|
||||||
|
"""
|
||||||
|
session, metadata = init_db(url)
|
||||||
|
|
||||||
|
songusage_table = Table(u'songusage_data', metadata,
|
||||||
|
Column(u'id', types.Integer(), primary_key=True),
|
||||||
|
Column(u'usagedate', types.Date, index=True, nullable=False),
|
||||||
|
Column(u'usagetime', types.Time, index=True, nullable=False),
|
||||||
|
Column(u'title', types.Unicode(255), nullable=False),
|
||||||
|
Column(u'authors', types.Unicode(255), nullable=False),
|
||||||
|
Column(u'copyright', types.Unicode(255)),
|
||||||
|
Column(u'ccl_number', types.Unicode(65))
|
||||||
|
)
|
||||||
|
|
||||||
def init_models(url):
|
|
||||||
engine = create_engine(url)
|
|
||||||
metadata.bind = engine
|
|
||||||
session = scoped_session(sessionmaker(autoflush=True, autocommit=False,
|
|
||||||
bind=engine))
|
|
||||||
mapper(SongUsageItem, songusage_table)
|
mapper(SongUsageItem, songusage_table)
|
||||||
|
|
||||||
|
metadata.create_all(checkfirst=True)
|
||||||
return session
|
return session
|
@ -25,16 +25,14 @@
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from PyQt4 import QtCore
|
|
||||||
from sqlalchemy.exceptions import InvalidRequestError
|
from sqlalchemy.exceptions import InvalidRequestError
|
||||||
|
|
||||||
from openlp.core.utils import AppLocation
|
from openlp.core.lib.db import Manager
|
||||||
from openlp.plugins.songusage.lib.models import init_models, metadata, \
|
from openlp.plugins.songusage.lib.db import init_schema, SongUsageItem
|
||||||
SongUsageItem
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
class SongUsageManager(object):
|
class SongUsageManager(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.
|
||||||
@ -47,98 +45,31 @@ class SongUsageManager(object):
|
|||||||
don't exist.
|
don't exist.
|
||||||
"""
|
"""
|
||||||
log.debug(u'SongUsage Initialising')
|
log.debug(u'SongUsage Initialising')
|
||||||
settings = QtCore.QSettings()
|
Manager.__init__(self, u'songusage', init_schema)
|
||||||
settings.beginGroup(u'songusage')
|
|
||||||
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/songusage.sqlite' % \
|
|
||||||
AppLocation.get_section_data_path(u'songusage')
|
|
||||||
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_models(self.db_url)
|
|
||||||
metadata.create_all(checkfirst=True)
|
|
||||||
settings.endGroup()
|
|
||||||
log.debug(u'SongUsage Initialised')
|
log.debug(u'SongUsage Initialised')
|
||||||
|
|
||||||
def get_all_songusage(self, start_date, end_date):
|
def get_songusage_for_period(self, start_date, end_date):
|
||||||
"""
|
"""
|
||||||
Returns the details of SongUsage
|
Returns the details of SongUsage for a designated time period
|
||||||
|
|
||||||
|
``start_date``
|
||||||
|
The start of the period to return
|
||||||
|
|
||||||
|
``end_date``
|
||||||
|
The end of the period to return
|
||||||
"""
|
"""
|
||||||
return self.session.query(SongUsageItem) \
|
return self.session.query(SongUsageItem) \
|
||||||
.filter(SongUsageItem.usagedate >= start_date.toPyDate()) \
|
.filter(SongUsageItem.usagedate >= start_date.toPyDate()) \
|
||||||
.filter(SongUsageItem.usagedate < end_date.toPyDate()) \
|
.filter(SongUsageItem.usagedate < end_date.toPyDate()) \
|
||||||
.order_by(SongUsageItem.usagedate, SongUsageItem.usagetime ).all()
|
.order_by(SongUsageItem.usagedate, SongUsageItem.usagetime).all()
|
||||||
|
|
||||||
def insert_songusage(self, songusageitem):
|
|
||||||
"""
|
|
||||||
Saves an SongUsage to the database
|
|
||||||
"""
|
|
||||||
log.debug(u'SongUsage added')
|
|
||||||
try:
|
|
||||||
self.session.add(songusageitem)
|
|
||||||
self.session.commit()
|
|
||||||
return True
|
|
||||||
except InvalidRequestError:
|
|
||||||
self.session.rollback()
|
|
||||||
log.exception(u'SongUsage item failed to save')
|
|
||||||
return False
|
|
||||||
|
|
||||||
def get_songusage(self, id=None):
|
|
||||||
"""
|
|
||||||
Returns the details of a SongUsage
|
|
||||||
"""
|
|
||||||
if id is None:
|
|
||||||
return SongUsageItem()
|
|
||||||
else:
|
|
||||||
return self.session.query(SongUsageItem).get(id)
|
|
||||||
|
|
||||||
def delete_songusage(self, id):
|
|
||||||
"""
|
|
||||||
Delete a SongUsage record
|
|
||||||
"""
|
|
||||||
if id != 0:
|
|
||||||
songusageitem = self.get_songusage(id)
|
|
||||||
try:
|
|
||||||
self.session.delete(songusageitem)
|
|
||||||
self.session.commit()
|
|
||||||
return True
|
|
||||||
except InvalidRequestError:
|
|
||||||
self.session.rollback()
|
|
||||||
log.exception(u'SongUsage Item failed to delete')
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
return True
|
|
||||||
|
|
||||||
def delete_all(self):
|
|
||||||
"""
|
|
||||||
Delete all Song Usage records
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
self.session.query(SongUsageItem).delete(synchronize_session=False)
|
|
||||||
self.session.commit()
|
|
||||||
return True
|
|
||||||
except InvalidRequestError:
|
|
||||||
self.session.rollback()
|
|
||||||
log.exception(u'Failed to delete all Song Usage items')
|
|
||||||
return False
|
|
||||||
|
|
||||||
def delete_to_date(self, date):
|
def delete_to_date(self, date):
|
||||||
"""
|
"""
|
||||||
Delete SongUsage records before given date
|
Delete SongUsage records before given date
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
self.session.query(SongUsageItem)\
|
self.session.query(SongUsageItem) \
|
||||||
.filter(SongUsageItem.usagedate <= date)\
|
.filter(SongUsageItem.usagedate <= date) \
|
||||||
.delete(synchronize_session=False)
|
.delete(synchronize_session=False)
|
||||||
self.session.commit()
|
self.session.commit()
|
||||||
return True
|
return True
|
||||||
@ -146,4 +77,3 @@ class SongUsageManager(object):
|
|||||||
self.session.rollback()
|
self.session.rollback()
|
||||||
log.exception(u'Failed to delete all Song Usage items to %s' % date)
|
log.exception(u'Failed to delete all Song Usage items to %s' % date)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -1,38 +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 #
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
from sqlalchemy import MetaData
|
|
||||||
|
|
||||||
__all__ = ['session', 'metadata', 'engine']
|
|
||||||
|
|
||||||
# SQLAlchemy database engine. Updated by model.init_model()
|
|
||||||
engine = None
|
|
||||||
|
|
||||||
# SQLAlchemy session manager. Updated by model.init_model()
|
|
||||||
session = None
|
|
||||||
|
|
||||||
# Global metadata. If you have multiple databases with overlapping table
|
|
||||||
# names, you'll need a metadata for each database
|
|
||||||
metadata = MetaData()
|
|
@ -1,39 +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 #
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
from sqlalchemy import Column, Table, types
|
|
||||||
|
|
||||||
from openlp.plugins.songusage.lib.meta import metadata
|
|
||||||
|
|
||||||
# Definition of the "songusage" table
|
|
||||||
songusage_table = Table(u'songusage_data', metadata,
|
|
||||||
Column(u'id', types.Integer(), primary_key=True),
|
|
||||||
Column(u'usagedate', types.Date, index=True, nullable=False),
|
|
||||||
Column(u'usagetime', types.Time, index=True, nullable=False),
|
|
||||||
Column(u'title', types.Unicode(255), nullable=False),
|
|
||||||
Column(u'authors', types.Unicode(255), nullable=False),
|
|
||||||
Column(u'copyright', types.Unicode(255)),
|
|
||||||
Column(u'ccl_number', types.Unicode(65))
|
|
||||||
)
|
|
@ -23,16 +23,16 @@
|
|||||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
from datetime import datetime
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
from datetime import datetime
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
from openlp.core.lib import Plugin, Receiver, build_icon, translate
|
from openlp.core.lib import Plugin, Receiver, build_icon, translate
|
||||||
from openlp.plugins.songusage.lib import SongUsageManager
|
from openlp.plugins.songusage.lib import SongUsageManager
|
||||||
from openlp.plugins.songusage.forms import SongUsageDetailForm, \
|
from openlp.plugins.songusage.forms import SongUsageDetailForm, \
|
||||||
SongUsageDeleteForm
|
SongUsageDeleteForm
|
||||||
from openlp.plugins.songusage.lib.models import SongUsageItem
|
from openlp.plugins.songusage.lib.db import SongUsageItem
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -148,7 +148,7 @@ class SongUsagePlugin(Plugin):
|
|||||||
song_usage_item.authors = u''
|
song_usage_item.authors = u''
|
||||||
for author in audit[1]:
|
for author in audit[1]:
|
||||||
song_usage_item.authors += author + u' '
|
song_usage_item.authors += author + u' '
|
||||||
self.songusagemanager.insert_songusage(song_usage_item)
|
self.songusagemanager.save_object(song_usage_item)
|
||||||
|
|
||||||
def onSongUsageDelete(self):
|
def onSongUsageDelete(self):
|
||||||
self.SongUsagedeleteform.exec_()
|
self.SongUsagedeleteform.exec_()
|
||||||
|
Loading…
Reference in New Issue
Block a user