This commit is contained in:
Tim Bentley 2010-06-28 20:14:31 +01:00
commit ebb368559f
54 changed files with 800 additions and 1470 deletions

View File

@ -22,7 +22,6 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
"""
The :mod:`lib` module contains most of the components and libraries that make
OpenLP work.
@ -47,6 +46,10 @@ def translate(context, text, comment=None):
``text``
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)
@ -115,6 +118,18 @@ def build_icon(icon):
def context_menu_action(base, icon, text, slot):
"""
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)
if icon:
@ -125,6 +140,15 @@ def context_menu_action(base, icon, text, slot):
def context_menu(base, icon, text):
"""
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.setIcon(build_icon(icon))
@ -133,6 +157,9 @@ def context_menu(base, icon, text):
def context_menu_separator(base):
"""
Add a separator to a context menu
``base``
The menu object to add the separator to
"""
action = QtGui.QAction(u'', base)
action.setSeparator(True)
@ -200,5 +227,4 @@ from themexmlhandler import ThemeXML
from renderer import Renderer
from rendermanager import RenderManager
from mediamanageritem import MediaManagerItem
from basemodel import BaseModel
from baselistwithdnd import BaseListWithDnD

View File

@ -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
View 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

View File

@ -28,7 +28,9 @@ import logging
from PyQt4 import QtCore, QtGui
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
log = logging.getLogger(__name__)
@ -41,11 +43,14 @@ class alertsPlugin(Plugin):
self.weight = -3
self.icon = build_icon(u':/media/media_image.png')
self.alertsmanager = AlertsManager(self)
self.manager = DBManager()
self.manager = Manager(u'alerts', init_schema)
self.alertForm = AlertForm(self.manager, self)
self.status = PluginStatus.Active
def get_settings_tab(self):
"""
Return the settings tab for the Alerts plugin
"""
self.alertsTab = AlertsTab(self)
return self.alertsTab

View File

@ -25,8 +25,8 @@
from PyQt4 import QtGui, QtCore
from openlp.plugins.alerts.lib.models import AlertItem
from openlp.core.lib import translate
from openlp.plugins.alerts.lib.db import AlertItem
from alertdialog import Ui_AlertDialog
@ -62,7 +62,7 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
def loadList(self):
self.AlertListWidget.clear()
alerts = self.manager.get_all_alerts()
alerts = self.manager.get_all_objects(AlertItem, AlertItem.text)
for alert in alerts:
item_name = QtGui.QListWidgetItem(alert.text)
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(alert.id))
@ -82,7 +82,7 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
item = self.AlertListWidget.currentItem()
if item:
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)
self.AlertListWidget.takeItem(row)
self.AlertTextEdit.setText(u'')
@ -98,7 +98,7 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
else:
alert = AlertItem()
alert.text = unicode(self.AlertTextEdit.text())
self.manager.save_alert(alert)
self.manager.save_object(alert)
self.AlertTextEdit.setText(u'')
self.loadList()
@ -107,9 +107,9 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
Save an alert
"""
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())
self.manager.save_alert(alert)
self.manager.save_object(alert)
self.item_id = None
self.loadList()
else:

View File

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

View File

@ -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

View File

@ -22,18 +22,36 @@
# 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 Alerts plugin
"""
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker, mapper
from sqlalchemy import Column, Table, types
from sqlalchemy.orm import mapper
from openlp.plugins.alerts.lib.meta import metadata
from openlp.plugins.alerts.lib.tables import *
from openlp.plugins.alerts.lib.classes import *
from openlp.core.lib.db import BaseModel, init_db
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)
metadata.create_all(checkfirst=True)
return session

View File

@ -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

View File

@ -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()

View File

@ -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))

View File

@ -32,6 +32,7 @@ from PyQt4 import QtCore, QtGui
from bibleimportwizard import Ui_BibleImportWizard
from openlp.core.lib import Receiver, SettingsManager, translate
from openlp.core.lib.db import delete_database
from openlp.core.utils import AppLocation
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.
"""
self.getFileName(
translate('BiblesPlugin.ImportWizardForm', 'Open OSIS File'),
translate('BiblesPlugin.ImportWizardForm', 'Open OSIS File'),
self.OSISLocationEdit)
def onBooksFileButtonClicked(self):
@ -239,10 +240,8 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
"""
Show the file open dialog for the verses CSV file.
"""
self.getFileName(
translate('BiblesPlugin.ImportWizardForm',
'Open Verses CSV File'),
self.CsvVerseLocationEdit)
self.getFileName(translate('BiblesPlugin.ImportWizardForm',
'Open Verses CSV File'), self.CsvVerseLocationEdit)
def onOpenSongBrowseButtonClicked(self):
"""
@ -451,7 +450,7 @@ class ImportWizardForm(QtGui.QWizard, Ui_BibleImportWizard):
self.ImportProgressLabel.setText(
translate('BiblesPlugin.ImportWizardForm',
'Your Bible import failed.'))
importer.delete()
delete_database(self.bibleplugin.settingsSection, importer.file)
def postImport(self):
self.ImportProgressBar.setValue(self.ImportProgressBar.maximum())

View File

@ -97,11 +97,11 @@ class CSVBible(BibleDB):
book_ptr = book.name
self.wizard.incrementProgressBar(
u'Importing %s %s' % (book.name, line[1]))
self.commit()
self.session.commit()
self.create_verse(book.id, line[1], line[2],
unicode(line[3], details['encoding']))
Receiver.send_message(u'openlp_process_events')
self.commit()
self.session.commit()
except IOError:
log.exception(u'Loading verses from file failed')
success = False
@ -113,5 +113,3 @@ class CSVBible(BibleDB):
return False
else:
return success

View File

@ -23,20 +23,99 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
import os
import logging
import chardet
import re
from sqlalchemy import or_
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.plugins.bibles.lib.models import *
from openlp.core.lib.db import BaseModel, init_db, Manager
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
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)
if u'file' in kwargs:
self.file = kwargs[u'file']
self.db_file = os.path.join(kwargs[u'path'], 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)
Manager.__init__(self, u'bibles', init_schema, self.file)
if u'file' in kwargs:
self.get_name()
self.wizard = None
def stop_import(self):
"""
@ -105,7 +168,7 @@ class BibleDB(QtCore.QObject):
"""
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:
self.name = version_name.value
else:
@ -125,16 +188,6 @@ class BibleDB(QtCore.QObject):
old_filename = re.sub(r'[^\w]+', u'_', old_filename).strip(u'_')
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):
"""
This method basically just initialialises the database. It is called
@ -146,36 +199,11 @@ class BibleDB(QtCore.QObject):
The actual Qt wizard form.
"""
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_testament(u'Old Testament')
self.create_testament(u'New Testament')
self.create_testament(u'Apocrypha')
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()
self.save_object(Testament.populate(name=u'Old Testament'))
self.save_object(Testament.populate(name=u'New Testament'))
self.save_object(Testament.populate(name=u'Apocrypha'))
return self.name
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)
book = Book.populate(name=name, abbreviation=abbrev,
testament_id=testament)
self.session.add(book)
self.commit()
self.save_object(book)
return book
def create_chapter(self, book_id, chapter, textlist):
@ -221,7 +248,7 @@ class BibleDB(QtCore.QObject):
text = verse_text
)
self.session.add(verse)
self.commit()
self.session.commit()
def create_verse(self, book_id, chapter, verse, text):
"""
@ -252,31 +279,32 @@ class BibleDB(QtCore.QObject):
return verse
def create_meta(self, key, value):
log.debug(u'save_meta %s/%s', key, value)
self.session.add(BibleMeta.populate(key=key, value=value))
self.commit()
"""
Utility method to save BibleMeta objects in a Bible database
def get_books(self):
log.debug(u'BibleDB.get_books()')
return self.session.query(Book).order_by(Book.id).all()
``key``
The key for this instance
``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):
log.debug(u'BibleDb.get_book("%s")', book)
db_book = self.session.query(Book)\
.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
"""
Return a book object from the database
def get_chapter(self, id, chapter):
log.debug(u'BibleDB.get_chapter("%s", %s)', id, chapter)
return self.session.query(Verse)\
.filter_by(chapter=chapter)\
.filter_by(book_id=id)\
.first()
``book``
The name of the book to return
"""
log.debug(u'BibleDb.get_book("%s")', book)
db_book = self.session.query(Book).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_verses(self, reference_list):
"""
@ -351,6 +379,12 @@ class BibleDB(QtCore.QObject):
return verses
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)
count = self.session.query(Verse.chapter).join(Book)\
.filter(Book.name==book)\
@ -361,6 +395,15 @@ class BibleDB(QtCore.QObject):
return count
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)
count = self.session.query(Verse).join(Book)\
.filter(Book.name==book)\
@ -371,20 +414,10 @@ class BibleDB(QtCore.QObject):
else:
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):
"""
Utility debugging method to dump the contents of a bible
"""
log.debug(u'.........Dumping Bible Database')
log.debug('...............................Books ')
books = self.session.query(Book).all()

View File

@ -35,8 +35,7 @@ from openlp.core.lib import Receiver
from openlp.core.utils import AppLocation
from openlp.plugins.bibles.lib.common import BibleCommon, SearchResults, \
unescape
from openlp.plugins.bibles.lib.db import BibleDB
from openlp.plugins.bibles.lib.models import Book
from openlp.plugins.bibles.lib.db import BibleDB, Book
log = logging.getLogger(__name__)

View File

@ -29,12 +29,12 @@ from PyQt4 import QtCore
from openlp.core.lib import SettingsManager
from openlp.core.utils import AppLocation
from openlp.plugins.bibles.lib.db import BibleDB, Book, BibleMeta
from common import parse_reference
from opensong import OpenSongBible
from osis import OSISBible
from csvbible import CSVBible
from db import BibleDB
from http import HTTPBible
log = logging.getLogger(__name__)
@ -137,11 +137,13 @@ class BibleManager(object):
log.debug(u'Bible Name: "%s"', name)
self.db_cache[name] = bible
# 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:
download_name = \
self.db_cache[name].get_meta(u'download name').value
meta_proxy = self.db_cache[name].get_meta(u'proxy url')
download_name = self.db_cache[name].get_object(BibleMeta,
u'download name').value
meta_proxy = self.db_cache[name].get_object(BibleMeta,
u'proxy url')
web_bible = HTTPBible(self.parent, path=self.path,
file=filename, download_source=source.value,
download_name=download_name)
@ -196,7 +198,7 @@ class BibleManager(object):
u'name': 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):
@ -249,7 +251,7 @@ class BibleManager(object):
Returns the meta data for a given 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):
"""

View File

@ -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)

View File

@ -90,7 +90,7 @@ class OpenSongBible(BibleDB):
QtCore.QString('%s %s %s' % (
translate('BiblesPlugin.Opensong', 'Importing'), \
db_book.name, chapter.attrib[u'n'])))
self.commit()
self.session.commit()
except IOError:
log.exception(u'Loading bible from OpenSong file failed')
success = False

View File

@ -140,7 +140,7 @@ class OSISBible(BibleDB):
self.wizard.ImportProgressBar.setMaximum(260)
if last_chapter != chapter:
if last_chapter != 0:
self.commit()
self.session.commit()
self.wizard.incrementProgressBar(
u'Importing %s %s...' % \
(self.books[match.group(1)][0], chapter))
@ -169,7 +169,7 @@ class OSISBible(BibleDB):
verse_text = self.spaces_regex.sub(u' ', verse_text)
self.create_verse(db_book.id, chapter, verse, verse_text)
Receiver.send_message(u'openlp_process_events')
self.commit()
self.session.commit()
self.wizard.incrementProgressBar(u'Finishing import...')
if match_count == 0:
success = False

View File

@ -26,8 +26,11 @@
import logging
from forms import EditCustomForm
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__)
@ -45,7 +48,7 @@ class CustomPlugin(Plugin):
def __init__(self, plugin_helpers):
Plugin.__init__(self, u'Custom', u'1.9.2', plugin_helpers)
self.weight = -5
self.custommanager = CustomManager()
self.custommanager = Manager(u'custom', init_schema)
self.edit_custom_form = EditCustomForm(self.custommanager)
self.icon = build_icon(u':/media/media_custom.png')
self.status = PluginStatus.Active
@ -75,6 +78,8 @@ class CustomPlugin(Plugin):
return about_text
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 False

View File

@ -29,7 +29,7 @@ from PyQt4 import QtCore, QtGui
from editcustomdialog import Ui_customEditDialog
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__)
@ -116,7 +116,7 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog):
self.customSlide = CustomSlide()
self.initialise()
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.CreditEdit.setText(self.customSlide.credits)
songXML = SongXMLParser(self.customSlide.text)
@ -166,8 +166,7 @@ class EditCustomForm(QtGui.QDialog, Ui_customEditDialog):
u'utf-8')
self.customSlide.theme_name = unicode(self.ThemeComboBox.currentText(),
u'utf-8')
self.custommanager.save_slide(self.customSlide)
return True
return self.custommanager.save_object(self.customSlide)
def onUpButtonPressed(self):
selectedRow = self.VerseListView.currentRow()

View File

@ -23,6 +23,5 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
from manager import CustomManager
from mediaitem import CustomMediaItem
from customtab import CustomTab

View File

@ -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

View File

@ -22,18 +22,40 @@
# 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 Custom plugin
"""
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker, mapper
from sqlalchemy import Column, Table, types
from sqlalchemy.orm import mapper
from openlp.plugins.custom.lib.meta import metadata
from openlp.plugins.custom.lib.tables import *
from openlp.plugins.custom.lib.classes import *
from openlp.core.lib.db import BaseModel, init_db
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)
metadata.create_all(checkfirst=True)
return session

View File

@ -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()

View File

@ -29,6 +29,7 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import MediaManagerItem, SongXMLParser, BaseListWithDnD, \
Receiver, ItemCapabilities, translate, check_item_selected
from openlp.plugins.custom.lib.db import CustomSlide
log = logging.getLogger(__name__)
@ -72,7 +73,8 @@ class CustomMediaItem(MediaManagerItem):
MediaManagerItem.requiredIcons(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
#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.
@ -84,10 +86,10 @@ class CustomMediaItem(MediaManagerItem):
def loadCustomListView(self, list):
self.ListView.clear()
for CustomSlide in list:
custom_name = QtGui.QListWidgetItem(CustomSlide.title)
for customSlide in list:
custom_name = QtGui.QListWidgetItem(customSlide.title)
custom_name.setData(
QtCore.Qt.UserRole, QtCore.QVariant(CustomSlide.id))
QtCore.Qt.UserRole, QtCore.QVariant(customSlide.id))
self.ListView.addItem(custom_name)
def onNewClick(self):
@ -106,7 +108,7 @@ class CustomMediaItem(MediaManagerItem):
type of display is required.
"""
fields = customid.split(u':')
valid = self.parent.custommanager.get_custom(fields[1])
valid = self.parent.custommanager.get_object(CustomSlide, fields[1])
if valid:
self.remoteCustom = fields[1]
self.remoteTriggered = fields[0]
@ -136,7 +138,7 @@ class CustomMediaItem(MediaManagerItem):
'You must select an item to delete.')):
item = self.ListView.currentItem()
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)
self.ListView.takeItem(row)
@ -158,7 +160,7 @@ class CustomMediaItem(MediaManagerItem):
service_item.add_capability(ItemCapabilities.AllowsEdit)
service_item.add_capability(ItemCapabilities.AllowsPreview)
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
credit = customSlide.credits
service_item.editId = item_id

View File

@ -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()

View File

@ -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))
)

View File

@ -24,6 +24,7 @@
###############################################################################
from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate
class Ui_AuthorsDialog(object):

View File

@ -28,7 +28,6 @@ from PyQt4 import QtGui, QtCore
from openlp.core.lib import translate
from openlp.plugins.songs.forms.authorsdialog import Ui_AuthorsDialog
class AuthorsForm(QtGui.QDialog, Ui_AuthorsDialog):
"""
Class to control the Maintenance of Authors Dialog

View File

@ -24,9 +24,8 @@
###############################################################################
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):
def setupUi(self, EditSongDialog):

View File

@ -31,7 +31,7 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import SongXMLBuilder, SongXMLParser, Receiver, translate
from openlp.plugins.songs.forms import EditVerseForm
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
log = logging.getLogger(__name__)
@ -118,7 +118,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.TopicRemoveButton.setEnabled(False)
def loadAuthors(self):
authors = self.songmanager.get_authors()
authors = self.songmanager.get_all_objects(Author, Author.display_name)
self.AuthorsSelectionComboItem.clear()
self.AuthorsSelectionComboItem.addItem(u'')
for author in authors:
@ -128,7 +128,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
row, QtCore.QVariant(author.id))
def loadTopics(self):
topics = self.songmanager.get_topics()
topics = self.songmanager.get_all_objects(Topic, Topic.name)
self.SongTopicCombo.clear()
self.SongTopicCombo.addItem(u'')
for topic in topics:
@ -137,7 +137,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.SongTopicCombo.setItemData(row, QtCore.QVariant(topic.id))
def loadBooks(self):
books = self.songmanager.get_books()
books = self.songmanager.get_all_objects(Book, Book.name)
self.SongbookCombo.clear()
self.SongbookCombo.addItem(u'')
for book in books:
@ -178,11 +178,12 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.loadAuthors()
self.loadTopics()
self.loadBooks()
self.song = self.songmanager.get_song(id)
self.song = self.songmanager.get_object(Song, id)
self.TitleEditItem.setText(self.song.title)
title = self.song.search_title.split(u'@')
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(
unicode(book_name.name), QtCore.Qt.MatchExactly)
if id == -1:
@ -289,7 +290,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
QtGui.QMessageBox.Yes) == QtGui.QMessageBox.Yes:
author = Author.populate(first_name=text.rsplit(u' ', 1)[0],
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)
author_item = QtGui.QListWidgetItem(
unicode(author.display_name))
@ -302,7 +303,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
return
elif item > 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)
author_item = QtGui.QListWidgetItem(unicode(author.display_name))
author_item.setData(QtCore.Qt.UserRole, QtCore.QVariant(author.id))
@ -325,7 +326,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.AuthorRemoveButton.setEnabled(False)
item = self.AuthorsListView.currentItem()
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)
row = self.AuthorsListView.row(item)
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.Yes:
topic = Topic.populate(name=text)
self.songmanager.save_topic(topic)
self.songmanager.save_object(topic)
self.song.topics.append(topic)
topic_item = QtGui.QListWidgetItem(unicode(topic.name))
topic_item.setData(QtCore.Qt.UserRole,
@ -353,7 +354,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
return
elif item > 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)
topic_item = QtGui.QListWidgetItem(unicode(topic.name))
topic_item.setData(QtCore.Qt.UserRole, QtCore.QVariant(topic.id))
@ -375,7 +376,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.TopicRemoveButton.setEnabled(False)
item = self.TopicsListView.currentItem()
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)
row = self.TopicsListView.row(item)
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.Yes:
book = Book.populate(name=text)
self.songmanager.save_book(book)
self.songmanager.save_object(book)
self.song.book = book
self.loadBooks()
else:
@ -630,7 +631,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
if self._validate_song():
self.processLyrics()
self.processTitle()
self.songmanager.save_song(self.song)
self.songmanager.save_object(self.song)
return True
return False

View File

@ -24,6 +24,7 @@
###############################################################################
from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate
class Ui_SongBookDialog(object):

View File

@ -28,7 +28,6 @@ from PyQt4 import QtGui
from openlp.core.lib import translate
from openlp.plugins.songs.forms.songbookdialog import Ui_SongBookDialog
class SongBookForm(QtGui.QDialog, Ui_SongBookDialog):
"""
Class documentation goes here.

View File

@ -25,12 +25,10 @@
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.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):
"""
@ -81,17 +79,17 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
else:
return -1
def _deleteItem(self, list_widget, get_func, del_func, reset_func,
dlg_title, del_text, err_text, sel_text):
def _deleteItem(self, item_class, list_widget, reset_func, dlg_title,
del_text, err_text, sel_text):
item_id = self._getCurrentItemId(list_widget)
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 QtGui.QMessageBox.warning(self, dlg_title, del_text,
QtGui.QMessageBox.StandardButtons(
QtGui.QMessageBox.No | QtGui.QMessageBox.Yes)
) == QtGui.QMessageBox.Yes:
del_func(item.id)
self.songmanager.delete_object(item_class, item.id)
reset_func()
else:
QtGui.QMessageBox.critical(self, dlg_title, err_text)
@ -100,7 +98,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
def resetAuthors(self):
self.AuthorsListWidget.clear()
authors = self.songmanager.get_authors()
authors = self.songmanager.get_all_objects(Author, Author.display_name)
for author in authors:
if author.display_name:
author_name = QtGui.QListWidgetItem(author.display_name)
@ -112,7 +110,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
def resetTopics(self):
self.TopicsListWidget.clear()
topics = self.songmanager.get_topics()
topics = self.songmanager.get_all_objects(Topic, Topic.name)
for topic in topics:
topic_name = QtGui.QListWidgetItem(topic.name)
topic_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(topic.id))
@ -120,7 +118,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
def resetBooks(self):
self.BooksListWidget.clear()
books = self.songmanager.get_books()
books = self.songmanager.get_all_objects(Book, Book.name)
for book in books:
book_name = QtGui.QListWidgetItem(book.name)
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()),
last_name=unicode(self.authorform.LastNameEdit.text()),
display_name=unicode(self.authorform.DisplayEdit.text()))
if self.songmanager.save_author(author):
if self.songmanager.save_object(author):
self.resetAuthors()
else:
QtGui.QMessageBox.critical(
@ -145,7 +143,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
def onTopicAddButtonClick(self):
if self.topicform.exec_():
topic = Topic.populate(name=unicode(self.topicform.NameEdit.text()))
if self.songmanager.save_topic(topic):
if self.songmanager.save_object(topic):
self.resetTopics()
else:
QtGui.QMessageBox.critical(
@ -159,7 +157,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
book = Book.populate(
name=unicode(self.bookform.NameEdit.text()),
publisher=unicode(self.bookform.PublisherEdit.text()))
if self.songmanager.save_book(book):
if self.songmanager.save_object(book):
self.resetBooks()
else:
QtGui.QMessageBox.critical(
@ -171,7 +169,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
def onAuthorEditButtonClick(self):
author_id = self._getCurrentItemId(self.AuthorsListWidget)
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
if author.first_name is None:
author.first_name = u''
@ -189,7 +187,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
author.last_name = unicode(self.authorform.LastNameEdit.text())
author.display_name = unicode(
self.authorform.DisplayEdit.text())
if self.songmanager.save_author(author):
if self.songmanager.save_object(author):
self.resetAuthors()
else:
QtGui.QMessageBox.critical(
@ -201,11 +199,11 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
def onTopicEditButtonClick(self):
topic_id = self._getCurrentItemId(self.TopicsListWidget)
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)
if self.topicform.exec_(False):
topic.name = unicode(self.topicform.NameEdit.text())
if self.songmanager.save_topic(topic):
if self.songmanager.save_object(topic):
self.resetTopics()
else:
QtGui.QMessageBox.critical(
@ -217,13 +215,13 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
def onBookEditButtonClick(self):
book_id = self._getCurrentItemId(self.BooksListWidget)
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.PublisherEdit.setText(book.publisher)
if self.bookform.exec_(False):
book.name = unicode(self.bookform.NameEdit.text())
book.publisher = unicode(self.bookform.PublisherEdit.text())
if self.songmanager.save_book(book):
if self.songmanager.save_object(book):
self.resetBooks()
else:
QtGui.QMessageBox.critical(
@ -236,11 +234,9 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
"""
Delete the author if the author is not attached to any songs
"""
self._deleteItem(
self.AuthorsListWidget, self.songmanager.get_author,
self.songmanager.delete_author, self.resetAuthors,
self._deleteItem(Author, self.AuthorsListWidget, self.resetAuthors,
translate('SongsPlugin.SongMaintenanceForm', 'Delete Author'),
translate('SongsPlugin.SongMaintenanceForm',
translate('SongsPlugin.SongMaintenanceForm',
'Are you sure you want to delete the selected author?'),
translate('SongsPlugin.SongMaintenanceForm',
'This author can\'t be deleted, they are currently '
@ -252,13 +248,11 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
"""
Delete the Book is the Book is not attached to any songs
"""
self._deleteItem(
self.TopicsListWidget, self.songmanager.get_topic,
self.songmanager.delete_topic, self.resetTopics,
self._deleteItem(Topic, self.TopicsListWidget, self.resetTopics,
translate('SongsPlugin.SongMaintenanceForm', 'Delete Topic'),
translate('SongsPlugin.SongMaintenanceForm',
translate('SongsPlugin.SongMaintenanceForm',
'Are you sure you want to delete the selected topic?'),
translate('SongsPlugin.SongMaintenanceForm',
translate('SongsPlugin.SongMaintenanceForm',
'This topic can\'t be deleted, it is currently '
'assigned to at least one song.'),
translate('SongsPlugin.SongMaintenanceForm',
@ -268,13 +262,11 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
"""
Delete the Book is the Book is not attached to any songs
"""
self._deleteItem(
self.BooksListWidget, self.songmanager.get_book,
self.songmanager.delete_book, self.resetBooks,
self._deleteItem(Book, self.BooksListWidget, self.resetBooks,
translate('SongsPlugin.SongMaintenanceForm', 'Delete Book'),
translate('SongsPlugin.SongMaintenanceForm',
'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 '
'assigned to at least one song.'),
translate('SongsPlugin.SongMaintenanceForm', 'No book selected!'))
translate('SongsPlugin.SongMaintenanceForm', u'No book selected!'))

View File

@ -24,6 +24,7 @@
###############################################################################
from PyQt4 import QtCore, QtGui
from openlp.core.lib import translate
class Ui_TopicsDialog(object):

View File

@ -28,7 +28,6 @@ from PyQt4 import QtGui
from openlp.core.lib import translate
from openlp.plugins.songs.forms.topicsdialog import Ui_TopicsDialog
class TopicsForm(QtGui.QDialog, Ui_TopicsDialog):
"""
Class documentation goes here.

View File

@ -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

View 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

View File

@ -25,12 +25,8 @@
import logging
from PyQt4 import QtCore
from sqlalchemy.exceptions import InvalidRequestError
from openlp.core.utils import AppLocation
from openlp.plugins.songs.lib.models import init_models, metadata, Song, \
Author, Topic, Book
from openlp.core.lib.db import Manager
from openlp.plugins.songs.lib.db import init_schema, Song, Author
#from openlp.plugins.songs.lib import OpenLyricsSong, OpenSongSong, CCLISong, \
# 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
class takes care of connecting to the database and running all the queries.
@ -93,35 +89,9 @@ class SongManager(object):
don't exist.
"""
log.debug(u'Song Initialising')
settings = QtCore.QSettings()
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()
Manager.__init__(self, u'songs', init_schema)
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):
"""
Searches the song title for keywords.
@ -144,175 +114,3 @@ class SongManager(object):
"""
return self.session.query(Author).filter(Author.display_name.like(
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()

View File

@ -31,6 +31,7 @@ from openlp.core.lib import MediaManagerItem, SongXMLParser, \
BaseListWithDnD, Receiver, ItemCapabilities, translate, check_item_selected
from openlp.plugins.songs.forms import EditSongForm, SongMaintenanceForm, \
ImportWizardForm
from openlp.plugins.songs.lib.db import Song
log = logging.getLogger(__name__)
@ -268,7 +269,7 @@ class SongMediaItem(MediaManagerItem):
type of display is required.
"""
fields = songid.split(u':')
valid = self.parent.manager.get_song(fields[1])
valid = self.parent.manager.get_object(Song, fields[1])
if valid:
self.remoteSong = fields[1]
self.remoteTriggered = fields[0]
@ -310,7 +311,7 @@ class SongMediaItem(MediaManagerItem):
return
for item in items:
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()
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.AllowsPreview)
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.editId = item_id
if song.lyrics.startswith(u'<?xml version='):

View File

@ -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()

View File

@ -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

View File

@ -27,7 +27,7 @@ import re
from openlp.core.lib import SongXMLBuilder, translate
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):
"""
@ -264,7 +264,6 @@ class SongImport(object):
if len(self.authors) == 0:
self.authors.append(u'Author unknown')
self.commit_song()
#self.print_song()
def commit_song(self):
"""
@ -303,30 +302,33 @@ class SongImport(object):
song.theme_name = self.theme_name
song.ccli_number = self.ccli_number
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:
author = Author()
author.display_name = authortext
author.last_name = 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)
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:
song_book = Book()
song_book.name = self.song_book_name
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
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:
topic = Topic()
topic.name = topictext
self.manager.save_topic(topic)
self.manager.save_object(topic)
song.topics.append(topictext)
self.manager.save_song(song)
self.manager.save_object(song)
def print_song(self):
"""
@ -357,5 +359,3 @@ class SongImport(object):
print u'THEME: ' + self.theme_name
if self.ccli_number:
print u'CCLI: ' + self.ccli_number

View File

@ -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)

View File

@ -30,6 +30,7 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import Plugin, build_icon, PluginStatus, Receiver, \
translate
from openlp.plugins.songs.lib import SongManager, SongMediaItem, SongsTab
from openlp.plugins.songs.lib.db import Song
try:
from openlp.plugins.songs.lib import SofImport, OooImport
@ -39,7 +40,6 @@ except ImportError:
log = logging.getLogger(__name__)
class SongsPlugin(Plugin):
"""
This is the number 1 plugin, if importance were placed on any
@ -69,7 +69,8 @@ class SongsPlugin(Plugin):
# self.songmanager = SongManager()
Plugin.initialise(self)
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):
log.info(u'Plugin Finalise')
@ -198,6 +199,7 @@ class SongsPlugin(Plugin):
return about_text
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 False

View File

@ -74,16 +74,16 @@ class SongUsageDetailForm(QtGui.QDialog, Ui_SongUsageDetailDialog):
filename = u'usage_detail_%s_%s.txt' % (
self.FromDate.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())
outname = os.path.join(unicode(self.FileLineEdit.text()), filename)
file = None
try:
file = open(outname, u'w')
for instance in usage:
record = u'\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"\n' % \
(instance.usagedate,instance.usagetime, instance.title,
instance.copyright, instance.ccl_number , instance.authors)
record = u'\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"\n' % (
instance.usagedate, instance.usagetime, instance.title,
instance.copyright, instance.ccl_number, instance.authors)
file.write(record)
except IOError:
log.exception(u'Failed to write out song usage records')

View File

@ -22,5 +22,7 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# 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

View File

@ -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

View File

@ -22,18 +22,42 @@
# 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 SongUsage plugin
"""
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker, mapper
from sqlalchemy import Column, Table, types
from sqlalchemy.orm import mapper
from openlp.plugins.songusage.lib.meta import metadata
from openlp.plugins.songusage.lib.tables import *
from openlp.plugins.songusage.lib.classes import *
from openlp.core.lib.db import BaseModel, init_db
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)
metadata.create_all(checkfirst=True)
return session

View File

@ -25,16 +25,14 @@
import logging
from PyQt4 import QtCore
from sqlalchemy.exceptions import InvalidRequestError
from openlp.core.utils import AppLocation
from openlp.plugins.songusage.lib.models import init_models, metadata, \
SongUsageItem
from openlp.core.lib.db import Manager
from openlp.plugins.songusage.lib.db import init_schema, SongUsageItem
log = logging.getLogger(__name__)
class SongUsageManager(object):
class SongUsageManager(Manager):
"""
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.
@ -47,98 +45,31 @@ class SongUsageManager(object):
don't exist.
"""
log.debug(u'SongUsage Initialising')
settings = QtCore.QSettings()
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()
Manager.__init__(self, u'songusage', init_schema)
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) \
.filter(SongUsageItem.usagedate >= start_date.toPyDate()) \
.filter(SongUsageItem.usagedate < end_date.toPyDate()) \
.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
.order_by(SongUsageItem.usagedate, SongUsageItem.usagetime).all()
def delete_to_date(self, date):
"""
Delete SongUsage records before given date
"""
try:
self.session.query(SongUsageItem)\
.filter(SongUsageItem.usagedate <= date)\
self.session.query(SongUsageItem) \
.filter(SongUsageItem.usagedate <= date) \
.delete(synchronize_session=False)
self.session.commit()
return True
@ -146,4 +77,3 @@ class SongUsageManager(object):
self.session.rollback()
log.exception(u'Failed to delete all Song Usage items to %s' % date)
return False

View File

@ -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()

View File

@ -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))
)

View File

@ -23,16 +23,16 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
from datetime import datetime
import logging
from datetime import datetime
from PyQt4 import QtCore, QtGui
from openlp.core.lib import Plugin, Receiver, build_icon, translate
from openlp.plugins.songusage.lib import SongUsageManager
from openlp.plugins.songusage.forms import SongUsageDetailForm, \
SongUsageDeleteForm
from openlp.plugins.songusage.lib.models import SongUsageItem
from openlp.plugins.songusage.lib.db import SongUsageItem
log = logging.getLogger(__name__)
@ -148,7 +148,7 @@ class SongUsagePlugin(Plugin):
song_usage_item.authors = u''
for author in audit[1]:
song_usage_item.authors += author + u' '
self.songusagemanager.insert_songusage(song_usage_item)
self.songusagemanager.save_object(song_usage_item)
def onSongUsageDelete(self):
self.SongUsagedeleteform.exec_()
@ -162,4 +162,4 @@ class SongUsagePlugin(Plugin):
'<b>SongUsage Plugin</b><br>This plugin '
'records the use of songs and when they have been used during '
'a live service')
return about_text
return about_text