Move Audit to SongUsage

This commit is contained in:
Tim Bentley 2009-10-27 08:38:02 +00:00
parent 03ba804be7
commit 60649e3624
18 changed files with 518 additions and 219 deletions

View File

@ -78,7 +78,7 @@ class EventReceiver(QtCore.QObject):
``{plugin}_stop`` ``{plugin}_stop``
Requests a plugin to handle a stop event Requests a plugin to handle a stop event
``audit_live`` ``songusage_live``
Sends live song audit requests to the audit component Sends live song audit requests to the audit component
``audit_changed`` ``audit_changed``
@ -154,4 +154,4 @@ class Receiver():
""" """
Get the global ``eventreceiver`` instance. Get the global ``eventreceiver`` instance.
""" """
return Receiver.eventreceiver return Receiver.eventreceiver

View File

@ -388,8 +388,8 @@ class SlideController(QtGui.QWidget):
self.onSlideSelected() self.onSlideSelected()
self.PreviewListWidget.setFocus() self.PreviewListWidget.setFocus()
log.info(u'Display Rendering took %4s' % (time.time() - before)) log.info(u'Display Rendering took %4s' % (time.time() - before))
if self.serviceitem.audit != u'': if self.serviceitem.audit != u'' and self.isLive:
Receiver().send_message(u'audit_live', self.serviceitem.audit) Receiver().send_message(u'songusage_live', self.serviceitem.audit)
log.debug(u'displayServiceManagerItems End') log.debug(u'displayServiceManagerItems End')
#Screen event methods #Screen event methods

View File

@ -1,169 +0,0 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2009 Raoul Snyman #
# Portions copyright (c) 2008-2009 Martin Thompson, Tim Bentley, Carsten #
# Tinggaard, Jon Tibble, Jonathan Corwin, Maikel Stuivenberg, Scott Guerrieri #
# --------------------------------------------------------------------------- #
# 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 datetime import datetime
import logging
from PyQt4 import QtCore, QtGui
from openlp.core.lib import Plugin, Receiver, str_to_bool, buildIcon
from openlp.plugins.audit.lib import AuditManager
from openlp.plugins.audit.forms import AuditDetailForm, AuditDeleteForm
from openlp.plugins.audit.lib.models import AuditItem
class AuditPlugin(Plugin):
global log
log = logging.getLogger(u'AuditPlugin')
log.info(u'Audit Plugin loaded')
def __init__(self, plugin_helpers):
# Call the parent constructor
Plugin.__init__(self, u'Audit', u'1.9.0', plugin_helpers)
self.weight = -4
# Create the plugin icon
self.icon = buildIcon(u':/media/media_image.png')
self.auditmanager = None
self.auditActive = False
def can_be_disabled(self):
return True
def add_tools_menu_item(self, tools_menu):
"""
Give the Audit plugin the opportunity to add items to the
**Tools** menu.
``tools_menu``
The actual **Tools** menu item, so that your actions can
use it as their parent.
"""
log.info(u'add tools menu')
self.toolsMenu = tools_menu
self.AuditMenu = QtGui.QMenu(tools_menu)
self.AuditMenu.setObjectName(u'AuditMenu')
self.AuditMenu.setTitle(tools_menu.trUtf8(u'&Song Usage'))
#Audit Delete
self.AuditDelete = QtGui.QAction(tools_menu)
self.AuditDelete.setText(tools_menu.trUtf8(u'&Delete recorded data'))
self.AuditDelete.setStatusTip(
tools_menu.trUtf8(u'Delete sing usage to sepecified date'))
self.AuditDelete.setObjectName(u'AuditDelete')
#Audit Report
self.AuditReport = QtGui.QAction(tools_menu)
self.AuditReport.setText(tools_menu.trUtf8(u'&Extract recoreded data'))
self.AuditReport.setStatusTip(
tools_menu.trUtf8(u'Generate Extracts on Song Usage'))
self.AuditReport.setObjectName(u'AuditReport')
#Audit activation
AuditIcon = buildIcon(u':/tools/tools_alert.png')
self.AuditStatus = QtGui.QAction(tools_menu)
self.AuditStatus.setIcon(AuditIcon)
self.AuditStatus.setCheckable(True)
self.AuditStatus.setChecked(False)
self.AuditStatus.setText(tools_menu.trUtf8(u'Song Usage Status'))
self.AuditStatus.setStatusTip(
tools_menu.trUtf8(u'Start/Stop live song usage recording'))
self.AuditStatus.setShortcut(u'F4')
self.AuditStatus.setObjectName(u'AuditStatus')
#Add Menus together
self.toolsMenu.addAction(self.AuditMenu.menuAction())
self.AuditMenu.addAction(self.AuditStatus)
self.AuditMenu.addSeparator()
self.AuditMenu.addAction(self.AuditDelete)
self.AuditMenu.addAction(self.AuditReport)
# Signals and slots
QtCore.QObject.connect(self.AuditStatus,
QtCore.SIGNAL(u'visibilityChanged(bool)'),
self.AuditStatus.setChecked)
QtCore.QObject.connect(self.AuditStatus,
QtCore.SIGNAL(u'triggered(bool)'),
self.toggleAuditState)
QtCore.QObject.connect(self.AuditDelete,
QtCore.SIGNAL(u'triggered()'), self.onAuditDelete)
QtCore.QObject.connect(self.AuditReport,
QtCore.SIGNAL(u'triggered()'), self.onAuditReport)
self.AuditMenu.menuAction().setVisible(False)
def initialise(self):
log.info(u'audit Initialising')
Plugin.initialise(self)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'audit_live'), self.onReceiveAudit)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'audit_changed'), self.onUpdateAudit)
self.auditActive = str_to_bool(
self.config.get_config(u'audit active', False))
self.AuditStatus.setChecked(self.auditActive)
if self.auditmanager is None:
self.auditmanager = AuditManager(self.config)
self.auditdeleteform = AuditDeleteForm(self.auditmanager)
self.auditdetailform = AuditDetailForm(self)
self.AuditMenu.menuAction().setVisible(True)
def finalise(self):
log.info(u'Plugin Finalise')
self.AuditMenu.menuAction().setVisible(False)
#stop any events being processed
self.auditActive = False
def toggleAuditState(self):
self.auditActive = not self.auditActive
self.config.set_config(u'audit active', self.auditActive)
def onReceiveAudit(self, auditData):
"""
Audit a live song from SlideController
"""
if self.auditActive:
audititem = AuditItem()
audititem.auditdate = datetime.today()
audititem.audittime = datetime.now().time()
audititem.title = auditData[0]
audititem.copyright = auditData[2]
audititem.ccl_number = auditData[3]
audititem.authors = u''
for author in auditData[1]:
audititem.authors += author + u' '
self.auditmanager.insert_audit(audititem)
def onUpdateAudit(self):
"""
Someone may have changed to audit details
Sort out the file and the auditing state
"""
self.auditActive = str_to_bool(
self.config.get_config(u'audit active', False))
self.AuditStatus.setEnabled(True)
def onAuditDelete(self):
self.auditdeleteform.exec_()
def onAuditReport(self):
self.auditdetailform.initialise()
self.auditdetailform.exec_()
def about(self):
about_text = u'<b>Audit Plugin</b><br />This plugin records the use '\
u'of songs and when they have been used during a live service'
return about_text

View File

@ -22,5 +22,5 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
from auditdeleteform import AuditDeleteForm from songusagedeleteform import SongUsageDeleteForm
from auditdetailform import AuditDetailForm from songusagedetailform import SongUsageDetailForm

View File

@ -9,7 +9,7 @@
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
class Ui_AuditDeleteDialog(object): class Ui_SongUsageDeleteDialog(object):
def setupUi(self, AuditDeleteDialog): def setupUi(self, AuditDeleteDialog):
AuditDeleteDialog.setObjectName(u'AuditDeleteDialog') AuditDeleteDialog.setObjectName(u'AuditDeleteDialog')
AuditDeleteDialog.resize(291, 243) AuditDeleteDialog.resize(291, 243)

View File

@ -26,9 +26,9 @@ from datetime import date
from PyQt4 import QtGui from PyQt4 import QtGui
from auditdeletedialog import Ui_AuditDeleteDialog from songusagedeletedialog import Ui_SongUsageDeleteDialog
class AuditDeleteForm(QtGui.QDialog, Ui_AuditDeleteDialog): class SongUsageDeleteForm(QtGui.QDialog, Ui_SongUsageDeleteDialog):
""" """
Class documentation goes here. Class documentation goes here.
""" """

View File

@ -0,0 +1,181 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'auditdetaildialog.ui'
#
# Created: Sun Oct 11 11:40:02 2009
# by: PyQt4 UI code generator 4.5.4
#
# WARNING! All changes made in this file will be lost!
from PyQt4 import QtCore, QtGui
class Ui_SongUsageDetailDialog(object):
def setupUi(self, AuditDetailDialog):
AuditDetailDialog.setObjectName(u'AuditDetailDialog')
AuditDetailDialog.resize(593, 501)
self.buttonBox = QtGui.QDialogButtonBox(AuditDetailDialog)
self.buttonBox.setGeometry(QtCore.QRect(420, 470, 170, 25))
self.buttonBox.setStandardButtons(
QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok)
self.buttonBox.setObjectName(u'buttonBox')
self.FileGroupBox = QtGui.QGroupBox(AuditDetailDialog)
self.FileGroupBox.setGeometry(QtCore.QRect(10, 370, 571, 70))
self.FileGroupBox.setObjectName(u'FileGroupBox')
self.verticalLayout_4 = QtGui.QVBoxLayout(self.FileGroupBox)
self.verticalLayout_4.setObjectName(u'verticalLayout_4')
self.horizontalLayout = QtGui.QHBoxLayout()
self.horizontalLayout.setObjectName(u'horizontalLayout')
self.FileLineEdit = QtGui.QLineEdit(self.FileGroupBox)
self.FileLineEdit.setObjectName(u'FileLineEdit')
self.horizontalLayout.addWidget(self.FileLineEdit)
self.SaveFilePushButton = QtGui.QPushButton(self.FileGroupBox)
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(u':/exports/export_load.png'),
QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.SaveFilePushButton.setIcon(icon)
self.SaveFilePushButton.setObjectName(u'SaveFilePushButton')
self.horizontalLayout.addWidget(self.SaveFilePushButton)
self.verticalLayout_4.addLayout(self.horizontalLayout)
self.layoutWidget = QtGui.QWidget(AuditDetailDialog)
self.layoutWidget.setGeometry(QtCore.QRect(10, 10, 561, 361))
self.layoutWidget.setObjectName(u'layoutWidget')
self.verticalLayout_3 = QtGui.QVBoxLayout(self.layoutWidget)
self.verticalLayout_3.setObjectName(u'verticalLayout_3')
self.ReportTypeGroup = QtGui.QGroupBox(self.layoutWidget)
self.ReportTypeGroup.setObjectName(u'ReportTypeGroup')
self.layoutWidget1 = QtGui.QWidget(self.ReportTypeGroup)
self.layoutWidget1.setGeometry(QtCore.QRect(50, 40, 481, 23))
self.layoutWidget1.setObjectName(u'layoutWidget1')
self.ReportHorizontalLayout = QtGui.QHBoxLayout(self.layoutWidget1)
self.ReportHorizontalLayout.setObjectName(u'ReportHorizontalLayout')
self.SummaryReport = QtGui.QRadioButton(self.layoutWidget1)
self.SummaryReport.setObjectName(u'SummaryReport')
self.ReportHorizontalLayout.addWidget(self.SummaryReport)
self.DetailedReport = QtGui.QRadioButton(self.layoutWidget1)
self.DetailedReport.setChecked(True)
self.DetailedReport.setObjectName(u'DetailedReport')
self.ReportHorizontalLayout.addWidget(self.DetailedReport)
self.verticalLayout_3.addWidget(self.ReportTypeGroup)
self.DateRangeGroupBox = QtGui.QGroupBox(self.layoutWidget)
self.DateRangeGroupBox.setObjectName(u'DateRangeGroupBox')
self.verticalLayout_2 = QtGui.QVBoxLayout(self.DateRangeGroupBox)
self.verticalLayout_2.setObjectName(u'verticalLayout_2')
self.DateHorizontalLayout = QtGui.QHBoxLayout()
self.DateHorizontalLayout.setObjectName(u'DateHorizontalLayout')
self.FromDateEdit = QtGui.QDateEdit(self.DateRangeGroupBox)
self.FromDateEdit.setCalendarPopup(True)
self.FromDateEdit.setObjectName(u'FromDateEdit')
self.DateHorizontalLayout.addWidget(self.FromDateEdit)
self.To = QtGui.QLabel(self.DateRangeGroupBox)
self.To.setObjectName(u'To')
self.DateHorizontalLayout.addWidget(self.To)
self.ToDateEdit = QtGui.QDateEdit(self.DateRangeGroupBox)
self.ToDateEdit.setCalendarPopup(True)
self.ToDateEdit.setObjectName(u'ToDateEdit')
self.DateHorizontalLayout.addWidget(self.ToDateEdit)
self.verticalLayout_2.addLayout(self.DateHorizontalLayout)
self.verticalLayout_3.addWidget(self.DateRangeGroupBox)
self.TimePeriodGroupBox = QtGui.QGroupBox(self.layoutWidget)
self.TimePeriodGroupBox.setObjectName(u'TimePeriodGroupBox')
self.verticalLayout = QtGui.QVBoxLayout(self.TimePeriodGroupBox)
self.verticalLayout.setObjectName(u'verticalLayout')
self.FirstHorizontalLayout = QtGui.QHBoxLayout()
self.FirstHorizontalLayout.setObjectName(u'FirstHorizontalLayout')
self.FirstCheckBox = QtGui.QCheckBox(self.TimePeriodGroupBox)
self.FirstCheckBox.setChecked(True)
self.FirstCheckBox.setObjectName(u'FirstCheckBox')
self.FirstHorizontalLayout.addWidget(self.FirstCheckBox)
self.FirstFromTimeEdit = QtGui.QTimeEdit(self.TimePeriodGroupBox)
self.FirstFromTimeEdit.setTime(QtCore.QTime(9, 0, 0))
self.FirstFromTimeEdit.setObjectName(u'FirstFromTimeEdit')
self.FirstHorizontalLayout.addWidget(self.FirstFromTimeEdit)
self.FirstTo = QtGui.QLabel(self.TimePeriodGroupBox)
self.FirstTo.setObjectName(u'FirstTo')
self.FirstHorizontalLayout.addWidget(self.FirstTo)
self.FirstToTimeEdit = QtGui.QTimeEdit(self.TimePeriodGroupBox)
self.FirstToTimeEdit.setCalendarPopup(True)
self.FirstToTimeEdit.setTime(QtCore.QTime(10, 0, 0))
self.FirstToTimeEdit.setObjectName(u'FirstToTimeEdit')
self.FirstHorizontalLayout.addWidget(self.FirstToTimeEdit)
self.verticalLayout.addLayout(self.FirstHorizontalLayout)
self.SecondHorizontalLayout = QtGui.QHBoxLayout()
self.SecondHorizontalLayout.setObjectName(u'SecondHorizontalLayout')
self.SecondCheckBox = QtGui.QCheckBox(self.TimePeriodGroupBox)
self.SecondCheckBox.setChecked(True)
self.SecondCheckBox.setObjectName(u'SecondCheckBox')
self.SecondHorizontalLayout.addWidget(self.SecondCheckBox)
self.SecondFromTimeEdit = QtGui.QTimeEdit(self.TimePeriodGroupBox)
self.SecondFromTimeEdit.setTime(QtCore.QTime(10, 45, 0))
self.SecondFromTimeEdit.setObjectName(u'SecondFromTimeEdit')
self.SecondHorizontalLayout.addWidget(self.SecondFromTimeEdit)
self.SecondTo = QtGui.QLabel(self.TimePeriodGroupBox)
self.SecondTo.setObjectName(u'SecondTo')
self.SecondHorizontalLayout.addWidget(self.SecondTo)
self.SecondToTimeEdit = QtGui.QTimeEdit(self.TimePeriodGroupBox)
self.SecondToTimeEdit.setObjectName(u'SecondToTimeEdit')
self.SecondHorizontalLayout.addWidget(self.SecondToTimeEdit)
self.verticalLayout.addLayout(self.SecondHorizontalLayout)
self.ThirdHorizontalLayout = QtGui.QHBoxLayout()
self.ThirdHorizontalLayout.setObjectName(u'ThirdHorizontalLayout')
self.ThirdCheckBox = QtGui.QCheckBox(self.TimePeriodGroupBox)
self.ThirdCheckBox.setChecked(True)
self.ThirdCheckBox.setObjectName(u'ThirdCheckBox')
self.ThirdHorizontalLayout.addWidget(self.ThirdCheckBox)
self.ThirdFromTimeEdit = QtGui.QTimeEdit(self.TimePeriodGroupBox)
self.ThirdFromTimeEdit.setTime(QtCore.QTime(18, 30, 0))
self.ThirdFromTimeEdit.setObjectName(u'ThirdFromTimeEdit')
self.ThirdHorizontalLayout.addWidget(self.ThirdFromTimeEdit)
self.ThirdTo = QtGui.QLabel(self.TimePeriodGroupBox)
self.ThirdTo.setObjectName(u'ThirdTo')
self.ThirdHorizontalLayout.addWidget(self.ThirdTo)
self.ThirdToTimeEdit = QtGui.QTimeEdit(self.TimePeriodGroupBox)
self.ThirdToTimeEdit.setTime(QtCore.QTime(19, 30, 0))
self.ThirdToTimeEdit.setObjectName(u'ThirdToTimeEdit')
self.ThirdHorizontalLayout.addWidget(self.ThirdToTimeEdit)
self.verticalLayout.addLayout(self.ThirdHorizontalLayout)
self.verticalLayout_3.addWidget(self.TimePeriodGroupBox)
self.retranslateUi(AuditDetailDialog)
QtCore.QObject.connect(
self.buttonBox, QtCore.SIGNAL(u'accepted()'),
AuditDetailDialog.accept)
QtCore.QObject.connect(
self.buttonBox, QtCore.SIGNAL(u'rejected()'),
AuditDetailDialog.close)
QtCore.QObject.connect(
self.FirstCheckBox, QtCore.SIGNAL(u'stateChanged(int)'),
AuditDetailDialog.changeFirstService)
QtCore.QObject.connect(
self.SecondCheckBox, QtCore.SIGNAL(u'stateChanged(int)'),
AuditDetailDialog.changeSecondService)
QtCore.QObject.connect(
self.ThirdCheckBox, QtCore.SIGNAL(u'stateChanged(int)'),
AuditDetailDialog.changeThirdService)
QtCore.QObject.connect(
self.SaveFilePushButton, QtCore.SIGNAL(u'pressed()'),
AuditDetailDialog.defineOutputLocation)
QtCore.QMetaObject.connectSlotsByName(AuditDetailDialog)
def retranslateUi(self, AuditDetailDialog):
AuditDetailDialog.setWindowTitle(self.trUtf8(u'Audit Detail Extraction'))
self.FileGroupBox.setTitle(self.trUtf8(u'Report Location'))
self.ReportTypeGroup.setTitle(self.trUtf8(u'Report Type'))
self.SummaryReport.setText(self.trUtf8(u'Summary'))
self.DetailedReport.setText(self.trUtf8(u'Detailed'))
self.DateRangeGroupBox.setTitle(self.trUtf8(u'Select Date Range'))
self.FromDateEdit.setDisplayFormat(self.trUtf8(u'dd/MM/yyyy'))
self.To.setText(self.trUtf8(u'to'))
self.ToDateEdit.setDisplayFormat(self.trUtf8(u'dd/MM/yyyy'))
self.TimePeriodGroupBox.setTitle(self.trUtf8(u'Select Time Periods'))
self.FirstCheckBox.setText(self.trUtf8(u'First Service'))
self.FirstFromTimeEdit.setDisplayFormat(self.trUtf8(u'hh:mm AP'))
self.FirstTo.setText(self.trUtf8(u'to'))
self.FirstToTimeEdit.setDisplayFormat(self.trUtf8(u'hh:mm AP'))
self.SecondCheckBox.setText(self.trUtf8(u'Second Service'))
self.SecondFromTimeEdit.setDisplayFormat(self.trUtf8(u'hh:mm AP'))
self.SecondTo.setText(self.trUtf8(u'to'))
self.SecondToTimeEdit.setDisplayFormat(self.trUtf8(u'hh:mm AP'))
self.ThirdCheckBox.setText(self.trUtf8(u'Third Service'))
self.ThirdFromTimeEdit.setDisplayFormat(self.trUtf8(u'hh:mm AP'))
self.ThirdTo.setText(self.trUtf8(u'to'))
self.ThirdToTimeEdit.setDisplayFormat(self.trUtf8(u'hh:mm AP'))

View File

@ -0,0 +1,127 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2009 Raoul Snyman #
# Portions copyright (c) 2008-2009 Martin Thompson, Tim Bentley, Carsten #
# Tinggaard, Jon Tibble, Jonathan Corwin, Maikel Stuivenberg, Scott Guerrieri #
# --------------------------------------------------------------------------- #
# 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 os
from PyQt4 import QtCore, QtGui
from songusagedetaildialog import Ui_SongUsageDetailDialog
class SongUsageDetailForm(QtGui.QDialog, Ui_SongUsageDetailDialog):
"""
Class documentation goes here.
"""
def __init__(self, parent=None):
"""
Constructor
"""
QtGui.QDialog.__init__(self, None)
self.parent = parent
self.setupUi(self)
def initialise(self):
self.FirstCheckBox.setCheckState(
int(self.parent.config.get_config(u'first service', QtCore.Qt.Checked)))
self.SecondCheckBox.setCheckState(
int(self.parent.config.get_config(u'second service', QtCore.Qt.Checked)))
self.ThirdCheckBox.setCheckState(
int(self.parent.config.get_config(u'third service', QtCore.Qt.Checked)))
year = QtCore.QDate().currentDate().year()
if QtCore.QDate().currentDate().month() < 9:
year -= 1
toDate = QtCore.QDate(year, 8, 31)
fromDate = QtCore.QDate(year - 1, 9, 1)
self.FromDateEdit.setDate(fromDate)
self.ToDateEdit.setDate(toDate)
self.FileLineEdit.setText(self.parent.config.get_last_dir(1))
self.resetWindow()
def changeFirstService(self, value):
self.parent.config.set_config(u'first service', value)
self.resetWindow()
def changeSecondService(self, value):
self.parent.config.set_config(u'second service', value)
self.resetWindow()
def changeThirdService(self, value):
self.parent.config.set_config(u'third service', value)
self.resetWindow()
def defineOutputLocation(self):
path = QtGui.QFileDialog.getExistingDirectory(self,
self.trUtf8(u'Output File Location'),
self.parent.config.get_last_dir(1) )
path = unicode(path)
if path != u'':
self.parent.config.set_last_dir(path, 1)
self.FileLineEdit.setText(path)
def resetWindow(self):
if self.FirstCheckBox.checkState() == QtCore.Qt.Unchecked:
self.FirstFromTimeEdit.setEnabled(False)
self.FirstToTimeEdit.setEnabled(False)
else:
self.FirstFromTimeEdit.setEnabled(True)
self.FirstToTimeEdit.setEnabled(True)
if self.SecondCheckBox.checkState() == QtCore.Qt.Unchecked:
self.SecondFromTimeEdit.setEnabled(False)
self.SecondToTimeEdit.setEnabled(False)
else:
self.SecondFromTimeEdit.setEnabled(True)
self.SecondToTimeEdit.setEnabled(True)
if self.ThirdCheckBox.checkState() == QtCore.Qt.Unchecked:
self.ThirdFromTimeEdit.setEnabled(False)
self.ThirdToTimeEdit.setEnabled(False)
else:
self.ThirdFromTimeEdit.setEnabled(True)
self.ThirdToTimeEdit.setEnabled(True)
def accept(self):
if self.DetailedReport.isChecked():
self.detailedReport()
else:
self.summaryReport()
self.close()
def detailedReport(self):
print "detailed"
filename = u'audit_det_%s_%s.txt' % \
(self.FromDateEdit.date().toString(u'ddMMyyyy'),
self.ToDateEdit.date().toString(u'ddMMyyyy'))
audits = self.parent.auditmanager.get_all_audits()
outname = os.path.join(unicode(self.FileLineEdit.text()), filename)
file = open(outname, u'w')
for audit in audits:
record = u'\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"\n' % \
(audit.auditdate,audit.audittime, audit.title,
audit.copyright, audit.ccl_number , audit.authors)
file.write(record)
file.close()
def summaryReport(self):
print "summary"
filename = u'audit_sum_%s_%s.txt' % \
(self.FromDateEdit.date().toString(u'ddMMyyyy'),
self.ToDateEdit.date().toString(u'ddMMyyyy'))
print filename

View File

@ -22,4 +22,4 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
from manager import AuditManager from manager import SongUsageManager

View File

@ -38,7 +38,7 @@ class BaseModel(object):
me.__setattr__(key, kwargs[key]) me.__setattr__(key, kwargs[key])
return me return me
class AuditItem(BaseModel): class SongUsageItem(BaseModel):
""" """
Audit model Audit model
""" """

View File

@ -24,17 +24,17 @@
import logging import logging
from openlp.plugins.audit.lib.models import init_models, metadata, AuditItem from openlp.plugins.songusage.lib.models import init_models, metadata, SongUsageItem
class AuditManager(): class SongUsageManager():
""" """
The Song Manager provides a central location for all database code. This The Song Manager provides a central location for all database code. This
class takes care of connecting to the database and running all the queries. class takes care of connecting to the database and running all the queries.
""" """
global log global log
log = logging.getLogger(u'AuditManager') log = logging.getLogger(u'SongUsageManager')
log.info(u'Audit manager loaded') log.info(u'SongUsage manager loaded')
def __init__(self, config): def __init__(self, config):
""" """
@ -42,11 +42,11 @@ class AuditManager():
don't exist. don't exist.
""" """
self.config = config self.config = config
log.debug(u'Audit Initialising') log.debug(u'SongUsage Initialising')
self.db_url = u'' self.db_url = u''
db_type = self.config.get_config(u'db type', u'sqlite') db_type = self.config.get_config(u'db type', u'sqlite')
if db_type == u'sqlite': if db_type == u'sqlite':
self.db_url = u'sqlite:///%s/audit.sqlite' % \ self.db_url = u'sqlite:///%s/songusage.sqlite' % \
self.config.get_data_path() self.config.get_data_path()
else: else:
self.db_url = u'%s://%s:%s@%s/%s' % \ self.db_url = u'%s://%s:%s@%s/%s' % \
@ -57,76 +57,78 @@ class AuditManager():
self.session = init_models(self.db_url) self.session = init_models(self.db_url)
metadata.create_all(checkfirst=True) metadata.create_all(checkfirst=True)
log.debug(u'Audit Initialised') log.debug(u'SongUsage Initialised')
def get_all_audits(self): def get_all_songusage(self):
""" """
Returns the details of a audit Returns the details of SongUsage
""" """
return self.session.query(AuditItem).order_by(AuditItem.auditdate, AuditItem.audittime ).all() return self.session.query(SongUsageItem).\
order_by(SongUsageItem.usagedate, SongUsageItem.usagetime ).all()
def insert_audit(self, audititem): def insert_songusage(self, songusageitem):
""" """
Saves an audit to the database Saves an SongUsage to the database
""" """
log.debug(u'Audit added') log.debug(u'SongUsage added')
try: try:
self.session.add(audititem) self.session.add(songusageitem)
self.session.commit() self.session.commit()
return True return True
except: except:
self.session.rollback() self.session.rollback()
log.exception(u'Audit item failed to save') log.exception(u'SongUsage item failed to save')
return False return False
def get_audit(self, id=None): def get_songusage(self, id=None):
""" """
Returns the details of an audit Returns the details of a SongUsage
""" """
if id is None: if id is None:
return AuditItem() return SongUsageItem()
else: else:
return self.session.query(AuditItem).get(id) return self.session.query(SongUsageItem).get(id)
def delete_audit(self, id): def delete_songusage(self, id):
""" """
Delete a audit record Delete a SongUsage record
""" """
if id !=0: if id !=0:
audititem = self.get_audit(id) songusageitem = self.get_songusage(id)
try: try:
self.session.delete(audititem) self.session.delete(songusageitem)
self.session.commit() self.session.commit()
return True return True
except: except:
self.session.rollback() self.session.rollback()
log.excertion(u'Audit Item failed to delete') log.excertion(u'SongUsage Item failed to delete')
return False return False
else: else:
return True return True
def delete_all(self): def delete_all(self):
""" """
Delete all audit records Delete all Song Usage records
""" """
try: try:
self.session.query(AuditItem).delete(synchronize_session=False) self.session.query(SongUsageItem).delete(synchronize_session=False)
self.session.commit() self.session.commit()
return True return True
except: except:
self.session.rollback() self.session.rollback()
log.excertion(u'Failed to delete all audit items') log.excertion(u'Failed to delete all Song Usage items')
return False return False
def delete_to_date(self, date): def delete_to_date(self, date):
""" """
Delete audit records before given date Delete SongUsage records before given date
""" """
try: try:
self.session.query(AuditItem).filter(AuditItem.auditdate <= date).delete(synchronize_session=False) self.session.query(SongUsageItem).\
filter(SongUsageItem.usagedate <= date).delete(synchronize_session=False)
self.session.commit() self.session.commit()
return True return True
except: except:
self.session.rollback() self.session.rollback()
log.excertion(u'Failed to delete all audit items to %s' % date) log.excertion(u'Failed to delete all Song Usage items to %s' % date)
return False return False

View File

@ -25,14 +25,14 @@
from sqlalchemy import create_engine from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker, mapper from sqlalchemy.orm import scoped_session, sessionmaker, mapper
from openlp.plugins.audit.lib.meta import metadata from openlp.plugins.songusage.lib.meta import metadata
from openlp.plugins.audit.lib.tables import * from openlp.plugins.songusage.lib.tables import *
from openlp.plugins.audit.lib.classes import * from openlp.plugins.songusage.lib.classes import *
def init_models(url): def init_models(url):
engine = create_engine(url) engine = create_engine(url)
metadata.bind = engine metadata.bind = engine
session = scoped_session(sessionmaker(autoflush=True, autocommit=False, session = scoped_session(sessionmaker(autoflush=True, autocommit=False,
bind=engine)) bind=engine))
mapper(AuditItem, audit_table) mapper(SongUsageItem, songusage_table)
return session return session

View File

@ -24,13 +24,13 @@
from sqlalchemy import Column, Table, types from sqlalchemy import Column, Table, types
from openlp.plugins.audit.lib.meta import metadata from openlp.plugins.songusage.lib.meta import metadata
# Definition of the "songs" table # Definition of the "songusage" table
audit_table = Table(u'audit_data', metadata, songusage_table = Table(u'songusage_data', metadata,
Column(u'id', types.Integer(), primary_key=True), Column(u'id', types.Integer(), primary_key=True),
Column(u'auditdate', types.Date, index=True, nullable=False), Column(u'usagedate', types.Date, index=True, nullable=False),
Column(u'audittime', types.Time, index=True, nullable=False), Column(u'usagetime', types.Time, index=True, nullable=False),
Column(u'title', types.Unicode(255), nullable=False), Column(u'title', types.Unicode(255), nullable=False),
Column(u'authors', types.Unicode(255), nullable=False), Column(u'authors', types.Unicode(255), nullable=False),
Column(u'copyright', types.Unicode(255)), Column(u'copyright', types.Unicode(255)),

View File

@ -0,0 +1,158 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2009 Raoul Snyman #
# Portions copyright (c) 2008-2009 Martin Thompson, Tim Bentley, Carsten #
# Tinggaard, Jon Tibble, Jonathan Corwin, Maikel Stuivenberg, Scott Guerrieri #
# --------------------------------------------------------------------------- #
# 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 datetime import datetime
import logging
from PyQt4 import QtCore, QtGui
from openlp.core.lib import Plugin, Receiver, str_to_bool, buildIcon
from openlp.plugins.songusage.lib import SongUsageManager
from openlp.plugins.songusage.forms import SongUsageDetailForm, SongUsageDeleteForm
from openlp.plugins.songusage.lib.models import SongUsageItem
class SongUsagePlugin(Plugin):
global log
log = logging.getLogger(u'SongUsagePlugin')
log.info(u'SongUsage Plugin loaded')
def __init__(self, plugin_helpers):
# Call the parent constructor
Plugin.__init__(self, u'SongUsage', u'1.9.0', plugin_helpers)
self.weight = -4
# Create the plugin icon
self.icon = buildIcon(u':/media/media_image.png')
self.songusagemanager = None
self.songusageActive = False
def can_be_disabled(self):
return True
def add_tools_menu_item(self, tools_menu):
"""
Give the SongUsage plugin the opportunity to add items to the
**Tools** menu.
``tools_menu``
The actual **Tools** menu item, so that your actions can
use it as their parent.
"""
log.info(u'add tools menu')
self.toolsMenu = tools_menu
self.SongUsageMenu = QtGui.QMenu(tools_menu)
self.SongUsageMenu.setObjectName(u'SongUsageMenu')
self.SongUsageMenu.setTitle(tools_menu.trUtf8(u'&Song Usage'))
#SongUsage Delete
self.SongUsageDelete = QtGui.QAction(tools_menu)
self.SongUsageDelete.setText(tools_menu.trUtf8(u'&Delete recorded data'))
self.SongUsageDelete.setStatusTip(
tools_menu.trUtf8(u'Delete sing usage to sepecified date'))
self.SongUsageDelete.setObjectName(u'SongUsageDelete')
#SongUsage Report
self.SongUsageReport = QtGui.QAction(tools_menu)
self.SongUsageReport.setText(tools_menu.trUtf8(u'&Extract recoreded data'))
self.SongUsageReport.setStatusTip(
tools_menu.trUtf8(u'Generate Extracts on Song Usage'))
self.SongUsageReport.setObjectName(u'SongUsageReport')
#SongUsage activation
SongUsageIcon = buildIcon(u':/tools/tools_alert.png')
self.SongUsageStatus = QtGui.QAction(tools_menu)
self.SongUsageStatus.setIcon(SongUsageIcon)
self.SongUsageStatus.setCheckable(True)
self.SongUsageStatus.setChecked(False)
self.SongUsageStatus.setText(tools_menu.trUtf8(u'Song Usage Status'))
self.SongUsageStatus.setStatusTip(
tools_menu.trUtf8(u'Start/Stop live song usage recording'))
self.SongUsageStatus.setShortcut(u'F4')
self.SongUsageStatus.setObjectName(u'SongUsageStatus')
#Add Menus together
self.toolsMenu.addAction(self.SongUsageMenu.menuAction())
self.SongUsageMenu.addAction(self.SongUsageStatus)
self.SongUsageMenu.addSeparator()
self.SongUsageMenu.addAction(self.SongUsageDelete)
self.SongUsageMenu.addAction(self.SongUsageReport)
# Signals and slots
QtCore.QObject.connect(self.SongUsageStatus,
QtCore.SIGNAL(u'visibilityChanged(bool)'),
self.SongUsageStatus.setChecked)
QtCore.QObject.connect(self.SongUsageStatus,
QtCore.SIGNAL(u'triggered(bool)'),
self.toggleSongUsageState)
QtCore.QObject.connect(self.SongUsageDelete,
QtCore.SIGNAL(u'triggered()'), self.onSongUsageDelete)
QtCore.QObject.connect(self.SongUsageReport,
QtCore.SIGNAL(u'triggered()'), self.onSongUsageReport)
self.SongUsageMenu.menuAction().setVisible(False)
def initialise(self):
log.info(u'SongUsage Initialising')
Plugin.initialise(self)
QtCore.QObject.connect(Receiver.get_receiver(),
QtCore.SIGNAL(u'songusage_live'), self.onReceiveSongUsage)
self.SongUsageActive = str_to_bool(
self.config.get_config(u'audit active', False))
self.SongUsageStatus.setChecked(self.SongUsageActive)
if self.songusagemanager is None:
self.songusagemanager = SongUsageManager(self.config)
self.SongUsagedeleteform = SongUsageDeleteForm(self.songusagemanager)
self.SongUsagedetailform = SongUsageDetailForm(self)
self.SongUsageMenu.menuAction().setVisible(True)
def finalise(self):
log.info(u'Plugin Finalise')
self.SongUsageMenu.menuAction().setVisible(False)
#stop any events being processed
self.SongUsageActive = False
def toggleSongUsageState(self):
self.SongUsageActive = not self.SongUsageActive
self.config.set_config(u'SongUsage active', self.SongUsageActive)
def onReceiveSongUsage(self, SongUsageData):
"""
SongUsage a live song from SlideController
"""
if self.SongUsageActive:
SongUsageitem = SongUsageItem()
SongUsageitem.usagedate = datetime.today()
SongUsageitem.usagetime = datetime.now().time()
SongUsageitem.title = SongUsageData[0]
SongUsageitem.copyright = SongUsageData[2]
SongUsageitem.ccl_number = SongUsageData[3]
SongUsageitem.authors = u''
for author in SongUsageData[1]:
SongUsageitem.authors += author + u' '
self.songusagemanager.insert_SongUsage(SongUsageitem)
def onSongUsageDelete(self):
self.SongUsagedeleteform.exec_()
def onSongUsageReport(self):
self.SongUsagedetailform.initialise()
self.SongUsagedetailform.exec_()
def about(self):
about_text = u'<b>SongUsage Plugin</b><br />This plugin records the use '\
u'of songs and when they have been used during a live service'
return about_text