This commit is contained in:
Raoul Snyman 2010-07-21 07:20:30 +02:00
commit 33fa1541a7
23 changed files with 394 additions and 197 deletions

View File

@ -135,16 +135,20 @@ class Manager(object):
settings.endGroup() settings.endGroup()
self.session = init_schema(self.db_url) self.session = init_schema(self.db_url)
def save_object(self, object_instance): def save_object(self, object_instance, commit=True):
""" """
Save an object to the database Save an object to the database
``object_instance`` ``object_instance``
The object to save The object to save
``commit``
Commit the session with this object
""" """
try: try:
self.session.add(object_instance) self.session.add(object_instance)
self.session.commit() if commit:
self.session.commit()
return True return True
except InvalidRequestError: except InvalidRequestError:
self.session.rollback() self.session.rollback()
@ -178,36 +182,24 @@ class Manager(object):
""" """
return self.session.query(object_class).filter(filter_clause).first() return self.session.query(object_class).filter(filter_clause).first()
def get_all_objects(self, object_class, order_by_ref=None): def get_all_objects(self, object_class, filter_clause=None,
order_by_ref=None):
""" """
Returns all the objects from the database Returns all the objects from the database
``object_class`` ``object_class``
The type of objects to return The type of objects to return
``filter_clause``
The filter governing selection of objects to return. Defaults to
None.
``order_by_ref`` ``order_by_ref``
Any parameters to order the returned objects by. Defaults to None. Any parameters to order the returned objects by. Defaults to None.
""" """
query = self.session.query(object_class) query = self.session.query(object_class)
if order_by_ref is not None: if filter_clause:
return query.order_by(order_by_ref).all() query = query.filter(filter_clause)
return query.all()
def get_all_objects_filtered(self, object_class, filter_clause,
order_by_ref=None):
"""
Returns a selection of objects from the database
``object_class``
The type of objects to return
``filter_clause``
The filter governing selection of objects to return
``order_by_ref``
Any parameters to order the returned objects by. Defaults to None.
"""
query = self.session.query(object_class).filter(filter_clause)
if order_by_ref is not None: if order_by_ref is not None:
return query.order_by(order_by_ref).all() return query.order_by(order_by_ref).all()
return query.all() return query.all()
@ -235,7 +227,7 @@ class Manager(object):
else: else:
return True return True
def delete_all_objects(self, object_class): def delete_all_objects(self, object_class, filter_clause=None):
""" """
Delete all object records Delete all object records
@ -243,11 +235,13 @@ class Manager(object):
The type of object to delete The type of object to delete
""" """
try: try:
self.session.query(object_class).delete(synchronize_session=False) query = self.session.query(object_class)
if filter_clause:
query = query.filter(filter_clause)
query.delete(synchronize_session=False)
self.session.commit() self.session.commit()
return True return True
except InvalidRequestError: except InvalidRequestError:
self.session.rollback() self.session.rollback()
log.exception(u'Failed to delete all %s records', log.exception(u'Failed to delete %s records', object_class.__name__)
object_class.__name__)
return False return False

View File

@ -62,7 +62,8 @@ class AlertForm(QtGui.QDialog, Ui_AlertDialog):
def loadList(self): def loadList(self):
self.AlertListWidget.clear() self.AlertListWidget.clear()
alerts = self.manager.get_all_objects(AlertItem, AlertItem.text) alerts = self.manager.get_all_objects(AlertItem,
order_by_ref=AlertItem.text)
for alert in alerts: for alert in alerts:
item_name = QtGui.QListWidgetItem(alert.text) item_name = QtGui.QListWidgetItem(alert.text)
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(alert.id)) item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(alert.id))

View File

@ -198,7 +198,8 @@ class BibleManager(object):
u'name': book.name, u'name': book.name,
u'chapters': self.db_cache[bible].get_chapter_count(book.name) u'chapters': self.db_cache[bible].get_chapter_count(book.name)
} }
for book in self.db_cache[bible].get_all_objects(Book, Book.id) for book in self.db_cache[bible].get_all_objects(Book,
order_by_ref=Book.id)
] ]
def get_chapter_count(self, bible, book): def get_chapter_count(self, bible, book):

View File

@ -508,14 +508,14 @@ class BibleMediaItem(MediaManagerItem):
reference = bitem.data(QtCore.Qt.UserRole) reference = bitem.data(QtCore.Qt.UserRole)
if isinstance(reference, QtCore.QVariant): if isinstance(reference, QtCore.QVariant):
reference = reference.toPyObject() reference = reference.toPyObject()
bible = self._decodeQtObject(reference, 'bible') #bible = self._decodeQtObject(reference, 'bible')
book = self._decodeQtObject(reference, 'book') book = self._decodeQtObject(reference, 'book')
chapter = self._decodeQtObject(reference, 'chapter') chapter = self._decodeQtObject(reference, 'chapter')
verse = self._decodeQtObject(reference, 'verse') verse = self._decodeQtObject(reference, 'verse')
text = self._decodeQtObject(reference, 'text') text = self._decodeQtObject(reference, 'text')
version = self._decodeQtObject(reference, 'version') version = self._decodeQtObject(reference, 'version')
copyright = self._decodeQtObject(reference, 'copyright') copyright = self._decodeQtObject(reference, 'copyright')
permission = self._decodeQtObject(reference, 'permission') #permission = self._decodeQtObject(reference, 'permission')
if self.parent.settings_tab.display_style == 1: if self.parent.settings_tab.display_style == 1:
verse_text = self.formatVerse(old_chapter, chapter, verse, verse_text = self.formatVerse(old_chapter, chapter, verse,
u'(u', u')') u'(u', u')')

View File

@ -75,7 +75,7 @@ class CustomPlugin(Plugin):
Returns True if the theme is being used, otherwise returns False. Returns True if the theme is being used, otherwise returns False.
""" """
if self.custommanager.get_all_objects_filtered(CustomSlide, if self.custommanager.get_all_objects(CustomSlide,
CustomSlide.theme_name == theme): CustomSlide.theme_name == theme):
return True return True
return False return False
@ -91,8 +91,8 @@ class CustomPlugin(Plugin):
``newTheme`` ``newTheme``
The new name the plugin should now use. The new name the plugin should now use.
""" """
customsUsingTheme = self.custommanager.get_all_objects_filtered( customsUsingTheme = self.custommanager.get_all_objects(CustomSlide,
CustomSlide, CustomSlide.theme_name == oldTheme) CustomSlide.theme_name == oldTheme)
for custom in customsUsingTheme: for custom in customsUsingTheme:
custom.theme_name = newTheme custom.theme_name = newTheme
self.custommanager.save_object(custom) self.custommanager.save_object(custom)

View File

@ -73,7 +73,7 @@ class CustomMediaItem(MediaManagerItem):
def initialise(self): def initialise(self):
self.loadCustomListView(self.parent.custommanager.get_all_objects( self.loadCustomListView(self.parent.custommanager.get_all_objects(
CustomSlide, CustomSlide.title)) CustomSlide, order_by_ref=CustomSlide.title))
#Called to redisplay the song list screen edith from a search #Called to redisplay the song list screen edith from a search
#or from the exit of the Song edit dialog. If remote editing is active #or from the exit of the Song edit dialog. If remote editing is active
#Trigger it and clean up so it will not update again. #Trigger it and clean up so it will not update again.

View File

@ -118,7 +118,8 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.TopicRemoveButton.setEnabled(False) self.TopicRemoveButton.setEnabled(False)
def loadAuthors(self): def loadAuthors(self):
authors = self.songmanager.get_all_objects(Author, Author.display_name) authors = self.songmanager.get_all_objects(Author,
order_by_ref=Author.display_name)
self.AuthorsSelectionComboItem.clear() self.AuthorsSelectionComboItem.clear()
self.AuthorsSelectionComboItem.addItem(u'') self.AuthorsSelectionComboItem.addItem(u'')
for author in authors: for author in authors:
@ -128,7 +129,8 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
row, QtCore.QVariant(author.id)) row, QtCore.QVariant(author.id))
def loadTopics(self): def loadTopics(self):
topics = self.songmanager.get_all_objects(Topic, Topic.name) topics = self.songmanager.get_all_objects(Topic,
order_by_ref=Topic.name)
self.SongTopicCombo.clear() self.SongTopicCombo.clear()
self.SongTopicCombo.addItem(u'') self.SongTopicCombo.addItem(u'')
for topic in topics: for topic in topics:
@ -137,7 +139,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.SongTopicCombo.setItemData(row, QtCore.QVariant(topic.id)) self.SongTopicCombo.setItemData(row, QtCore.QVariant(topic.id))
def loadBooks(self): def loadBooks(self):
books = self.songmanager.get_all_objects(Book, Book.name) books = self.songmanager.get_all_objects(Book, order_by_ref=Book.name)
self.SongbookCombo.clear() self.SongbookCombo.clear()
self.SongbookCombo.addItem(u'') self.SongbookCombo.addItem(u'')
for book in books: for book in books:
@ -180,7 +182,10 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.loadBooks() self.loadBooks()
self.song = self.songmanager.get_object(Song, id) self.song = self.songmanager.get_object(Song, id)
self.TitleEditItem.setText(self.song.title) self.TitleEditItem.setText(self.song.title)
title = self.song.search_title.split(u'@') if self.song.alternate_title:
self.AlternativeEdit.setText(self.song.alternate_title)
else:
self.AlternativeEdit.setText(u'')
if self.song.song_book_id != 0: if self.song.song_book_id != 0:
book_name = self.songmanager.get_object(Book, book_name = self.songmanager.get_object(Book,
self.song.song_book_id) self.song.song_book_id)
@ -198,8 +203,6 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
id = 0 id = 0
self.song.theme_name = None self.song.theme_name = None
self.ThemeSelectionComboItem.setCurrentIndex(id) self.ThemeSelectionComboItem.setCurrentIndex(id)
if len(title) > 1:
self.AlternativeEdit.setText(title[1])
if self.song.copyright: if self.song.copyright:
self.CopyrightEditItem.setText(self.song.copyright) self.CopyrightEditItem.setText(self.song.copyright)
else: else:
@ -290,7 +293,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
QtGui.QMessageBox.Yes) == QtGui.QMessageBox.Yes: QtGui.QMessageBox.Yes) == QtGui.QMessageBox.Yes:
author = Author.populate(first_name=text.rsplit(u' ', 1)[0], author = Author.populate(first_name=text.rsplit(u' ', 1)[0],
last_name=text.rsplit(u' ', 1)[1], display_name=text) last_name=text.rsplit(u' ', 1)[1], display_name=text)
self.songmanager.save_object(author) self.songmanager.save_object(author, False)
self.song.authors.append(author) self.song.authors.append(author)
author_item = QtGui.QListWidgetItem( author_item = QtGui.QListWidgetItem(
unicode(author.display_name)) unicode(author.display_name))
@ -304,10 +307,18 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
elif item > 0: elif item > 0:
item_id = (self.AuthorsSelectionComboItem.itemData(item)).toInt()[0] item_id = (self.AuthorsSelectionComboItem.itemData(item)).toInt()[0]
author = self.songmanager.get_object(Author, item_id) author = self.songmanager.get_object(Author, item_id)
self.song.authors.append(author) if author in self.song.authors:
author_item = QtGui.QListWidgetItem(unicode(author.display_name)) QtGui.QMessageBox.warning(self,
author_item.setData(QtCore.Qt.UserRole, QtCore.QVariant(author.id)) translate('SongsPlugin.EditSongForm', 'Error'),
self.AuthorsListView.addItem(author_item) translate('SongsPlugin.EditSongForm', 'This author is '
'already in the list.'))
else:
self.song.authors.append(author)
author_item = QtGui.QListWidgetItem(unicode(
author.display_name))
author_item.setData(QtCore.Qt.UserRole,
QtCore.QVariant(author.id))
self.AuthorsListView.addItem(author_item)
self.AuthorsSelectionComboItem.setCurrentIndex(0) self.AuthorsSelectionComboItem.setCurrentIndex(0)
else: else:
QtGui.QMessageBox.warning(self, QtGui.QMessageBox.warning(self,
@ -342,7 +353,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.Yes | QtGui.QMessageBox.No,
QtGui.QMessageBox.Yes) == QtGui.QMessageBox.Yes: QtGui.QMessageBox.Yes) == QtGui.QMessageBox.Yes:
topic = Topic.populate(name=text) topic = Topic.populate(name=text)
self.songmanager.save_object(topic) self.songmanager.save_object(topic, False)
self.song.topics.append(topic) self.song.topics.append(topic)
topic_item = QtGui.QListWidgetItem(unicode(topic.name)) topic_item = QtGui.QListWidgetItem(unicode(topic.name))
topic_item.setData(QtCore.Qt.UserRole, topic_item.setData(QtCore.Qt.UserRole,
@ -355,10 +366,17 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
elif item > 0: elif item > 0:
item_id = (self.SongTopicCombo.itemData(item)).toInt()[0] item_id = (self.SongTopicCombo.itemData(item)).toInt()[0]
topic = self.songmanager.get_object(Topic, item_id) topic = self.songmanager.get_object(Topic, item_id)
self.song.topics.append(topic) if topic in self.song.topics:
topic_item = QtGui.QListWidgetItem(unicode(topic.name)) QtGui.QMessageBox.warning(self,
topic_item.setData(QtCore.Qt.UserRole, QtCore.QVariant(topic.id)) translate('SongsPlugin.EditSongForm', 'Error'),
self.TopicsListView.addItem(topic_item) translate('SongsPlugin.EditSongForm', 'This topic is '
'already in the list.'))
else:
self.song.topics.append(topic)
topic_item = QtGui.QListWidgetItem(unicode(topic.name))
topic_item.setData(QtCore.Qt.UserRole,
QtCore.QVariant(topic.id))
self.TopicsListView.addItem(topic_item)
self.SongTopicCombo.setCurrentIndex(0) self.SongTopicCombo.setCurrentIndex(0)
else: else:
QtGui.QMessageBox.warning(self, QtGui.QMessageBox.warning(self,
@ -382,23 +400,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
self.TopicsListView.takeItem(row) self.TopicsListView.takeItem(row)
def onSongBookComboChanged(self, item): def onSongBookComboChanged(self, item):
item = int(self.SongbookCombo.currentIndex()) if item >= 1:
text = unicode(self.SongbookCombo.currentText())
if item == 0 and text:
if QtGui.QMessageBox.question(self,
translate('SongsPlugin.EditSongForm', 'Add Book'),
translate('SongsPlugin.EditSongForm', 'This song book does '
'not exist, do you want to add it?'),
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No,
QtGui.QMessageBox.Yes) == QtGui.QMessageBox.Yes:
book = Book.populate(name=text)
self.songmanager.save_object(book)
self.song.book = book
self.loadBooks()
else:
return
elif item >= 1:
item = int(self.SongbookCombo.currentIndex())
self.song.song_book_id = \ self.song.song_book_id = \
(self.SongbookCombo.itemData(item)).toInt()[0] (self.SongbookCombo.itemData(item)).toInt()[0]
else: else:
@ -616,12 +618,28 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
def accept(self): def accept(self):
log.debug(u'accept') log.debug(u'accept')
item = int(self.SongbookCombo.currentIndex())
text = unicode(self.SongbookCombo.currentText())
if item == 0 and text:
if QtGui.QMessageBox.question(self,
translate('SongsPlugin.EditSongForm', 'Add Book'),
translate('SongsPlugin.EditSongForm', 'This song book does '
'not exist, do you want to add it?'),
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No,
QtGui.QMessageBox.Yes) == QtGui.QMessageBox.Yes:
book = Book.populate(name=text)
self.songmanager.save_object(book)
self.song.book = book
self.loadBooks()
else:
return
if self.saveSong(): if self.saveSong():
Receiver.send_message(u'songs_load_list') Receiver.send_message(u'songs_load_list')
self.close() self.close()
def saveSong(self): def saveSong(self):
self.song.title = unicode(self.TitleEditItem.text()) self.song.title = unicode(self.TitleEditItem.text())
self.song.alternate_title = unicode(self.AlternativeEdit.text())
self.song.copyright = unicode(self.CopyrightEditItem.text()) self.song.copyright = unicode(self.CopyrightEditItem.text())
self.song.search_title = self.song.title + u'@' + \ self.song.search_title = self.song.title + u'@' + \
unicode(self.AlternativeEdit.text()) unicode(self.AlternativeEdit.text())

View File

@ -41,6 +41,7 @@ class Ui_SongBookDialog(object):
QtGui.QFormLayout.LabelRole, self.NameLabel) QtGui.QFormLayout.LabelRole, self.NameLabel)
self.NameEdit = QtGui.QLineEdit(SongBookDialog) self.NameEdit = QtGui.QLineEdit(SongBookDialog)
self.NameEdit.setObjectName(u'NameEdit') self.NameEdit.setObjectName(u'NameEdit')
self.NameLabel.setBuddy(self.NameEdit)
self.SongBookLayout.setWidget(0, self.SongBookLayout.setWidget(0,
QtGui.QFormLayout.FieldRole, self.NameEdit) QtGui.QFormLayout.FieldRole, self.NameEdit)
self.PublisherLabel = QtGui.QLabel(SongBookDialog) self.PublisherLabel = QtGui.QLabel(SongBookDialog)
@ -49,6 +50,7 @@ class Ui_SongBookDialog(object):
QtGui.QFormLayout.LabelRole, self.PublisherLabel) QtGui.QFormLayout.LabelRole, self.PublisherLabel)
self.PublisherEdit = QtGui.QLineEdit(SongBookDialog) self.PublisherEdit = QtGui.QLineEdit(SongBookDialog)
self.PublisherEdit.setObjectName(u'PublisherEdit') self.PublisherEdit.setObjectName(u'PublisherEdit')
self.PublisherLabel.setBuddy(self.PublisherEdit)
self.SongBookLayout.setWidget(1, self.SongBookLayout.setWidget(1,
QtGui.QFormLayout.FieldRole, self.PublisherEdit) QtGui.QFormLayout.FieldRole, self.PublisherEdit)
self.ButtonBox = QtGui.QDialogButtonBox(SongBookDialog) self.ButtonBox = QtGui.QDialogButtonBox(SongBookDialog)

View File

@ -102,7 +102,8 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
Reloads the Authors list. Reloads the Authors list.
""" """
self.AuthorsListWidget.clear() self.AuthorsListWidget.clear()
authors = self.songmanager.get_all_objects(Author, Author.display_name) authors = self.songmanager.get_all_objects(Author,
order_by_ref=Author.display_name)
for author in authors: for author in authors:
if author.display_name: if author.display_name:
author_name = QtGui.QListWidgetItem(author.display_name) author_name = QtGui.QListWidgetItem(author.display_name)
@ -117,7 +118,8 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
Reloads the Topics list. Reloads the Topics list.
""" """
self.TopicsListWidget.clear() self.TopicsListWidget.clear()
topics = self.songmanager.get_all_objects(Topic, Topic.name) topics = self.songmanager.get_all_objects(Topic,
order_by_ref=Topic.name)
for topic in topics: for topic in topics:
topic_name = QtGui.QListWidgetItem(topic.name) topic_name = QtGui.QListWidgetItem(topic.name)
topic_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(topic.id)) topic_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(topic.id))
@ -128,7 +130,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
Reloads the Books list. Reloads the Books list.
""" """
self.BooksListWidget.clear() self.BooksListWidget.clear()
books = self.songmanager.get_all_objects(Book, Book.name) books = self.songmanager.get_all_objects(Book, order_by_ref=Book.name)
for book in books: for book in books:
book_name = QtGui.QListWidgetItem(u'%s (%s)' % (book.name, book_name = QtGui.QListWidgetItem(u'%s (%s)' % (book.name,
book.publisher)) book.publisher))
@ -140,7 +142,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
Returns False if the given Author is already in the list otherwise Returns False if the given Author is already in the list otherwise
True. True.
""" """
authors = self.songmanager.get_all_objects_filtered(Author, authors = self.songmanager.get_all_objects(Author,
and_(Author.first_name == new_author.first_name, and_(Author.first_name == new_author.first_name,
Author.last_name == new_author.last_name, Author.last_name == new_author.last_name,
Author.display_name == new_author.display_name)) Author.display_name == new_author.display_name))
@ -162,7 +164,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
""" """
Returns False if the given Topic is already in the list otherwise True. Returns False if the given Topic is already in the list otherwise True.
""" """
topics = self.songmanager.get_all_objects_filtered(Topic, topics = self.songmanager.get_all_objects(Topic,
Topic.name == new_topic.name) Topic.name == new_topic.name)
if len(topics) > 0: if len(topics) > 0:
# If we edit an existing Topic, we need to make sure that we do # If we edit an existing Topic, we need to make sure that we do
@ -182,7 +184,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
""" """
Returns False if the given Book is already in the list otherwise True. Returns False if the given Book is already in the list otherwise True.
""" """
books = self.songmanager.get_all_objects_filtered(Book, books = self.songmanager.get_all_objects(Book,
and_(Book.name == new_book.name, and_(Book.name == new_book.name,
Book.publisher == new_book.publisher)) Book.publisher == new_book.publisher))
if len(books) > 0: if len(books) > 0:
@ -392,7 +394,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
and_(Author.first_name == old_author.first_name, and_(Author.first_name == old_author.first_name,
Author.last_name == old_author.last_name, Author.last_name == old_author.last_name,
Author.display_name == old_author.display_name)) Author.display_name == old_author.display_name))
songs = self.songmanager.get_all_objects_filtered(Song, songs = self.songmanager.get_all_objects(Song,
Song.authors.contains(old_author)) Song.authors.contains(old_author))
for song in songs: for song in songs:
# We check if the song has already existing_author as author. If # We check if the song has already existing_author as author. If
@ -412,7 +414,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
''' '''
existing_topic = self.songmanager.get_object_filtered(Topic, existing_topic = self.songmanager.get_object_filtered(Topic,
Topic.name == old_topic.name) Topic.name == old_topic.name)
songs = self.songmanager.get_all_objects_filtered(Song, songs = self.songmanager.get_all_objects(Song,
Song.topics.contains(old_topic)) Song.topics.contains(old_topic))
for song in songs: for song in songs:
# We check if the song has already existing_topic as topic. If that # We check if the song has already existing_topic as topic. If that
@ -433,7 +435,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
existing_book = self.songmanager.get_object_filtered(Book, existing_book = self.songmanager.get_object_filtered(Book,
and_(Book.name == old_book.name, and_(Book.name == old_book.name,
Book.publisher == old_book.publisher)) Book.publisher == old_book.publisher))
songs = self.songmanager.get_all_objects_filtered(Song, songs = self.songmanager.get_all_objects(Song,
Song.song_book_id == old_book.id) Song.song_book_id == old_book.id)
for song in songs: for song in songs:
song.song_book_id = existing_book.id song.song_book_id = existing_book.id

View File

@ -142,6 +142,7 @@ from songstab import SongsTab
from mediaitem import SongMediaItem from mediaitem import SongMediaItem
from songimport import SongImport from songimport import SongImport
from opensongimport import OpenSongImport from opensongimport import OpenSongImport
from olpimport import OpenLPSongImport
try: try:
from sofimport import SofImport from sofimport import SofImport
from oooimport import OooImport from oooimport import OooImport

View File

@ -46,6 +46,12 @@ class Book(BaseModel):
return u'<Book id="%s" name="%s" publisher="%s" />' % ( return u'<Book id="%s" name="%s" publisher="%s" />' % (
str(self.id), self.name, self.publisher) str(self.id), self.name, self.publisher)
class MediaFile(BaseModel):
"""
MediaFile model
"""
pass
class Song(BaseModel): class Song(BaseModel):
""" """
Song model Song model
@ -75,6 +81,13 @@ def init_schema(url):
Column(u'display_name', types.Unicode(255), nullable=False) Column(u'display_name', types.Unicode(255), nullable=False)
) )
# Definition of the "media_files" table
media_files_table = Table(u'media_files', metadata,
Column(u'id', types.Integer, primary_key=True),
Column(u'file_name', types.Unicode(255), nullable=False),
Column(u'type', types.Unicode(64), nullable=False, default=u'audio')
)
# Definition of the "song_books" table # Definition of the "song_books" table
song_books_table = Table(u'song_books', metadata, song_books_table = Table(u'song_books', metadata,
Column(u'id', types.Integer, primary_key=True), Column(u'id', types.Integer, primary_key=True),
@ -88,6 +101,7 @@ def init_schema(url):
Column(u'song_book_id', types.Integer, Column(u'song_book_id', types.Integer,
ForeignKey(u'song_books.id'), default=0), ForeignKey(u'song_books.id'), default=0),
Column(u'title', types.Unicode(255), nullable=False), Column(u'title', types.Unicode(255), nullable=False),
Column(u'alternate_title', types.Unicode(255)),
Column(u'lyrics', types.UnicodeText, nullable=False), Column(u'lyrics', types.UnicodeText, nullable=False),
Column(u'verse_order', types.Unicode(128)), Column(u'verse_order', types.Unicode(128)),
Column(u'copyright', types.Unicode(255)), Column(u'copyright', types.Unicode(255)),
@ -113,6 +127,14 @@ def init_schema(url):
ForeignKey(u'songs.id'), primary_key=True) ForeignKey(u'songs.id'), primary_key=True)
) )
# Definition of the "media_files_songs" table
media_files_songs_table = Table(u'media_files_songs', metadata,
Column(u'media_file_id', types.Integer,
ForeignKey(u'media_files.id'), primary_key=True),
Column(u'song_id', types.Integer,
ForeignKey(u'songs.id'), primary_key=True)
)
# Definition of the "songs_topics" table # Definition of the "songs_topics" table
songs_topics_table = Table(u'songs_topics', metadata, songs_topics_table = Table(u'songs_topics', metadata,
Column(u'song_id', types.Integer, Column(u'song_id', types.Integer,
@ -125,6 +147,7 @@ def init_schema(url):
Index(u'authors_id', authors_table.c.id) Index(u'authors_id', authors_table.c.id)
Index(u'authors_display_name_id', authors_table.c.display_name, Index(u'authors_display_name_id', authors_table.c.display_name,
authors_table.c.id) authors_table.c.id)
Index(u'media_files_id', media_files_table.c.id)
Index(u'song_books_id', song_books_table.c.id) Index(u'song_books_id', song_books_table.c.id)
Index(u'songs_id', songs_table.c.id) Index(u'songs_id', songs_table.c.id)
Index(u'topics_id', topics_table.c.id) Index(u'topics_id', topics_table.c.id)
@ -132,6 +155,10 @@ def init_schema(url):
authors_songs_table.c.song_id) authors_songs_table.c.song_id)
Index(u'authors_songs_song', authors_songs_table.c.song_id, Index(u'authors_songs_song', authors_songs_table.c.song_id,
authors_songs_table.c.author_id) authors_songs_table.c.author_id)
Index(u'media_files_songs_file', media_files_songs_table.c.media_file_id,
media_files_songs_table.c.song_id)
Index(u'media_files_songs_song', media_files_songs_table.c.song_id,
media_files_songs_table.c.media_file_id)
Index(u'topics_song_topic', songs_topics_table.c.topic_id, Index(u'topics_song_topic', songs_topics_table.c.topic_id,
songs_topics_table.c.song_id) songs_topics_table.c.song_id)
Index(u'topics_song_song', songs_topics_table.c.song_id, Index(u'topics_song_song', songs_topics_table.c.song_id,
@ -139,12 +166,17 @@ def init_schema(url):
mapper(Author, authors_table) mapper(Author, authors_table)
mapper(Book, song_books_table) mapper(Book, song_books_table)
mapper(MediaFile, media_files_table)
mapper(Song, songs_table, mapper(Song, songs_table,
properties={'authors': relation(Author, backref='songs', properties={
secondary=authors_songs_table), 'authors': relation(Author, backref='songs',
secondary=authors_songs_table),
'book': relation(Book, backref='songs'), 'book': relation(Book, backref='songs'),
'media_files': relation(MediaFile, backref='songs',
secondary=media_files_songs_table),
'topics': relation(Topic, backref='songs', 'topics': relation(Topic, backref='songs',
secondary=songs_topics_table)}) secondary=songs_topics_table)
})
mapper(Topic, topics_table) mapper(Topic, topics_table)
metadata.create_all(checkfirst=True) metadata.create_all(checkfirst=True)

View File

@ -164,20 +164,20 @@ class SongMediaItem(MediaManagerItem):
search_type = self.SearchTypeComboBox.currentIndex() search_type = self.SearchTypeComboBox.currentIndex()
if search_type == 0: if search_type == 0:
log.debug(u'Titles Search') log.debug(u'Titles Search')
search_results = self.parent.manager.get_all_objects_filtered(Song, search_results = self.parent.manager.get_all_objects(Song,
Song.search_title.like(u'%' + search_keywords + u'%'), Song.search_title.like(u'%' + search_keywords + u'%'),
Song.search_title.asc()) Song.search_title.asc())
self.displayResultsSong(search_results) self.displayResultsSong(search_results)
elif search_type == 1: elif search_type == 1:
log.debug(u'Lyrics Search') log.debug(u'Lyrics Search')
search_results = self.parent.manager.get_all_objects_filtered(Song, search_results = self.parent.manager.get_all_objects(Song,
Song.search_lyrics.like(u'%' + search_keywords + u'%'), Song.search_lyrics.like(u'%' + search_keywords + u'%'),
Song.search_lyrics.asc()) Song.search_lyrics.asc())
self.displayResultsSong(search_results) self.displayResultsSong(search_results)
elif search_type == 2: elif search_type == 2:
log.debug(u'Authors Search') log.debug(u'Authors Search')
search_results = self.parent.manager.get_all_objects_filtered( search_results = self.parent.manager.get_all_objects(Author,
Author, Author.display_name.like(u'%' + search_keywords + u'%'), Author.display_name.like(u'%' + search_keywords + u'%'),
Author.display_name.asc()) Author.display_name.asc())
self.displayResultsAuthor(search_results) self.displayResultsAuthor(search_results)
#Called to redisplay the song list screen edith from a search #Called to redisplay the song list screen edith from a search

View File

@ -0,0 +1,200 @@
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# This program is free software; you can redistribute it and/or modify it #
# under the terms of the GNU General Public License as published by the Free #
# Software Foundation; version 2 of the License. #
# #
# This program is distributed in the hope that it will be useful, but WITHOUT #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
# more details. #
# #
# You should have received a copy of the GNU General Public License along #
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
"""
The :mod:`olpimport` module provides the functionality for importing OpenLP
song databases into the current installation database.
"""
import logging
from sqlalchemy import create_engine, MetaData
from sqlalchemy.orm import class_mapper, mapper, relation, scoped_session, \
sessionmaker
from sqlalchemy.orm.exc import UnmappedClassError
from openlp.core.lib.db import BaseModel
from openlp.plugins.songs.lib.db import Author, Book, Song, Topic #, MediaFile
log = logging.getLogger(__name__)
class OldAuthor(BaseModel):
"""
Author model
"""
pass
class OldBook(BaseModel):
"""
Book model
"""
pass
class OldMediaFile(BaseModel):
"""
MediaFile model
"""
pass
class OldSong(BaseModel):
"""
Song model
"""
pass
class OldTopic(BaseModel):
"""
Topic model
"""
pass
class OpenLPSongImport(object):
"""
"""
def __init__(self, master_manager, source_db):
"""
"""
self.master_manager = master_manager
self.import_source = source_db
self.source_session = None
def import_source_v2_db(self):
"""
"""
engine = create_engine(self.import_source)
source_meta = MetaData()
source_meta.reflect(engine)
self.source_session = scoped_session(sessionmaker(bind=engine))
if u'media_files' in source_meta.tables.keys():
has_media_files = True
else:
has_media_files = False
source_authors_table = source_meta.tables[u'authors']
source_song_books_table = source_meta.tables[u'song_books']
source_songs_table = source_meta.tables[u'songs']
source_topics_table = source_meta.tables[u'topics']
source_authors_songs_table = source_meta.tables[u'authors_songs']
source_songs_topics_table = source_meta.tables[u'songs_topics']
if has_media_files:
source_media_files_table = source_meta.tables[u'media_files']
source_media_files_songs_table = \
source_meta.tables[u'media_files_songs']
try:
class_mapper(OldMediaFile)
except UnmappedClassError:
mapper(OldMediaFile, source_media_files_table)
song_props = {
'authors': relation(OldAuthor, backref='songs',
secondary=source_authors_songs_table),
'book': relation(OldBook, backref='songs'),
'topics': relation(OldTopic, backref='songs',
secondary=source_songs_topics_table)
}
if has_media_files:
song_props['media_files'] = relation(OldMediaFile, backref='songs',
secondary=source_media_files_songs_table)
try:
class_mapper(OldAuthor)
except UnmappedClassError:
mapper(OldAuthor, source_authors_table)
try:
class_mapper(OldBook)
except UnmappedClassError:
mapper(OldBook, source_song_books_table)
try:
class_mapper(OldSong)
except UnmappedClassError:
mapper(OldSong, source_songs_table, properties=song_props)
try:
class_mapper(OldTopic)
except UnmappedClassError:
mapper(OldTopic, source_topics_table)
source_songs = self.source_session.query(OldSong).all()
for song in source_songs:
new_song = Song()
new_song.title = song.title
if has_media_files:
new_song.alternate_title = song.alternate_title
else:
new_song.alternate_title = u''
new_song.search_title = song.search_title
new_song.song_number = song.song_number
new_song.lyrics = song.lyrics
new_song.search_lyrics = song.search_lyrics
new_song.verse_order = song.verse_order
new_song.copyright = song.copyright
new_song.comments = song.comments
new_song.theme_name = song.theme_name
new_song.ccli_number = song.ccli_number
if song.authors:
for author in song.authors:
existing_author = self.master_manager.get_object_filtered(
Author, Author.display_name == author.display_name)
if existing_author:
new_song.authors.append(existing_author)
else:
new_song.authors.append(Author.populate(
first_name=author.first_name,
last_name=author.last_name,
display_name=author.display_name))
else:
au = self.master_manager.get_object_filtered(Author,
Author.display_name == u'Author Unknown')
if au:
new_song.authors.append(au)
else:
new_song.authors.append(Author.populate(
display_name=u'Author Unknown'))
if song.song_book_id != 0:
existing_song_book = self.master_manager.get_object_filtered(
Book, Book.name == song.book.name)
if existing_song_book:
new_song.book = existing_song_book
else:
new_song.book = Book.populate(name=song.book.name,
publisher=song.book.publisher)
if song.topics:
for topic in song.topics:
existing_topic = self.master_manager.get_object_filtered(
Topic, Topic.name == topic.name)
if existing_topic:
new_song.topics.append(existing_topic)
else:
new_song.topics.append(Topic.populate(name=topic.name))
# if has_media_files:
# if song.media_files:
# for media_file in song.media_files:
# existing_media_file = \
# self.master_manager.get_object_filtered(MediaFile,
# MediaFile.file_name == media_file.file_name)
# if existing_media_file:
# new_song.media_files.append(existing_media_file)
# else:
# new_song.media_files.append(MediaFile.populate(
# file_name=media_file.file_name))
self.master_manager.save_object(new_song)
engine.dispose()

View File

@ -23,17 +23,13 @@
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
import logging
import os import os
import re
from zipfile import ZipFile from zipfile import ZipFile
from lxml.etree import Element
from lxml import objectify from lxml import objectify
from openlp.plugins.songs.lib.songimport import SongImport from openlp.plugins.songs.lib.songimport import SongImport
import logging
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
class OpenSongImportError(Exception): class OpenSongImportError(Exception):
@ -148,8 +144,6 @@ class OpenSongImport(object):
self.song_import.__setattr__(fn_or_string, ustring) self.song_import.__setattr__(fn_or_string, ustring)
else: else:
fn_or_string(ustring) fn_or_string(ustring)
res = []
if u'theme' in fields: if u'theme' in fields:
self.song_import.topics.append(unicode(root.theme)) self.song_import.topics.append(unicode(root.theme))
if u'alttheme' in fields: if u'alttheme' in fields:
@ -218,7 +212,6 @@ class OpenSongImport(object):
versetypes = verses.keys() versetypes = verses.keys()
versetypes.sort() versetypes.sort()
versetags = {} versetags = {}
verse_renames = {}
for versetype in versetypes: for versetype in versetypes:
versenums = verses[versetype].keys() versenums = verses[versetype].keys()
versenums.sort() versenums.sort()
@ -241,6 +234,7 @@ class OpenSongImport(object):
log.warn(u'Got order %s but not in versetags, skipping', tag) log.warn(u'Got order %s but not in versetags, skipping', tag)
else: else:
self.song_import.verse_order_list.append(tag) self.song_import.verse_order_list.append(tag)
def finish(self): def finish(self):
""" Separate function, allows test suite to not pollute database""" """ Separate function, allows test suite to not pollute database"""
self.song_import.finish() self.song_import.finish()

View File

@ -50,7 +50,7 @@ class SongImport(object):
self.song_number = u'' self.song_number = u''
self.alternate_title = u'' self.alternate_title = u''
self.copyright = u'' self.copyright = u''
self.comment = u'' self.comments = u''
self.theme_name = u'' self.theme_name = u''
self.ccli_number = u'' self.ccli_number = u''
self.authors = [] self.authors = []
@ -253,7 +253,7 @@ class SongImport(object):
song.lyrics = unicode(sxml.extract_xml(), u'utf-8') song.lyrics = unicode(sxml.extract_xml(), u'utf-8')
song.verse_order = u' '.join(self.verse_order_list) song.verse_order = u' '.join(self.verse_order_list)
song.copyright = self.copyright song.copyright = self.copyright
song.comment = self.comment song.comments = self.comments
song.theme_name = self.theme_name song.theme_name = self.theme_name
song.ccli_number = self.ccli_number song.ccli_number = self.ccli_number
for authortext in self.authors: for authortext in self.authors:
@ -274,7 +274,8 @@ class SongImport(object):
for topictext in self.topics: for topictext in self.topics:
if len(topictext) == 0: if len(topictext) == 0:
continue continue
topic = self.manager.get_object_filtered(Topic, Topic.name == topictext) topic = self.manager.get_object_filtered(Topic,
Topic.name == topictext)
if topic is None: if topic is None:
topic = Topic.populate(name=topictext) topic = Topic.populate(name=topictext)
song.topics.append(topic) song.topics.append(topic)
@ -303,8 +304,8 @@ class SongImport(object):
print u'NUMBER: ' + self.song_number print u'NUMBER: ' + self.song_number
for topictext in self.topics: for topictext in self.topics:
print u'TOPIC: ' + topictext print u'TOPIC: ' + topictext
if self.comment: if self.comments:
print u'COMMENT: ' + self.comment print u'COMMENTS: ' + self.comments
if self.theme_name: if self.theme_name:
print u'THEME: ' + self.theme_name print u'THEME: ' + self.theme_name
if self.ccli_number: if self.ccli_number:

View File

@ -28,7 +28,6 @@ import logging
#import os #import os
from types import ListType from types import ListType
from xml.etree.ElementTree import ElementTree, XML
# Do we need these two lines? # Do we need these two lines?
#sys.path.append(os.path.abspath(u'./../../../..')) #sys.path.append(os.path.abspath(u'./../../../..'))

View File

@ -22,11 +22,10 @@
# with this program; if not, write to the Free Software Foundation, Inc., 59 # # with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Temple Place, Suite 330, Boston, MA 02111-1307 USA #
############################################################################### ###############################################################################
from openlp.plugins.songs.lib.opensongimport import OpenSongImport from openlp.plugins.songs.lib.opensongimport import OpenSongImport
from openlp.core.lib.db import Manager from openlp.core.lib.db import Manager
from openlp.plugins.songs.lib.db import init_schema from openlp.plugins.songs.lib.db import init_schema
from openlp.plugins.songs.songsplugin import SongsPlugin
import sys
def test(): def test():
manager = Manager(u'songs', init_schema) manager = Manager(u'songs', init_schema)

View File

@ -30,7 +30,7 @@ from PyQt4 import QtCore, QtGui
from openlp.core.lib import Plugin, build_icon, PluginStatus, Receiver, \ from openlp.core.lib import Plugin, build_icon, PluginStatus, Receiver, \
translate translate
from openlp.core.lib.db import Manager from openlp.core.lib.db import Manager
from openlp.plugins.songs.lib import SongMediaItem, SongsTab from openlp.plugins.songs.lib import OpenLPSongImport, SongMediaItem, SongsTab
from openlp.plugins.songs.lib.db import init_schema, Song from openlp.plugins.songs.lib.db import init_schema, Song
try: try:
@ -71,7 +71,7 @@ class SongsPlugin(Plugin):
log.info(u'Songs Initialising') log.info(u'Songs Initialising')
Plugin.initialise(self) Plugin.initialise(self)
self.mediaItem.displayResultsSong( self.mediaItem.displayResultsSong(
self.manager.get_all_objects(Song, Song.title)) self.manager.get_all_objects(Song, order_by_ref=Song.title))
def getMediaManagerItem(self): def getMediaManagerItem(self):
""" """
@ -157,7 +157,19 @@ class SongsPlugin(Plugin):
import_menu.addAction(self.ImportOpenSongItem) import_menu.addAction(self.ImportOpenSongItem)
QtCore.QObject.connect(self.ImportOpenSongItem, QtCore.QObject.connect(self.ImportOpenSongItem,
QtCore.SIGNAL(u'triggered()'), self.onImportOpenSongItemClick) QtCore.SIGNAL(u'triggered()'), self.onImportOpenSongItemClick)
# OpenLP v2 import menu item - ditto above regarding refactoring into
# an import wizard
self.ImportOpenLPSongItem = QtGui.QAction(import_menu)
self.ImportOpenLPSongItem.setObjectName(u'ImportOpenLPSongItem')
self.ImportOpenLPSongItem.setText(translate('SongsPlugin',
'OpenLP v2 Songs (temporary)'))
self.ImportOpenLPSongItem.setToolTip(translate('SongsPlugin',
'Import an OpenLP v2 song database'))
self.ImportOpenLPSongItem.setStatusTip(translate('SongsPlugin',
'Import an OpenLP v2 song database'))
import_menu.addAction(self.ImportOpenLPSongItem)
QtCore.QObject.connect(self.ImportOpenLPSongItem,
QtCore.SIGNAL(u'triggered()'), self.onImportOpenLPSongItemClick)
def addExportMenuItem(self, export_menu): def addExportMenuItem(self, export_menu):
""" """
@ -218,6 +230,25 @@ class SongsPlugin(Plugin):
QtGui.QMessageBox.Ok) QtGui.QMessageBox.Ok)
Receiver.send_message(u'songs_load_list') Receiver.send_message(u'songs_load_list')
def onImportOpenLPSongItemClick(self):
filenames = QtGui.QFileDialog.getOpenFileNames(None,
translate('SongsPlugin', 'Select OpenLP database(s) to import...'),
u'', u'OpenLP databases (*.sqlite);;All Files (*)')
try:
for filename in filenames:
db_url = u'sqlite:///%s' % filename
importer = OpenLPSongImport(self.manager, db_url)
importer.import_source_v2_db()
QtGui.QMessageBox.information(None, translate('SongsPlugin',
'Database(s) imported'), translate('SongsPlugin', 'Your '
'OpenLP v2 song databases have been successfully imported'))
except:
log.exception(u'Failed to import OpenLP v2 database(s)')
QtGui.QMessageBox.critical(None, translate('SongsPlugin',
'Import Error'), translate('SongsPlugin',
'Error importing OpenLP v2 database(s)'))
Receiver.send_message(u'songs_load_list')
def onImportOooItemClick(self): def onImportOooItemClick(self):
filenames = QtGui.QFileDialog.getOpenFileNames( filenames = QtGui.QFileDialog.getOpenFileNames(
None, translate('SongsPlugin', None, translate('SongsPlugin',
@ -239,8 +270,7 @@ class SongsPlugin(Plugin):
Returns True if the theme is being used, otherwise returns False. Returns True if the theme is being used, otherwise returns False.
""" """
if self.manager.get_all_objects_filtered(Song, if self.manager.get_all_objects(Song, Song.theme_name == theme):
Song.theme_name == theme):
return True return True
return False return False
@ -255,7 +285,7 @@ class SongsPlugin(Plugin):
``newTheme`` ``newTheme``
The new name the plugin should now use. The new name the plugin should now use.
""" """
songsUsingTheme = self.manager.get_all_objects_filtered(Song, songsUsingTheme = self.manager.get_all_objects(Song,
Song.theme_name == oldTheme) Song.theme_name == oldTheme)
for song in songsUsingTheme: for song in songsUsingTheme:
song.theme_name = newTheme song.theme_name = newTheme

View File

@ -25,8 +25,9 @@
from PyQt4 import QtGui from PyQt4 import QtGui
from songusagedeletedialog import Ui_SongUsageDeleteDialog
from openlp.core.lib import translate from openlp.core.lib import translate
from openlp.plugins.songusage.lib.db import SongUsageItem
from songusagedeletedialog import Ui_SongUsageDeleteDialog
class SongUsageDeleteForm(QtGui.QDialog, Ui_SongUsageDeleteDialog): class SongUsageDeleteForm(QtGui.QDialog, Ui_SongUsageDeleteDialog):
""" """
@ -52,6 +53,6 @@ class SongUsageDeleteForm(QtGui.QDialog, Ui_SongUsageDeleteDialog):
QtGui.QMessageBox.Cancel) QtGui.QMessageBox.Cancel)
if ret == QtGui.QMessageBox.Ok: if ret == QtGui.QMessageBox.Ok:
deleteDate = self.DeleteCalendar.selectedDate().toPyDate() deleteDate = self.DeleteCalendar.selectedDate().toPyDate()
self.songusagemanager.delete_to_date(deleteDate) self.songusagemanager.delete_all_objects(SongUsageItem,
SongUsageItem.usagedate <= deleteDate)
self.close() self.close()

View File

@ -27,9 +27,10 @@ import logging
import os import os
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from sqlalchemy.sql import and_
from openlp.core.lib import SettingsManager, translate from openlp.core.lib import SettingsManager, translate
from openlp.plugins.songusage.lib.db import SongUsageItem
from songusagedetaildialog import Ui_SongUsageDetailDialog from songusagedetaildialog import Ui_SongUsageDetailDialog
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -74,8 +75,11 @@ class SongUsageDetailForm(QtGui.QDialog, Ui_SongUsageDetailDialog):
filename = u'usage_detail_%s_%s.txt' % ( filename = u'usage_detail_%s_%s.txt' % (
self.FromDate.selectedDate().toString(u'ddMMyyyy'), self.FromDate.selectedDate().toString(u'ddMMyyyy'),
self.ToDate.selectedDate().toString(u'ddMMyyyy')) self.ToDate.selectedDate().toString(u'ddMMyyyy'))
usage = self.parent.songusagemanager.get_songusage_for_period( usage = self.parent.songusagemanager.get_all_objects(
self.FromDate.selectedDate(), self.ToDate.selectedDate()) SongUsageItem, and_(
SongUsageItem.usagedate >= self.FromDate.selectedDate().toPyDate(),
SongUsageItem.usagedate < self.ToDate.selectedDate().toPyDate()),
[SongUsageItem.usagedate, SongUsageItem.usagetime])
outname = os.path.join(unicode(self.FileLineEdit.text()), filename) outname = os.path.join(unicode(self.FileLineEdit.text()), filename)
file = None file = None
try: try:

View File

@ -25,4 +25,3 @@
""" """
The :mod:`lib` module contains the library functions for the songusage plugin. The :mod:`lib` module contains the library functions for the songusage plugin.
""" """
from openlp.plugins.songusage.lib.manager import SongUsageManager

View File

@ -1,81 +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 #
###############################################################################
"""
The :mod:`manager` module provides song usage specific database query code
"""
import logging
from sqlalchemy.exceptions import InvalidRequestError
from openlp.core.lib.db import Manager
from openlp.plugins.songusage.lib.db import init_schema, SongUsageItem
log = logging.getLogger(__name__)
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.
"""
log.info(u'SongUsage manager loaded')
def __init__(self):
"""
Creates the connection to the database, and creates the tables if they
don't exist.
"""
log.debug(u'SongUsage Initialising')
Manager.__init__(self, u'songusage', init_schema)
log.debug(u'SongUsage Initialised')
def get_songusage_for_period(self, start_date, end_date):
"""
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 delete_to_date(self, date):
"""
Delete SongUsage records before given date
"""
try:
self.session.query(SongUsageItem) \
.filter(SongUsageItem.usagedate <= date) \
.delete(synchronize_session=False)
self.session.commit()
return True
except InvalidRequestError:
self.session.rollback()
log.exception(u'Failed to delete all Song Usage items to %s' % date)
return False

View File

@ -24,15 +24,15 @@
############################################################################### ###############################################################################
import logging import logging
from datetime import datetime from datetime import datetime
from PyQt4 import QtCore, QtGui from PyQt4 import QtCore, QtGui
from openlp.core.lib import Plugin, Receiver, build_icon, translate from openlp.core.lib import Plugin, Receiver, build_icon, translate
from openlp.plugins.songusage.lib import SongUsageManager from openlp.core.lib.db import Manager
from openlp.plugins.songusage.forms import SongUsageDetailForm, \ from openlp.plugins.songusage.forms import SongUsageDetailForm, \
SongUsageDeleteForm SongUsageDeleteForm
from openlp.plugins.songusage.lib.db import SongUsageItem from openlp.plugins.songusage.lib.db import init_schema, SongUsageItem
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
@ -117,7 +117,7 @@ class SongUsagePlugin(Plugin):
QtCore.QVariant(False)).toBool() QtCore.QVariant(False)).toBool()
self.SongUsageStatus.setChecked(self.SongUsageActive) self.SongUsageStatus.setChecked(self.SongUsageActive)
if self.songusagemanager is None: if self.songusagemanager is None:
self.songusagemanager = SongUsageManager() self.songusagemanager = Manager(u'songusage', init_schema)
self.SongUsagedeleteform = SongUsageDeleteForm(self.songusagemanager) self.SongUsagedeleteform = SongUsageDeleteForm(self.songusagemanager)
self.SongUsagedetailform = SongUsageDetailForm(self) self.SongUsagedetailform = SongUsageDetailForm(self)
self.SongUsageMenu.menuAction().setVisible(True) self.SongUsageMenu.menuAction().setVisible(True)