From 11bede8fd81b24c7e414b2f90e1d09f8f27adb52 Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Sat, 17 Jan 2009 13:58:16 +0000 Subject: [PATCH] Updating the SongsManager to use SQLAlchemy bzr-revno: 284 --- .eric4project/openlp.org 2.0.e4q | 2 +- .eric4project/openlp.org 2.0.e4t | 2 +- openlp.org 2.0.e4p | 6 +- openlp/plugins/songs/forms/editsongform.py | 46 ++-- .../songs/lib/{songclasses.py => classes.py} | 0 openlp/plugins/songs/lib/models.py | 4 +- openlp/plugins/songs/lib/songmanager.py | 260 ++++++------------ .../songs/lib/{songtables.py => tables.py} | 0 8 files changed, 113 insertions(+), 207 deletions(-) rename openlp/plugins/songs/lib/{songclasses.py => classes.py} (100%) rename openlp/plugins/songs/lib/{songtables.py => tables.py} (100%) diff --git a/.eric4project/openlp.org 2.0.e4q b/.eric4project/openlp.org 2.0.e4q index 82e9567a6..63d35f777 100644 --- a/.eric4project/openlp.org 2.0.e4q +++ b/.eric4project/openlp.org 2.0.e4q @@ -1,7 +1,7 @@ - + \ No newline at end of file diff --git a/.eric4project/openlp.org 2.0.e4t b/.eric4project/openlp.org 2.0.e4t index bf893b274..0512aad27 100644 --- a/.eric4project/openlp.org 2.0.e4t +++ b/.eric4project/openlp.org 2.0.e4t @@ -1,7 +1,7 @@ - + TODO: what is the tags for bridge, pre-chorus? diff --git a/openlp.org 2.0.e4p b/openlp.org 2.0.e4p index 2c31308b3..3e2e55bb1 100644 --- a/openlp.org 2.0.e4p +++ b/openlp.org 2.0.e4p @@ -1,7 +1,7 @@ - + Python @@ -65,9 +65,7 @@ openlp/core/test/testplugins/testplugin2/testplugin2.py openlp/plugins/bibles/bibleplugin.py openlp/plugins/bibles/forms/bibleimportdialog.py - openlp/plugins/bibles/forms/bibleimportprogressform.py openlp/plugins/bibles/forms/bibleimportform.py - openlp/plugins/bibles/forms/bibleimportprogressdialog.py openlp/plugins/bibles/lib/biblemanager.py openlp/plugins/bibles/lib/bibleDBimpl.py openlp/plugins/bibles/lib/bibleOSISimpl.py @@ -113,6 +111,8 @@ openlp/migration/migratesongs.py openlp/migration/display.py openlp/migration/migratebibles.py + openlp/plugins/songs/lib/songclasses.py + openlp/plugins/songs/lib/songtables.py
resources/forms/openlpexportform.ui
diff --git a/openlp/plugins/songs/forms/editsongform.py b/openlp/plugins/songs/forms/editsongform.py index 6e605f28a..d8a3b79a3 100644 --- a/openlp/plugins/songs/forms/editsongform.py +++ b/openlp/plugins/songs/forms/editsongform.py @@ -27,7 +27,7 @@ from songbookform import SongBookForm from editsongdialog import Ui_EditSongDialog -from openlp.plugins.songs.lib.songtable import * +from openlp.plugins.songs.lib.models import Session, Song, Author, Topic class EditSongForm(QWidget, Ui_EditSongDialog): """ @@ -42,18 +42,18 @@ class EditSongForm(QWidget, Ui_EditSongDialog): self.songmanager = songmanager self.authors_form = AuthorsForm(self.songmanager) self.topics_form = TopicsForm(self.songmanager) - self.song_book_form = SongBookForm(self.songmanager) + self.song_book_form = SongBookForm(self.songmanager) self.initialise() self.AuthorsListView.setColumnCount(2) self.AuthorsListView.setColumnHidden(0, True) self.AuthorsListView.setColumnWidth(1, 200) self.AuthorsListView.setShowGrid(False) - self.AuthorsListView.setSortingEnabled(False) + self.AuthorsListView.setSortingEnabled(False) self.AuthorsListView.setAlternatingRowColors(True) - self.savebutton = self.ButtonBox.button(QtGui.QDialogButtonBox.Save) - - + self.savebutton = self.ButtonBox.button(QtGui.QDialogButtonBox.Save) + + def initialise(self): list = self.songmanager.get_authors() self.AuthorsSelectionComboItem.clear() @@ -66,23 +66,23 @@ class EditSongForm(QWidget, Ui_EditSongDialog): else: self.songid = songid self.song = self.songmanager.get_song(songid) - self.TitleEditItem.setText(self.song.title) + self.TitleEditItem.setText(self.song.title) self.LyricsTextEdit.setText(self.song.lyrics) self.CopyrightEditItem.setText(self.song.copyright) self.AuthorsListView.clear() # clear the results self.AuthorsListView.setHorizontalHeaderLabels(QtCore.QStringList(["","Author"])) - self.AuthorsListView.setVerticalHeaderLabels(QtCore.QStringList([""])) + self.AuthorsListView.setVerticalHeaderLabels(QtCore.QStringList([""])) self.AuthorsListView.setRowCount(0) for author in self.song.authors: c = self.AuthorsListView.rowCount() self.AuthorsListView.setRowCount(c+1) twi = QtGui.QTableWidgetItem(str(author.id)) - self.AuthorsListView.setItem(c , 0, twi) + self.AuthorsListView.setItem(c , 0, twi) twi = QtGui.QTableWidgetItem(str(author.display_name)) - self.AuthorsListView.setItem(c , 1, twi) + self.AuthorsListView.setItem(c , 1, twi) self.AuthorsListView.setRowHeight(c, 20) - self._validate_song() + self._validate_song() @pyqtSignature("") def on_AddAuthorsButton_clicked(self): @@ -90,7 +90,7 @@ class EditSongForm(QWidget, Ui_EditSongDialog): Slot documentation goes here. """ self.authors_form.load_form() - self.authors_form.show() + self.authors_form.show() @pyqtSignature("") def on_AddTopicButton_clicked(self): @@ -100,18 +100,18 @@ class EditSongForm(QWidget, Ui_EditSongDialog): self.topics_form.load_form() self.topics_form.show() @pyqtSignature("") - + def on_AddSongBookButton_clicked(self): """ Slot documentation goes here. """ self.song_book_form.load_form() - self.song_book_form.show() - + self.song_book_form.show() + def _validate_song(self): """ Check the validity of the form. Only display the 'save' if the data can be saved. - """ + """ valid = True # Lets be nice and assume the data is correct. if len(self.TitleEditItem.displayText()) == 0: #Song title missing valid = False @@ -122,23 +122,23 @@ class EditSongForm(QWidget, Ui_EditSongDialog): valid = False self._color_widget(self.CopyrightEditItem, True) else: - self._color_widget(self.CopyrightEditItem, False) - + self._color_widget(self.CopyrightEditItem, False) + if valid: self.ButtonBox.addButton(self.savebutton, QtGui.QDialogButtonBox.AcceptRole) # hide the save button tile screen is valid else: self.ButtonBox.removeButton(self.savebutton) # hide the save button tile screen is valid - + def _color_widget(self, slot, invalid): r = Qt.QPalette(slot.palette()) if invalid == True: r.setColor(Qt.QPalette.Base, Qt.QColor('darkRed')) else: - r.setColor(Qt.QPalette.Base, Qt.QColor('white')) + r.setColor(Qt.QPalette.Base, Qt.QColor('white')) slot.setPalette(r) - slot.setAutoFillBackground(True) - + slot.setAutoFillBackground(True) + def on_TitleEditItem_lostFocus(self): self._validate_song() def on_CopyrightEditItem_lostFocus(self): - self._validate_song() + self._validate_song() diff --git a/openlp/plugins/songs/lib/songclasses.py b/openlp/plugins/songs/lib/classes.py similarity index 100% rename from openlp/plugins/songs/lib/songclasses.py rename to openlp/plugins/songs/lib/classes.py diff --git a/openlp/plugins/songs/lib/models.py b/openlp/plugins/songs/lib/models.py index 368c76ced..d6294e23c 100644 --- a/openlp/plugins/songs/lib/models.py +++ b/openlp/plugins/songs/lib/models.py @@ -23,10 +23,10 @@ from sqlalchemy.orm import scoped_session, sessionmaker, mapper, relation from openlp.plugins.songs.lib.tables import * from openlp.plugins.songs.lib.classes import * -Session = None +session = None def init_models(url): - Session = scoped_session(sessionmaker(autoflush=True, autocommit=False, + session = scoped_session(sessionmaker(autoflush=True, autocommit=False, bind=create_engine(url))) diff --git a/openlp/plugins/songs/lib/songmanager.py b/openlp/plugins/songs/lib/songmanager.py index 0dc384ade..30f91aee9 100644 --- a/openlp/plugins/songs/lib/songmanager.py +++ b/openlp/plugins/songs/lib/songmanager.py @@ -21,215 +21,121 @@ Place, Suite 330, Boston, MA 02111-1307 USA import os, os.path import sys -from songDBimpl import SongDBImpl +from sqlalchemy.orm import asc, desc, like +from openlp.plugins.songs.lib.models import init_models, metadata, session, \ + songs_table, Song, Author, Topic import logging class SongManager(): + """ + 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. + """ + global log log=logging.getLogger("SongManager") log.info("Song manager loaded") + def __init__(self, config): """ - Finds all the bibles defined for the system - Creates an Interface Object for each bible containing connection information - Throws Exception if no Bibles are found. - - Init confirms the bible exists and stores the database path. + Creates the connection to the database, and creates the tables if they + don't exist. """ self.config = config log.debug( "Song Initialising") - self.songDBCache = None - self.authorcache = None - self.songPath = self.config.get_data_path() - self.songSuffix = "sqlite" - log.debug("Song Path %s and suffix %s", self.songPath, self.songSuffix ) - self.dialogobject = None - - files = self.config.get_files(self.songSuffix) - if len(files) > 0: - log.debug("Song File %s", files ) - self.songDBCache = SongDBImpl(self.songPath,files[0], self.songSuffix) - + self.db_url = u'' + db_type = self.config.get_db_type() + if db_type == u'sqlite': + self.db_url = u'sqlite://' + self.config.get_data_path() + \ + u'songs.sqlite' + else: + self.db_url = self.config.get_db_type + 'u://' + \ + self.config.get_db_username + u':' + \ + self.config.get_db_password + u'@' + \ + self.config.get_db_hostname + u'/' + \ + self.config.get_db_database + ini_models(self.db_url) + if not songs_table.exists(): + metadata.create_all() log.debug( "Song Initialised") - - def have_song_database(self): - if self.songDBCache == None: - return False - return True def process_dialog(self, dialogobject): self.dialogobject = dialogobject - def get_song(self, songid): + def get_songs(self): """ Returns the details of a song """ - return self.songDBCache.get_song(songid) - - def get_authors(self, reload=False): + return session.query(Song).order_by(title).all() + + def search_song_title(self, keywords): + """ + Searches the song title for keywords. + """ + return session.query(Song).filter(search_title.like(u'%' + keywords + u'%')) + + def search_song_lyrics(self, keywords): + """ + Searches the song lyrics for keywords. + """ + return session.query(Song).filter(search_lyrics.like(u'%' + keywords + u'%')) + + def get_song(self, id): + """ + Returns the details of a song + """ + return session.query(Song).get(id) + + def save_song(self, song): + """ + Saves a song to the database + """ + try: + session.add(song) + session.commit() + return True + except: + return False + + def delete_song(self, song): + try: + session.delete(song) + session.commit() + return True + except: + return False + + def get_authors(self): """ Returns a list of all the authors """ - if self.authorcache == None or reload == True: - self.authorcache = self.songDBCache.get_authors() - return self.authorcache - - def get_author(self, authorid): + return session.query(Author).order_by(display_name).all() + + def get_author(self, id): """ Details of the Author """ - return self.songDBCache.get_author(authorid) + return session.query(Author).get(id) def save_author(self, author): """ Save the Author and refresh the cache """ - self.songDBCache.save_author(author) - self.get_authors(True) # Updates occured refresh the cache - return True - + try: + session.add(author) + session.commit() + return True + except: + return False + def delete_author(self, authorid): """ Delete the author and refresh the author cache """ - self.songDBCache.delete_author(authorid) - self.get_authors(True) # Updates occured refresh the cache - return True - - def get_song_authors_for_author(self, authorid): - """ - Returns the details of a song - """ - return self.songDBCache.get_song_authors_for_author(authorid) - - def get_song_authors_for_song(self, songid): - """ - Returns the details of a song - """ - return self.songDBCache.get_song_authors_for_song(songid) - - def get_bible_books(self,bible): - """ - Returns a list of the books of the bible from the database - """ - log.debug("get_bible_books %s", bible) - return self.bibleDBCache[bible].get_bible_books() - - def get_book_chapter_count(self, bible, book): - """ - Returns the number of Chapters for a given book - """ - log.debug( "get_book_chapter_count %s,%s", bible, book) - return self.bibleDBCache[bible].get_max_bible_book_chapter(book) - - def get_book_verse_count(self, bible, book, chapter): - """ - Returns all the number of verses for a given - book and chapterMaxBibleBookVerses - """ - log.debug( "get_book_verse_count %s,%s,%s", bible, book, chapter) - return self.bibleDBCache[bible].get_max_bible_book_verses(book, chapter) - - def get_verse_from_text(self, bible, versetext): - """ - Returns all the number of verses for a given - book and chapterMaxBibleBookVerses - """ - log.debug( "get_verses_from_text %s,%s", bible, versetext) - return self.bibleDBCache[bible].get_verses_from_text(versetext) - - def save_meta_data(self, bible, version, copyright, permissions): - """ - Saves the bibles meta data - """ - log.debug( "save_meta %s,%s, %s,%s", bible, version, copyright, permissions) - self.bibleDBCache[bible].save_meta("Version", version) - self.bibleDBCache[bible].save_meta("Copyright", copyright) - self.bibleDBCache[bible].save_meta("Permissins", permissions) - - def get_meta_data(self, bible, key): - """ - Returns the meta data for a given key - """ - log.debug( "get_meta %s,%s", bible, key) - self.bibleDBCache[bible].get_meta(key) - - def get_verse_text(self, bible, bookname, schapter, echapter, sverse, everse = 0 ): - """ - Returns a list of verses for a given Book, Chapter and ranges of verses. - If the end verse(everse) is less then the start verse(sverse) - then only one verse is returned - bible - Which bible to use. - Rest can be guessed at ! - """ - text = [] - #log.debug( self.bibleDBCache) - #log.debug( self.bibleHTTPCache) - log.debug( "get_verse_text %s,%s,%s,%s,%s,%s", bible,bookname, schapter,echapter, sverse, everse) -# bookid = self.booksOfBible[bookname] # convert to id ie Genesis --> 1 Revelation --> 73 -# # SORT OUT BOOKNAME BOOK ID. -# # NAME COMES IN TO ID AND BACK TO NAME ? -# c = self.bibleDBCache[bible].getBibleChapter(bookname, chapter) # check to see if book/chapter exists -# bookabbrev = "" -# log.debug( "Bible Chapter %s", c ) -# if not c: -# self._loadBook(bible,bookid, bookname, bookabbrev) -# self._loadChapter(bible, bookid,bookname, chapter) - if schapter == echapter: - text = self.bibleDBCache[bible].get_bible_text(bookname, schapter, sverse, everse) - else: - for i in range (schapter, echapter + 1): - if i == schapter: - start = sverse - end = self.get_book_verse_count(bible, bookname,i )[0] - elif i == echapter: - start = 1 - end = everse - else: - start = 1 - end = self.get_book_verse_count(bible, bookname,i )[0] - - txt = self.bibleDBCache[bible].get_bible_text(bookname, i, start, end) - text.extend(txt) - return text - - def _load_book(self, bible, bookid, bookname, bookabbrev): - log.debug( "load_book %s,%s,%s,%s", bible, bookid, bookname, bookabbrev) - cl = self.bibleDBCache[bible].get_bible_book(bookname) - log.debug( "get bible book %s" , cl) - if not cl : - self.bibleDBCache[bible].create_book(bookid, bookname, bookabbrev) - - def _loadChapter(self, bible, bookid, bookname, chapter): - log.debug( "load_chapter %s,%s,%s,%s", bible, bookid,bookname, chapter) - try : - chaptlist = self.bibleHTTPCache[bible].get_bible_chapter(bible, bookid,bookname, chapter) - self.bibleDBCache[bible].create_chapter(bookname, chapter, chaptlist) - except : - log.error("Errow thrown %s", sys.exc_info()[1]) - - def _is_new_bible(self, name): - """ - Check cache to see if new bible - """ - for b , o in self.bibleDBCache.iteritems(): - log.debug( b ) - if b == name : - return False - return True - - def get_song_from_title(self,searchtext): - log.debug("get song from title %s", searchtext) - return self.songDBCache.get_song_from_title(searchtext) - - def get_song_from_lyrics(self,searchtext): - log.debug("get song from lyrics %s", searchtext) - return self.songDBCache.get_song_from_lyrics(searchtext) - - def get_song_from_author(self,searchtext): - log.debug("get song from author %s", searchtext) - return self.songDBCache.get_song_from_author(searchtext) - - def dump_songs(self): - self.songDBCache.dump_songs() + try: + session.delete(author) + session.commit() + return True + except: + return False diff --git a/openlp/plugins/songs/lib/songtables.py b/openlp/plugins/songs/lib/tables.py similarity index 100% rename from openlp/plugins/songs/lib/songtables.py rename to openlp/plugins/songs/lib/tables.py